int ff_MPV_encode_picture(AVCodecContext *avctx, AVPacket *pkt,

                          AVFrame *pic_arg, int *got_packet)

{

    MpegEncContext *s = avctx->priv_data;

    int i, stuffing_count, ret;

    int context_count = s->slice_context_count;

    s->picture_in_gop_number++;

    if (load_input_picture(s, pic_arg) < 0)

        return -1;

    if (select_input_picture(s) < 0) {

        return -1;

    }

    /* output? */

    if (s->new_picture.f.data[0]) {

        if ((ret = ff_alloc_packet2(avctx, pkt, s->mb_width*s->mb_height*(MAX_MB_BYTES+100)+10000)) < 0)

            return ret;

        if (s->mb_info) {

            s->mb_info_ptr = av_packet_new_side_data(pkt,

                                 AV_PKT_DATA_H263_MB_INFO,

                                 s->mb_width*s->mb_height*12);

            s->prev_mb_info = s->last_mb_info = s->mb_info_size = 0;

        }

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

            int start_y = s->thread_context[i]->start_mb_y;

            int   end_y = s->thread_context[i]->  end_mb_y;

            int h       = s->mb_height;

            uint8_t *start = pkt->data + (size_t)(((int64_t) pkt->size) * start_y / h);

            uint8_t *end   = pkt->data + (size_t)(((int64_t) pkt->size) *   end_y / h);

            init_put_bits(&s->thread_context[i]->pb, start, end - start);

        }

        s->pict_type = s->new_picture.f.pict_type;

        //emms_c();

        ff_MPV_frame_start(s, avctx);

vbv_retry:

        if (encode_picture(s, s->picture_number) < 0)

            return -1;

        avctx->header_bits = s->header_bits;

        avctx->mv_bits     = s->mv_bits;

        avctx->misc_bits   = s->misc_bits;

        avctx->i_tex_bits  = s->i_tex_bits;

        avctx->p_tex_bits  = s->p_tex_bits;

        avctx->i_count     = s->i_count;

        // FIXME f/b_count in avctx

        avctx->p_count     = s->mb_num - s->i_count - s->skip_count;

        avctx->skip_count  = s->skip_count;

        ff_MPV_frame_end(s);

        if (CONFIG_MJPEG_ENCODER && s->out_format == FMT_MJPEG)

            ff_mjpeg_encode_picture_trailer(s);

        if (avctx->rc_buffer_size) {

            RateControlContext *rcc = &s->rc_context;

            int max_size = rcc->buffer_index * avctx->rc_max_available_vbv_use;

            if (put_bits_count(&s->pb) > max_size &&

                s->lambda < s->avctx->lmax) {

                s->next_lambda = FFMAX(s->lambda + 1, s->lambda *

                                       (s->qscale + 1) / s->qscale);

                if (s->adaptive_quant) {

                    int i;

                    for (i = 0; i < s->mb_height * s->mb_stride; i++)

                        s->lambda_table[i] =

                            FFMAX(s->lambda_table[i] + 1,

                                  s->lambda_table[i] * (s->qscale + 1) /

                                  s->qscale);

                }

                s->mb_skipped = 0;        // done in MPV_frame_start()

                // done in encode_picture() so we must undo it

                if (s->pict_type == AV_PICTURE_TYPE_P) {

                    if (s->flipflop_rounding          ||

                        s->codec_id == AV_CODEC_ID_H263P ||

                        s->codec_id == AV_CODEC_ID_MPEG4)

                        s->no_rounding ^= 1;

                }

                if (s->pict_type != AV_PICTURE_TYPE_B) {

                    s->time_base       = s->last_time_base;

                    s->last_non_b_time = s->time - s->pp_time;

                }

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

                    PutBitContext *pb = &s->thread_context[i]->pb;

                    init_put_bits(pb, pb->buf, pb->buf_end - pb->buf);

                }

                goto vbv_retry;

            }

            assert(s->avctx->rc_max_rate);

        }

        if (s->flags & CODEC_FLAG_PASS1)

            ff_write_pass1_stats(s);

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

            s->current_picture_ptr->f.error[i] = s->current_picture.f.error[i];

            avctx->error[i] += s->current_picture_ptr->f.error[i];

        }

        if (s->flags & CODEC_FLAG_PASS1)

            assert(avctx->header_bits + avctx->mv_bits + avctx->misc_bits +

                   avctx->i_tex_bits + avctx->p_tex_bits ==

                       put_bits_count(&s->pb));

        flush_put_bits(&s->pb);

        s->frame_bits  = put_bits_count(&s->pb);

        stuffing_count = ff_vbv_update(s, s->frame_bits);

        s->stuffing_bits = 8*stuffing_count;

        if (stuffing_count) {

            if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb) >> 3) <

                    stuffing_count + 50) {

                av_log(s->avctx, AV_LOG_ERROR, "stuffing too large\n");

                return -1;

            }

            switch (s->codec_id) {

            case AV_CODEC_ID_MPEG1VIDEO:

            case AV_CODEC_ID_MPEG2VIDEO:

                while (stuffing_count--) {

                    put_bits(&s->pb, 8, 0);

                }

            break;

            case AV_CODEC_ID_MPEG4:

                put_bits(&s->pb, 16, 0);

                put_bits(&s->pb, 16, 0x1C3);

                stuffing_count -= 4;

                while (stuffing_count--) {

                    put_bits(&s->pb, 8, 0xFF);

                }

            break;

            default:

                av_log(s->avctx, AV_LOG_ERROR, "vbv buffer overflow\n");

            }

            flush_put_bits(&s->pb);

            s->frame_bits  = put_bits_count(&s->pb);

        }

        /* update mpeg1/2 vbv_delay for CBR */

        if (s->avctx->rc_max_rate                          &&

            s->avctx->rc_min_rate == s->avctx->rc_max_rate &&

            s->out_format == FMT_MPEG1                     &&

            90000LL * (avctx->rc_buffer_size - 1) <=

                s->avctx->rc_max_rate * 0xFFFFLL) {

            int vbv_delay, min_delay;

            double inbits  = s->avctx->rc_max_rate *

                             av_q2d(s->avctx->time_base);

            int    minbits = s->frame_bits - 8 *

                             (s->vbv_delay_ptr - s->pb.buf - 1);

            double bits    = s->rc_context.buffer_index + minbits - inbits;

            if (bits < 0)

                av_log(s->avctx, AV_LOG_ERROR,

                       "Internal error, negative bits\n");

            assert(s->repeat_first_field == 0);

            vbv_delay = bits * 90000 / s->avctx->rc_max_rate;

            min_delay = (minbits * 90000LL + s->avctx->rc_max_rate - 1) /

                        s->avctx->rc_max_rate;

            vbv_delay = FFMAX(vbv_delay, min_delay);

            av_assert0(vbv_delay < 0xFFFF);

            s->vbv_delay_ptr[0] &= 0xF8;

            s->vbv_delay_ptr[0] |= vbv_delay >> 13;

            s->vbv_delay_ptr[1]  = vbv_delay >> 5;

            s->vbv_delay_ptr[2] &= 0x07;

            s->vbv_delay_ptr[2] |= vbv_delay << 3;

            avctx->vbv_delay     = vbv_delay * 300;

        }

        s->total_bits     += s->frame_bits;

        avctx->frame_bits  = s->frame_bits;

        pkt->pts = s->current_picture.f.pts;

        if (!s->low_delay && s->pict_type != AV_PICTURE_TYPE_B) {

            if (!s->current_picture.f.coded_picture_number)

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

            else

                pkt->dts = s->reordered_pts;

            s->reordered_pts = pkt->pts;

        } else

            pkt->dts = pkt->pts;

        if (s->current_picture.f.key_frame)

            pkt->flags |= AV_PKT_FLAG_KEY;

        if (s->mb_info)

            av_packet_shrink_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, s->mb_info_size);

    } else {

        s->frame_bits = 0;

    }

    assert((s->frame_bits & 7) == 0);

    pkt->size = s->frame_bits / 8;

    *got_packet = !!pkt->size;

    return 0;

}


static always_inline target_ulong MASK (uint32_t start, uint32_t end)

{

    target_ulong ret;

#if defined(TARGET_PPC64)

    if (likely(start == 0)) {

        ret = (uint64_t)(-1ULL) << (63 - end);

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

        ret = (uint64_t)(-1ULL) >> start;

    }

#else

    if (likely(start == 0)) {

        ret = (uint32_t)(-1ULL) << (31  - end);

    } else if (likely(end == 31)) {

        ret = (uint32_t)(-1ULL) >> start;

    }

#endif

    else {

        ret = (((target_ulong)(-1ULL)) >> (start)) ^

            (((target_ulong)(-1ULL) >> (end)) >> 1);

        if (unlikely(start > end))

            return ~ret;

    }

    return ret;

}


void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)

{

    int flags;

    uint8_t data = 0;

    const SDL_VideoInfo *vi;

    char *filename;

#if defined(__APPLE__)

    /* always use generic keymaps */

    if (!keyboard_layout)

        keyboard_layout = "en-us";

#endif

    if(keyboard_layout) {

        kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);

        if (!kbd_layout)

            exit(1);

    }

    if (no_frame)

        gui_noframe = 1;

    if (!full_screen) {

        setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 0);

    }

#ifdef __linux__

    /* on Linux, SDL may use fbcon|directfb|svgalib when run without

     * accessible $DISPLAY to open X11 window.  This is often the case

     * when qemu is run using sudo.  But in this case, and when actually

     * run in X11 environment, SDL fights with X11 for the video card,

     * making current display unavailable, often until reboot.

     * So make x11 the default SDL video driver if this variable is unset.

     * This is a bit hackish but saves us from bigger problem.

     * Maybe it's a good idea to fix this in SDL instead.

     */

    setenv("SDL_VIDEODRIVER", "x11", 0);

#endif

    /* Enable normal up/down events for Caps-Lock and Num-Lock keys.

     * This requires SDL >= 1.2.14. */

    setenv("SDL_DISABLE_LOCK_KEYS", "1", 1);

    flags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE;

    if (SDL_Init (flags)) {

        fprintf(stderr, "Could not initialize SDL(%s) - exiting\n",

                SDL_GetError());

        exit(1);

    }

    vi = SDL_GetVideoInfo();

    host_format = *(vi->vfmt);

    /* Load a 32x32x4 image. White pixels are transparent. */

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");

    if (filename) {

        SDL_Surface *image = SDL_LoadBMP(filename);

        if (image) {

            uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);

            SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey);

            SDL_WM_SetIcon(image, NULL);

        }

        g_free(filename);

    }

    if (full_screen) {

        gui_fullscreen = 1;

        sdl_grab_start();

    }

    dcl = g_malloc0(sizeof(DisplayChangeListener));

    dcl->ops = &dcl_ops;

    register_displaychangelistener(dcl);

    mouse_mode_notifier.notify = sdl_mouse_mode_change;

    qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);

    sdl_update_caption();

    SDL_EnableKeyRepeat(250, 50);

    gui_grab = 0;

    sdl_cursor_hidden = SDL_CreateCursor(&data, &data, 8, 1, 0, 0);

    sdl_cursor_normal = SDL_GetCursor();

    atexit(sdl_cleanup);

}


static void apply_tns(INTFLOAT coef[1024], TemporalNoiseShaping *tns,

                      IndividualChannelStream *ics, int decode)

{

    const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);

    int w, filt, m, i;

    int bottom, top, order, start, end, size, inc;

    INTFLOAT lpc[TNS_MAX_ORDER];

    INTFLOAT tmp[TNS_MAX_ORDER+1];

    for (w = 0; w < ics->num_windows; w++) {

        bottom = ics->num_swb;

        for (filt = 0; filt < tns->n_filt[w]; filt++) {

            top    = bottom;

            bottom = FFMAX(0, top - tns->length[w][filt]);

            order  = tns->order[w][filt];

            if (order == 0)

                continue;

            // tns_decode_coef

            AAC_RENAME(compute_lpc_coefs)(tns->coef[w][filt], order, lpc, 0, 0, 0);

            start = ics->swb_offset[FFMIN(bottom, mmm)];

            end   = ics->swb_offset[FFMIN(   top, mmm)];

            if ((size = end - start) <= 0)

                continue;

            if (tns->direction[w][filt]) {

                inc = -1;

                start = end - 1;

            } else {

                inc = 1;

            }

            start += w * 128;

            if (decode) {

                // ar filter

                for (m = 0; m < size; m++, start += inc)

                    for (i = 1; i <= FFMIN(m, order); i++)

                        coef[start] -= AAC_MUL26(coef[start - i * inc], lpc[i - 1]);

            } else {

                // ma filter

                for (m = 0; m < size; m++, start += inc) {

                    tmp[0] = coef[start];

                    for (i = 1; i <= FFMIN(m, order); i++)

                        coef[start] += AAC_MUL26(tmp[i], lpc[i - 1]);

                    for (i = order; i > 0; i--)

                        tmp[i] = tmp[i - 1];

                }

            }

        }

    }

}


static void checkpoint(void) {

    assert(((mapping_t*)array_get(&(vvv->mapping), 0))->end == 2);

    check1(vvv);

    check2(vvv);

    assert(!vvv->current_mapping || vvv->current_fd || (vvv->current_mapping->mode & MODE_DIRECTORY));

#if 0

    if (((direntry_t*)vvv->directory.pointer)[1].attributes != 0xf)

	fprintf(stderr, "Nonono!\n");

    mapping_t* mapping;

    direntry_t* direntry;

    assert(vvv->mapping.size >= vvv->mapping.item_size * vvv->mapping.next);

    assert(vvv->directory.size >= vvv->directory.item_size * vvv->directory.next);

    if (vvv->mapping.next<47)

	return;

    assert((mapping = array_get(&(vvv->mapping), 47)));

    assert(mapping->dir_index < vvv->directory.next);

    direntry = array_get(&(vvv->directory), mapping->dir_index);

    assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);

#endif

    return;

    /* avoid compiler warnings: */

    hexdump(NULL, 100);

    remove_mapping(vvv, NULL);

    print_mapping(NULL);

    print_direntry(NULL);

}


static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size)

{

    int res = 0;

    if (end - start < nal_length_size)

        return NULL;

    while (nal_length_size--)

        res = (res << 8) | *start++;

    if (start + res > end || res < 0 || start + res < start)

        return NULL;

    return start + res;

}


av_cold void ff_vp8dsp_init_neon(VP8DSPContext *dsp)

{

    dsp->vp8_luma_dc_wht    = ff_vp8_luma_dc_wht_neon;

    dsp->vp8_idct_add       = ff_vp8_idct_add_neon;

    dsp->vp8_idct_dc_add    = ff_vp8_idct_dc_add_neon;

    dsp->vp8_idct_dc_add4y  = ff_vp8_idct_dc_add4y_neon;

    dsp->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_neon;

    dsp->vp8_v_loop_filter16y = ff_vp8_v_loop_filter16_neon;

    dsp->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16_neon;

    dsp->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_neon;

    dsp->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_neon;

    dsp->vp8_v_loop_filter16y_inner = ff_vp8_v_loop_filter16_inner_neon;

    dsp->vp8_h_loop_filter16y_inner = ff_vp8_h_loop_filter16_inner_neon;

    dsp->vp8_v_loop_filter8uv_inner = ff_vp8_v_loop_filter8uv_inner_neon;

    dsp->vp8_h_loop_filter8uv_inner = ff_vp8_h_loop_filter8uv_inner_neon;

    dsp->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter16_simple_neon;

    dsp->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter16_simple_neon;

    dsp->put_vp8_epel_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon;

    dsp->put_vp8_epel_pixels_tab[0][0][2] = ff_put_vp8_epel16_h6_neon;

    dsp->put_vp8_epel_pixels_tab[0][2][0] = ff_put_vp8_epel16_v6_neon;

    dsp->put_vp8_epel_pixels_tab[0][2][2] = ff_put_vp8_epel16_h6v6_neon;

    dsp->put_vp8_epel_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon;

    dsp->put_vp8_epel_pixels_tab[1][0][1] = ff_put_vp8_epel8_h4_neon;

    dsp->put_vp8_epel_pixels_tab[1][0][2] = ff_put_vp8_epel8_h6_neon;

    dsp->put_vp8_epel_pixels_tab[1][1][0] = ff_put_vp8_epel8_v4_neon;

    dsp->put_vp8_epel_pixels_tab[1][1][1] = ff_put_vp8_epel8_h4v4_neon;

    dsp->put_vp8_epel_pixels_tab[1][1][2] = ff_put_vp8_epel8_h6v4_neon;

    dsp->put_vp8_epel_pixels_tab[1][2][0] = ff_put_vp8_epel8_v6_neon;

    dsp->put_vp8_epel_pixels_tab[1][2][1] = ff_put_vp8_epel8_h4v6_neon;

    dsp->put_vp8_epel_pixels_tab[1][2][2] = ff_put_vp8_epel8_h6v6_neon;

    dsp->put_vp8_epel_pixels_tab[2][0][1] = ff_put_vp8_epel4_h4_neon;

    dsp->put_vp8_epel_pixels_tab[2][0][2] = ff_put_vp8_epel4_h6_neon;

    dsp->put_vp8_epel_pixels_tab[2][1][0] = ff_put_vp8_epel4_v4_neon;

    dsp->put_vp8_epel_pixels_tab[2][1][1] = ff_put_vp8_epel4_h4v4_neon;

    dsp->put_vp8_epel_pixels_tab[2][1][2] = ff_put_vp8_epel4_h6v4_neon;

    dsp->put_vp8_epel_pixels_tab[2][2][0] = ff_put_vp8_epel4_v6_neon;

    dsp->put_vp8_epel_pixels_tab[2][2][1] = ff_put_vp8_epel4_h4v6_neon;

    dsp->put_vp8_epel_pixels_tab[2][2][2] = ff_put_vp8_epel4_h6v6_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][0][1] = ff_put_vp8_bilin16_h_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][0][2] = ff_put_vp8_bilin16_h_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][1][0] = ff_put_vp8_bilin16_v_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][1][1] = ff_put_vp8_bilin16_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][1][2] = ff_put_vp8_bilin16_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][2][0] = ff_put_vp8_bilin16_v_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][2][1] = ff_put_vp8_bilin16_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[0][2][2] = ff_put_vp8_bilin16_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][0][1] = ff_put_vp8_bilin8_h_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][0][2] = ff_put_vp8_bilin8_h_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][1][0] = ff_put_vp8_bilin8_v_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][1][1] = ff_put_vp8_bilin8_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][1][2] = ff_put_vp8_bilin8_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][2][0] = ff_put_vp8_bilin8_v_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][2][1] = ff_put_vp8_bilin8_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[1][2][2] = ff_put_vp8_bilin8_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][0][1] = ff_put_vp8_bilin4_h_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][0][2] = ff_put_vp8_bilin4_h_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][1][0] = ff_put_vp8_bilin4_v_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][1][1] = ff_put_vp8_bilin4_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][1][2] = ff_put_vp8_bilin4_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][2][0] = ff_put_vp8_bilin4_v_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][2][1] = ff_put_vp8_bilin4_hv_neon;

    dsp->put_vp8_bilinear_pixels_tab[2][2][2] = ff_put_vp8_bilin4_hv_neon;

}


static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,

    int64_t offset, int count, BdrvRequestFlags flags)

{

    BlockDriver *drv = bs->drv;

    QEMUIOVector qiov;

    struct iovec iov = {0};

    int ret = 0;

    bool need_flush = false;

    int head = 0;

    int tail = 0;

    int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);

    int alignment = MAX(bs->bl.pwrite_zeroes_alignment,

                        bs->bl.request_alignment);

    assert(alignment % bs->bl.request_alignment == 0);

    head = offset % alignment;

    tail = (offset + count) % alignment;

    max_write_zeroes = QEMU_ALIGN_DOWN(max_write_zeroes, alignment);

    assert(max_write_zeroes >= bs->bl.request_alignment);

    while (count > 0 && !ret) {

        int num = count;

        /* Align request.  Block drivers can expect the "bulk" of the request

         * to be aligned, and that unaligned requests do not cross cluster

         * boundaries.

         */

        if (head) {

            /* Make a small request up to the first aligned sector.  */

            num = MIN(count, alignment - head);

            head = 0;

        } else if (tail && num > alignment) {

            /* Shorten the request to the last aligned sector.  */

            num -= tail;

        }

        /* limit request size */

        if (num > max_write_zeroes) {

            num = max_write_zeroes;

        }

        ret = -ENOTSUP;

        /* First try the efficient write zeroes operation */

        if (drv->bdrv_co_pwrite_zeroes) {

            ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num,

                                             flags & bs->supported_zero_flags);

            if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) &&

                !(bs->supported_zero_flags & BDRV_REQ_FUA)) {

                need_flush = true;

            }

        } else {

            assert(!bs->supported_zero_flags);

        }

        if (ret == -ENOTSUP) {

            /* Fall back to bounce buffer if write zeroes is unsupported */

            int max_transfer = MIN_NON_ZERO(bs->bl.max_transfer,

                                            MAX_WRITE_ZEROES_BOUNCE_BUFFER);

            BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;

            if ((flags & BDRV_REQ_FUA) &&

                !(bs->supported_write_flags & BDRV_REQ_FUA)) {

                /* No need for bdrv_driver_pwrite() to do a fallback

                 * flush on each chunk; use just one at the end */

                write_flags &= ~BDRV_REQ_FUA;

                need_flush = true;

            }

            num = MIN(num, max_transfer);

            iov.iov_len = num;

            if (iov.iov_base == NULL) {

                iov.iov_base = qemu_try_blockalign(bs, num);

                if (iov.iov_base == NULL) {

                    ret = -ENOMEM;

                    goto fail;

                }

                memset(iov.iov_base, 0, num);

            }

            qemu_iovec_init_external(&qiov, &iov, 1);

            ret = bdrv_driver_pwritev(bs, offset, num, &qiov, write_flags);

            /* Keep bounce buffer around if it is big enough for all

             * all future requests.

             */

            if (num < max_transfer) {

                qemu_vfree(iov.iov_base);

                iov.iov_base = NULL;

            }

        }

        offset += num;

        count -= num;

    }

fail:

    if (ret == 0 && need_flush) {

        ret = bdrv_co_flush(bs);

    }

    qemu_vfree(iov.iov_base);

    return ret;

}


static void virtio_ccw_notify(DeviceState *d, uint16_t vector)

{

    VirtioCcwDevice *dev = to_virtio_ccw_dev_fast(d);

    SubchDev *sch = dev->sch;

    uint64_t indicators;

    if (vector >= 128) {

        return;

    }

    if (vector < VIRTIO_CCW_QUEUE_MAX) {

        if (!dev->indicators) {

            return;

        }

        if (sch->thinint_active) {

            /*

             * In the adapter interrupt case, indicators points to a

             * memory area that may be (way) larger than 64 bit and

             * ind_bit indicates the start of the indicators in a big

             * endian notation.

             */

            uint64_t ind_bit = dev->routes.adapter.ind_offset;

            virtio_set_ind_atomic(sch, dev->indicators->addr +

                                  (ind_bit + vector) / 8,

                                  0x80 >> ((ind_bit + vector) % 8));

            if (!virtio_set_ind_atomic(sch, dev->summary_indicator->addr,

                                       0x01)) {

                css_adapter_interrupt(dev->thinint_isc);

            }

        } else {

            indicators = address_space_ldq(&address_space_memory,

                                           dev->indicators->addr,

                                           MEMTXATTRS_UNSPECIFIED,

                                           NULL);

            indicators |= 1ULL << vector;

            address_space_stq(&address_space_memory, dev->indicators->addr,

                              indicators, MEMTXATTRS_UNSPECIFIED, NULL);

            css_conditional_io_interrupt(sch);

        }

    } else {

        if (!dev->indicators2) {

            return;

        }

        vector = 0;

        indicators = address_space_ldq(&address_space_memory,

                                       dev->indicators2->addr,

                                       MEMTXATTRS_UNSPECIFIED,

                                       NULL);

        indicators |= 1ULL << vector;

        address_space_stq(&address_space_memory, dev->indicators2->addr,

                          indicators, MEMTXATTRS_UNSPECIFIED, NULL);

        css_conditional_io_interrupt(sch);

    }

}


static int thp_probe(AVProbeData *p)

{

    /* check file header */

    if (AV_RL32(p->buf) == MKTAG('T', 'H', 'P', '\0'))

        return AVPROBE_SCORE_MAX;

    else

        return 0;

}


static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb,
                                   void *log_ctx)
{
    AVRational frame_rate = { 0, 0 };
    unsigned luma_depth = 8, luma_offset = 16;
    int idx;
    int chroma_x_shift, chroma_y_shift;
    /* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */
    /* [DIRAC_STD] custom_dimensions_flag */
    if (get_bits1(gb)) {
        dsh->width  = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH  */
        dsh->height = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */
    }
    /* [DIRAC_STD] 10.3.3 Chroma Sampling Format.
     *  chroma_sampling_format(video_params) */
    /* [DIRAC_STD] custom_chroma_format_flag */
    if (get_bits1(gb))
        /* [DIRAC_STD] CHROMA_FORMAT_INDEX */
        dsh->chroma_format = svq3_get_ue_golomb(gb);
    if (dsh->chroma_format > 2U) {
        if (log_ctx)
            av_log(log_ctx, AV_LOG_ERROR, "Unknown chroma format %d\n",
                   dsh->chroma_format);
    }
    /* [DIRAC_STD] 10.3.4 Scan Format. scan_format(video_params) */
    /* [DIRAC_STD] custom_scan_format_flag */
    if (get_bits1(gb))
        /* [DIRAC_STD] SOURCE_SAMPLING */
        dsh->interlaced = svq3_get_ue_golomb(gb);
    if (dsh->interlaced > 1U)
    /* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */
    if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */
        dsh->frame_rate_index = svq3_get_ue_golomb(gb);
        if (dsh->frame_rate_index > 10U)
        if (!dsh->frame_rate_index) {
            /* [DIRAC_STD] FRAME_RATE_NUMER */
            frame_rate.num = svq3_get_ue_golomb(gb);
            /* [DIRAC_STD] FRAME_RATE_DENOM */
            frame_rate.den = svq3_get_ue_golomb(gb);
        }
    }
    /* [DIRAC_STD] preset_frame_rate(video_params, index) */
    if (dsh->frame_rate_index > 0) {
        if (dsh->frame_rate_index <= 8)
            frame_rate = ff_mpeg12_frame_rate_tab[dsh->frame_rate_index];
        else
            /* [DIRAC_STD] Table 10.3 values 9-10 */
            frame_rate = dirac_frame_rate[dsh->frame_rate_index - 9];
    }
    dsh->framerate = frame_rate;
    /* [DIRAC_STD] 10.3.6 Pixel Aspect Ratio.
     * pixel_aspect_ratio(video_params) */
    if (get_bits1(gb)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */
        /* [DIRAC_STD] index */
        dsh->aspect_ratio_index = svq3_get_ue_golomb(gb);
        if (dsh->aspect_ratio_index > 6U)
        if (!dsh->aspect_ratio_index) {
            dsh->sample_aspect_ratio.num = svq3_get_ue_golomb(gb);
            dsh->sample_aspect_ratio.den = svq3_get_ue_golomb(gb);
        }
    }
    /* [DIRAC_STD] Take value from Table 10.4 Available preset pixel
     *  aspect ratio values */
    if (dsh->aspect_ratio_index > 0)
        dsh->sample_aspect_ratio =
            dirac_preset_aspect_ratios[dsh->aspect_ratio_index - 1];
    /* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */
    if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */
        /* [DIRAC_STD] CLEAN_WIDTH */
        dsh->clean_width = svq3_get_ue_golomb(gb);
        /* [DIRAC_STD] CLEAN_HEIGHT */
        dsh->clean_height = svq3_get_ue_golomb(gb);
        /* [DIRAC_STD] CLEAN_LEFT_OFFSET */
        dsh->clean_left_offset = svq3_get_ue_golomb(gb);
        /* [DIRAC_STD] CLEAN_RIGHT_OFFSET */
        dsh->clean_right_offset = svq3_get_ue_golomb(gb);
    }
    /* [DIRAC_STD] 10.3.8 Signal range. signal_range(video_params)
     * WARNING: Some adaptation seems to be done using the
     * AVCOL_RANGE_MPEG/JPEG values */
    if (get_bits1(gb)) { /* [DIRAC_STD] custom_signal_range_flag */
        /* [DIRAC_STD] index */
        dsh->pixel_range_index = svq3_get_ue_golomb(gb);
        if (dsh->pixel_range_index > 4U)
        /* This assumes either fullrange or MPEG levels only */
        if (!dsh->pixel_range_index) {
            luma_offset = svq3_get_ue_golomb(gb);
            luma_depth  = av_log2(svq3_get_ue_golomb(gb)) + 1;
            svq3_get_ue_golomb(gb); /* chroma offset    */
            svq3_get_ue_golomb(gb); /* chroma excursion */
            dsh->color_range = luma_offset ? AVCOL_RANGE_MPEG
                                           : AVCOL_RANGE_JPEG;
        }
    }
    /* [DIRAC_STD] Table 10.5
     * Available signal range presets <--> pixel_range_presets */
    if (dsh->pixel_range_index > 0) {
        idx                = dsh->pixel_range_index - 1;
        luma_depth         = pixel_range_presets[idx].bitdepth;
        dsh->color_range   = pixel_range_presets[idx].color_range;
    }
    dsh->bit_depth = luma_depth;
    dsh->pix_fmt = dirac_pix_fmt[dsh->chroma_format][dsh->pixel_range_index-2];
    avcodec_get_chroma_sub_sample(dsh->pix_fmt, &chroma_x_shift, &chroma_y_shift);
    if ((dsh->width % (1<<chroma_x_shift)) || (dsh->height % (1<<chroma_y_shift))) {
        if (log_ctx)
            av_log(log_ctx, AV_LOG_ERROR, "Dimensions must be an integer multiple of the chroma subsampling\n");
    }
    /* [DIRAC_STD] 10.3.9 Colour specification. colour_spec(video_params) */
    if (get_bits1(gb)) { /* [DIRAC_STD] custom_colour_spec_flag */
        /* [DIRAC_STD] index */
        idx = dsh->color_spec_index = svq3_get_ue_golomb(gb);
        if (dsh->color_spec_index > 4U)
        dsh->color_primaries = dirac_color_presets[idx].color_primaries;
        dsh->colorspace      = dirac_color_presets[idx].colorspace;
        dsh->color_trc       = dirac_color_presets[idx].color_trc;
        if (!dsh->color_spec_index) {
            /* [DIRAC_STD] 10.3.9.1 Colour primaries */
            if (get_bits1(gb)) {
                idx = svq3_get_ue_golomb(gb);
                if (idx < 3U)
                    dsh->color_primaries = dirac_primaries[idx];
            }
            /* [DIRAC_STD] 10.3.9.2 Colour matrix */
            if (get_bits1(gb)) {
                idx = svq3_get_ue_golomb(gb);
                if (!idx)
                    dsh->colorspace = AVCOL_SPC_BT709;
                else if (idx == 1)
                    dsh->colorspace = AVCOL_SPC_BT470BG;
            }
            /* [DIRAC_STD] 10.3.9.3 Transfer function */
            if (get_bits1(gb) && !svq3_get_ue_golomb(gb))
                dsh->color_trc = AVCOL_TRC_BT709;
        }
    } else {
        idx                    = dsh->color_spec_index;
        dsh->color_primaries = dirac_color_presets[idx].color_primaries;
        dsh->colorspace      = dirac_color_presets[idx].colorspace;
        dsh->color_trc       = dirac_color_presets[idx].color_trc;
    }
    return 0;
}


static int handle_packets(MpegTSContext *ts, int nb_packets)

{

    AVFormatContext *s = ts->stream;

    uint8_t packet[TS_PACKET_SIZE];

    int packet_num, ret = 0;

    if (avio_tell(s->pb) != ts->last_pos) {

        int i;

        av_dlog(ts->stream, "Skipping after seek\n");

        /* seek detected, flush pes buffer */

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

            if (ts->pids[i]) {

                if (ts->pids[i]->type == MPEGTS_PES) {

                   PESContext *pes = ts->pids[i]->u.pes_filter.opaque;

                   av_freep(&pes->buffer);

                   pes->data_index = 0;

                   pes->state = MPEGTS_SKIP; /* skip until pes header */

                }

                ts->pids[i]->last_cc = -1;

            }

        }

    }

    ts->stop_parse = 0;

    packet_num = 0;

    for(;;) {

        if (ts->stop_parse>0)

            break;

        packet_num++;

        if (nb_packets != 0 && packet_num >= nb_packets)

            break;

        ret = read_packet(s, packet, ts->raw_packet_size);

        if (ret != 0)

            break;

        ret = handle_packet(ts, packet);

        if (ret != 0)

            break;

    }

    ts->last_pos = avio_tell(s->pb);

    return ret;

}


static int v4l2_read_header(AVFormatContext *s1)

{

    struct video_data *s = s1->priv_data;

    AVStream *st;

    int res = 0;

    uint32_t desired_format;

    enum AVCodecID codec_id = AV_CODEC_ID_NONE;

    enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE;

    st = avformat_new_stream(s1, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    s->fd = device_open(s1);

    if (s->fd < 0)

        return s->fd;

    if (s->list_format) {

        list_formats(s1, s->fd, s->list_format);

        return AVERROR_EXIT;

    }

    avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */

    if (s->pixel_format) {

        AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format);

        if (codec)

            s1->video_codec_id = codec->id;

        pix_fmt = av_get_pix_fmt(s->pixel_format);

        if (pix_fmt == AV_PIX_FMT_NONE && !codec) {

            av_log(s1, AV_LOG_ERROR, "No such input format: %s.\n",

                   s->pixel_format);

            return AVERROR(EINVAL);

        }

    }

    if (!s->width && !s->height) {

        struct v4l2_format fmt;

        av_log(s1, AV_LOG_VERBOSE,

               "Querying the device for the current frame size\n");

        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

        if (v4l2_ioctl(s->fd, VIDIOC_G_FMT, &fmt) < 0) {

            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_FMT): %s\n",

                   strerror(errno));

            return AVERROR(errno);

        }

        s->width  = fmt.fmt.pix.width;

        s->height = fmt.fmt.pix.height;

        av_log(s1, AV_LOG_VERBOSE,

               "Setting frame size to %dx%d\n", s->width, s->height);

    }

    desired_format = device_try_init(s1, pix_fmt, &s->width, &s->height,

                                     &codec_id);

    /* If no pixel_format was specified, the codec_id was not known up

     * until now. Set video_codec_id in the context, as codec_id will

     * not be available outside this function

     */

    if (codec_id != AV_CODEC_ID_NONE && s1->video_codec_id == AV_CODEC_ID_NONE)

        s1->video_codec_id = codec_id;

    if (desired_format == 0) {

        av_log(s1, AV_LOG_ERROR, "Cannot find a proper format for "

               "codec_id %d, pix_fmt %d.\n", s1->video_codec_id, pix_fmt);

        v4l2_close(s->fd);

        return AVERROR(EIO);

    }

    if ((res = av_image_check_size(s->width, s->height, 0, s1)) < 0)

        return res;

    s->frame_format = desired_format;

    if ((res = v4l2_set_parameters(s1)) < 0)

        return res;

    st->codec->pix_fmt = fmt_v4l2ff(desired_format, codec_id);

    s->frame_size =

        avpicture_get_size(st->codec->pix_fmt, s->width, s->height);

    if ((res = mmap_init(s1)) ||

        (res = mmap_start(s1)) < 0) {

        v4l2_close(s->fd);

        return res;

    }

    s->top_field_first = first_field(s->fd);

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id = codec_id;

    if (codec_id == AV_CODEC_ID_RAWVIDEO)

        st->codec->codec_tag =

            avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);

    if (desired_format == V4L2_PIX_FMT_YVU420)

        st->codec->codec_tag = MKTAG('Y', 'V', '1', '2');

    st->codec->width = s->width;

    st->codec->height = s->height;

    st->codec->bit_rate = s->frame_size * av_q2d(st->avg_frame_rate) * 8;

    return 0;

}


static uint32_t ppc_hash64_pte_size_decode(uint64_t pte1, uint32_t slb_pshift)

{

    switch (slb_pshift) {

    case 12:

        return 12;

    case 16:

        if ((pte1 & 0xf000) == 0x1000) {

            return 16;

        }

        return 0;

    case 24:

        if ((pte1 & 0xff000) == 0) {

            return 24;

        }

        return 0;

    }

    return 0;

}


static int pci_unregister_device(DeviceState *dev)

{

    PCIDevice *pci_dev = PCI_DEVICE(dev);

    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(pci_dev);

    pci_unregister_io_regions(pci_dev);

    pci_del_option_rom(pci_dev);

    if (pc->exit) {

        pc->exit(pci_dev);

    }

    do_pci_unregister_device(pci_dev);

    return 0;

}


bool css_schid_final(int m, uint8_t cssid, uint8_t ssid, uint16_t schid)

{

    SubchSet *set;

    uint8_t real_cssid;

    real_cssid = (!m && (cssid == 0)) ? channel_subsys.default_cssid : cssid;

    if (real_cssid > MAX_CSSID || ssid > MAX_SSID ||

        !channel_subsys.css[real_cssid] ||

        !channel_subsys.css[real_cssid]->sch_set[ssid]) {

        return true;

    }

    set = channel_subsys.css[real_cssid]->sch_set[ssid];

    return schid > find_last_bit(set->schids_used,

                                 (MAX_SCHID + 1) / sizeof(unsigned long));

}


AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret)
{
    AVProbeData lpd = *pd;
    AVInputFormat *fmt1 = NULL, *fmt;
    int score, nodat = 0, score_max=0;
    if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
        int id3len = ff_id3v2_tag_len(lpd.buf);
        if (lpd.buf_size > id3len + 16) {
            lpd.buf += id3len;
            lpd.buf_size -= id3len;
        }else
            nodat = 1;
    }
    fmt = NULL;
    while ((fmt1 = av_iformat_next(fmt1))) {
        if (!is_opened == !(fmt1->flags & AVFMT_NOFILE))
            continue;
        score = 0;
        if (fmt1->read_probe) {
            score = fmt1->read_probe(&lpd);
            if(fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions))
                score = FFMAX(score, nodat ? AVPROBE_SCORE_MAX/4-1 : 1);
        } else if (fmt1->extensions) {
            if (av_match_ext(lpd.filename, fmt1->extensions)) {
                score = 50;
            }
        }
        if (score > score_max) {
            score_max = score;
            fmt = fmt1;
        }else if (score == score_max)
            fmt = NULL;
    }
    *score_ret= score_max;
    return fmt;
}


static av_cold int movie_common_init(AVFilterContext *ctx)

{

    MovieContext *movie = ctx->priv;

    AVInputFormat *iformat = NULL;

    int64_t timestamp;

    int nb_streams = 1, ret, i;

    char default_streams[16], *stream_specs, *spec, *cursor;

    char name[16];

    AVStream *st;

    if (!movie->file_name) {

        av_log(ctx, AV_LOG_ERROR, "No filename provided!\n");

        return AVERROR(EINVAL);

    }

    movie->seek_point = movie->seek_point_d * 1000000 + 0.5;

    stream_specs = movie->stream_specs;

    if (!stream_specs) {

        snprintf(default_streams, sizeof(default_streams), "d%c%d",

                 !strcmp(ctx->filter->name, "amovie") ? 'a' : 'v',

                 movie->stream_index);

        stream_specs = default_streams;

    }

    for (cursor = stream_specs; *cursor; cursor++)

        if (*cursor == '+')

            nb_streams++;

    if (movie->loop_count != 1 && nb_streams != 1) {

        av_log(ctx, AV_LOG_ERROR,

               "Loop with several streams is currently unsupported\n");

        return AVERROR_PATCHWELCOME;

    }

    av_register_all();

    // Try to find the movie format (container)

    iformat = movie->format_name ? av_find_input_format(movie->format_name) : NULL;

    movie->format_ctx = NULL;

    if ((ret = avformat_open_input(&movie->format_ctx, movie->file_name, iformat, NULL)) < 0) {

        av_log(ctx, AV_LOG_ERROR,

               "Failed to avformat_open_input '%s'\n", movie->file_name);

        return ret;

    }

    if ((ret = avformat_find_stream_info(movie->format_ctx, NULL)) < 0)

        av_log(ctx, AV_LOG_WARNING, "Failed to find stream info\n");

    // if seeking requested, we execute it

    if (movie->seek_point > 0) {

        timestamp = movie->seek_point;

        // add the stream start time, should it exist

        if (movie->format_ctx->start_time != AV_NOPTS_VALUE) {

            if (timestamp > 0 && movie->format_ctx->start_time > INT64_MAX - timestamp) {

                av_log(ctx, AV_LOG_ERROR,

                       "%s: seek value overflow with start_time:%"PRId64" seek_point:%"PRId64"\n",

                       movie->file_name, movie->format_ctx->start_time, movie->seek_point);

                return AVERROR(EINVAL);

            }

            timestamp += movie->format_ctx->start_time;

        }

        if ((ret = av_seek_frame(movie->format_ctx, -1, timestamp, AVSEEK_FLAG_BACKWARD)) < 0) {

            av_log(ctx, AV_LOG_ERROR, "%s: could not seek to position %"PRId64"\n",

                   movie->file_name, timestamp);

            return ret;

        }

    }

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

        movie->format_ctx->streams[i]->discard = AVDISCARD_ALL;

    movie->st = av_calloc(nb_streams, sizeof(*movie->st));

    if (!movie->st)

        return AVERROR(ENOMEM);

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

        spec = av_strtok(stream_specs, "+", &cursor);

        if (!spec)

            return AVERROR_BUG;

        stream_specs = NULL; /* for next strtok */

        st = find_stream(ctx, movie->format_ctx, spec);

        if (!st)

            return AVERROR(EINVAL);

        st->discard = AVDISCARD_DEFAULT;

        movie->st[i].st = st;

        movie->max_stream_index = FFMAX(movie->max_stream_index, st->index);

        movie->st[i].discontinuity_threshold =

            av_rescale_q(movie->discontinuity_threshold, AV_TIME_BASE_Q, st->time_base);

    }

    if (av_strtok(NULL, "+", &cursor))

        return AVERROR_BUG;

    movie->out_index = av_calloc(movie->max_stream_index + 1,

                                 sizeof(*movie->out_index));

    if (!movie->out_index)

        return AVERROR(ENOMEM);

    for (i = 0; i <= movie->max_stream_index; i++)

        movie->out_index[i] = -1;

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

        AVFilterPad pad = { 0 };

        movie->out_index[movie->st[i].st->index] = i;

        snprintf(name, sizeof(name), "out%d", i);

        pad.type          = movie->st[i].st->codecpar->codec_type;

        pad.name          = av_strdup(name);

        if (!pad.name)

            return AVERROR(ENOMEM);

        pad.config_props  = movie_config_output_props;

        pad.request_frame = movie_request_frame;

        ff_insert_outpad(ctx, i, &pad);

        if ( movie->st[i].st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&

            !movie->st[i].st->codecpar->channel_layout) {

            ret = guess_channel_layout(&movie->st[i], i, ctx);

            if (ret < 0)

                return ret;

        }

        ret = open_stream(ctx, &movie->st[i]);

        if (ret < 0)

            return ret;

    }

    av_log(ctx, AV_LOG_VERBOSE, "seek_point:%"PRIi64" format_name:%s file_name:%s stream_index:%d\n",

           movie->seek_point, movie->format_name, movie->file_name,

           movie->stream_index);

    return 0;

}


static inline int available_samples(AVFrame *out)

{

    int bytes_per_sample = av_get_bytes_per_sample(out->format);

    int samples = out->linesize[0] / bytes_per_sample;

    if (av_sample_fmt_is_planar(out->format)) {

        return samples;

    } else {

        int channels = av_get_channel_layout_nb_channels(out->channel_layout);

        return samples / channels;

    }

}


GACommandState *ga_command_state_new(void)

{

    GACommandState *cs = g_malloc0(sizeof(GACommandState));

    cs->groups = NULL;

    return cs;

}


static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,

                             int Al, const uint8_t *mb_bitmask,

                             const AVFrame *reference)

{

    int i, mb_x, mb_y;

    uint8_t *data[MAX_COMPONENTS];

    const uint8_t *reference_data[MAX_COMPONENTS];

    int linesize[MAX_COMPONENTS];

    GetBitContext mb_bitmask_gb;

    int bytes_per_pixel = 1 + (s->bits > 8);

    if (mb_bitmask)

        init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);

    s->restart_count = 0;

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

        int c   = s->comp_index[i];

        data[c] = s->picture_ptr->data[c];

        reference_data[c] = reference ? reference->data[c] : NULL;

        linesize[c] = s->linesize[c];

        s->coefs_finished[c] |= 1;

    }

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

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

            const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb);

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

                s->restart_count = s->restart_interval;

            if (get_bits_left(&s->gb) < 0) {

                av_log(s->avctx, AV_LOG_ERROR, "overread %d\n",

                       -get_bits_left(&s->gb));

                return AVERROR_INVALIDDATA;

            }

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

                uint8_t *ptr;

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

                int block_offset;

                n = s->nb_blocks[i];

                c = s->comp_index[i];

                h = s->h_scount[i];

                v = s->v_scount[i];

                x = 0;

                y = 0;

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

                    block_offset = (((linesize[c] * (v * mb_y + y) * 8) +

                                     (h * mb_x + x) * 8 * bytes_per_pixel) >> s->avctx->lowres);

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

                        block_offset += linesize[c] >> 1;

                    ptr = data[c] + block_offset;

                    if (!s->progressive) {

                        if (copy_mb)

                            mjpeg_copy_block(s, ptr, reference_data[c] + block_offset,

                                             linesize[c], s->avctx->lowres);

                        else {

                            s->dsp.clear_block(s->block);

                            if (decode_block(s, s->block, i,

                                             s->dc_index[i], s->ac_index[i],

                                             s->quant_matrixes[s->quant_sindex[i]]) < 0) {

                                av_log(s->avctx, AV_LOG_ERROR,

                                       "error y=%d x=%d\n", mb_y, mb_x);

                                return AVERROR_INVALIDDATA;

                            }

                            s->dsp.idct_put(ptr, linesize[c], s->block);

                            if (s->bits & 7)

                                shift_output(s, ptr, linesize[c]);

                        }

                    } else {

                        int block_idx  = s->block_stride[c] * (v * mb_y + y) +

                                         (h * mb_x + x);

                        int16_t *block = s->blocks[c][block_idx];

                        if (Ah)

                            block[0] += get_bits1(&s->gb) *

                                        s->quant_matrixes[s->quant_sindex[i]][0] << Al;

                        else if (decode_dc_progressive(s, block, i, s->dc_index[i],

                                                       s->quant_matrixes[s->quant_sindex[i]],

                                                       Al) < 0) {

                            av_log(s->avctx, AV_LOG_ERROR,

                                   "error y=%d x=%d\n", mb_y, mb_x);

                            return AVERROR_INVALIDDATA;

                        }

                    }

                    av_dlog(s->avctx, "mb: %d %d processed\n", mb_y, mb_x);

                    av_dlog(s->avctx, "%d %d %d %d %d %d %d %d \n",

                            mb_x, mb_y, x, y, c, s->bottom_field,

                            (v * mb_y + y) * 8, (h * mb_x + x) * 8);

                    if (++x == h) {

                        x = 0;

                        y++;

                    }

                }

            }

            handle_rstn(s, nb_components);

        }

    }

    return 0;

}


static int rv40_v_loop_filter_strength(uint8_t *src, int stride,

                                       int beta, int beta2, int edge,

                                       int *p1, int *q1)

{

    return rv40_loop_filter_strength(src, 1, stride, beta, beta2, edge, p1, q1);

}


static void build_trampolines(TCGContext *s)

{

    static void * const qemu_ld_helpers[16] = {

        [MO_UB]   = helper_ret_ldub_mmu,

        [MO_SB]   = helper_ret_ldsb_mmu,

        [MO_LEUW] = helper_le_lduw_mmu,

        [MO_LESW] = helper_le_ldsw_mmu,

        [MO_LEUL] = helper_le_ldul_mmu,

        [MO_LEQ]  = helper_le_ldq_mmu,

        [MO_BEUW] = helper_be_lduw_mmu,

        [MO_BESW] = helper_be_ldsw_mmu,

        [MO_BEUL] = helper_be_ldul_mmu,

        [MO_BEQ]  = helper_be_ldq_mmu,

    };

    static void * const qemu_st_helpers[16] = {

        [MO_UB]   = helper_ret_stb_mmu,

        [MO_LEUW] = helper_le_stw_mmu,

        [MO_LEUL] = helper_le_stl_mmu,

        [MO_LEQ]  = helper_le_stq_mmu,

        [MO_BEUW] = helper_be_stw_mmu,

        [MO_BEUL] = helper_be_stl_mmu,

        [MO_BEQ]  = helper_be_stq_mmu,

    };

    int i;

    TCGReg ra;

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

        if (qemu_ld_helpers[i] == NULL) {

            continue;

        }

        /* May as well align the trampoline.  */

        while ((uintptr_t)s->code_ptr & 15) {

            tcg_out_nop(s);

        }

        qemu_ld_trampoline[i] = s->code_ptr;

        if (SPARC64 || TARGET_LONG_BITS == 32) {

            ra = TCG_REG_O3;

        } else {

            /* Install the high part of the address.  */

            tcg_out_arithi(s, TCG_REG_O1, TCG_REG_O2, 32, SHIFT_SRLX);

            ra = TCG_REG_O4;

        }

        /* Set the retaddr operand.  */

        tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);

        /* Set the env operand.  */

        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);

        /* Tail call.  */

        tcg_out_call_nodelay(s, qemu_ld_helpers[i]);

        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);

    }

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

        if (qemu_st_helpers[i] == NULL) {

            continue;

        }

        /* May as well align the trampoline.  */

        while ((uintptr_t)s->code_ptr & 15) {

            tcg_out_nop(s);

        }

        qemu_st_trampoline[i] = s->code_ptr;

        if (SPARC64) {

            emit_extend(s, TCG_REG_O2, i);

            ra = TCG_REG_O4;

        } else {

            ra = TCG_REG_O1;

            if (TARGET_LONG_BITS == 64) {

                /* Install the high part of the address.  */

                tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);

                ra += 2;

            } else {

                ra += 1;

            }

            if ((i & MO_SIZE) == MO_64) {

                /* Install the high part of the data.  */

                tcg_out_arithi(s, ra, ra + 1, 32, SHIFT_SRLX);

                ra += 2;

            } else {

                ra += 1;

            }

            /* Skip the oi argument.  */

            ra += 1;

        }

        /* Set the retaddr operand.  */

        if (ra >= TCG_REG_O6) {

            tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_O7, TCG_REG_CALL_STACK,

                       TCG_TARGET_CALL_STACK_OFFSET);

            ra = TCG_REG_G1;

        }

        tcg_out_mov(s, TCG_TYPE_PTR, ra, TCG_REG_O7);

        /* Set the env operand.  */

        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O0, TCG_AREG0);

        /* Tail call.  */

        tcg_out_call_nodelay(s, qemu_st_helpers[i]);

        tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_O7, ra);

    }

}


int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,

    int *num, uint64_t *host_offset, QCowL2Meta **m)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t start, remaining;

    uint64_t cluster_offset;

    uint64_t cur_bytes;

    int ret;

    trace_qcow2_alloc_clusters_offset(qemu_coroutine_self(), offset, *num);

    assert((offset & ~BDRV_SECTOR_MASK) == 0);

again:

    start = offset;

    remaining = *num << BDRV_SECTOR_BITS;

    cluster_offset = 0;

    *host_offset = 0;

    cur_bytes = 0;

    *m = NULL;

    while (true) {

        if (!*host_offset) {

            *host_offset = start_of_cluster(s, cluster_offset);

        }

        assert(remaining >= cur_bytes);

        start           += cur_bytes;

        remaining       -= cur_bytes;

        cluster_offset  += cur_bytes;

        if (remaining == 0) {

            break;

        }

        cur_bytes = remaining;

        /*

         * Now start gathering as many contiguous clusters as possible:

         *

         * 1. Check for overlaps with in-flight allocations

         *

         *      a) Overlap not in the first cluster -> shorten this request and

         *         let the caller handle the rest in its next loop iteration.

         *

         *      b) Real overlaps of two requests. Yield and restart the search

         *         for contiguous clusters (the situation could have changed

         *         while we were sleeping)

         *

         *      c) TODO: Request starts in the same cluster as the in-flight

         *         allocation ends. Shorten the COW of the in-fight allocation,

         *         set cluster_offset to write to the same cluster and set up

         *         the right synchronisation between the in-flight request and

         *         the new one.

         */

        ret = handle_dependencies(bs, start, &cur_bytes, m);

        if (ret == -EAGAIN) {

            /* Currently handle_dependencies() doesn't yield if we already had

             * an allocation. If it did, we would have to clean up the L2Meta

             * structs before starting over. */

            assert(*m == NULL);

            goto again;

        } else if (ret < 0) {

            return ret;

        } else if (cur_bytes == 0) {

            break;

        } else {

            /* handle_dependencies() may have decreased cur_bytes (shortened

             * the allocations below) so that the next dependency is processed

             * correctly during the next loop iteration. */

        }

        /*

         * 2. Count contiguous COPIED clusters.

         */

        ret = handle_copied(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            continue;

        } else if (cur_bytes == 0) {

            break;

        }

        /*

         * 3. If the request still hasn't completed, allocate new clusters,

         *    considering any cluster_offset of steps 1c or 2.

         */

        ret = handle_alloc(bs, start, &cluster_offset, &cur_bytes, m);

        if (ret < 0) {

            return ret;

        } else if (ret) {

            continue;

        } else {

            assert(cur_bytes == 0);

            break;

        }

    }

    *num -= remaining >> BDRV_SECTOR_BITS;

    assert(*num > 0);

    assert(*host_offset != 0);

    return 0;

}


static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[], int dstStride, int width, int height,

                                const QP_STORE_T QPs[], int QPStride, int isColor, PPContext *c2)

{

    DECLARE_ALIGNED(8, PPContext, c)= *c2; //copy to stack for faster access

    int x,y;

#ifdef COMPILE_TIME_MODE

    const int mode= COMPILE_TIME_MODE;

#else

    const int mode= isColor ? c.ppMode.chromMode : c.ppMode.lumMode;

#endif

    int black=0, white=255; // blackest black and whitest white in the picture

    int QPCorrecture= 256*256;

    int copyAhead;

#if HAVE_MMX_INLINE

    int i;

#endif

    const int qpHShift= isColor ? 4-c.hChromaSubSample : 4;

    const int qpVShift= isColor ? 4-c.vChromaSubSample : 4;

    //FIXME remove

    uint64_t * const yHistogram= c.yHistogram;

    uint8_t * const tempSrc= srcStride > 0 ? c.tempSrc : c.tempSrc - 23*srcStride;

    uint8_t * const tempDst= dstStride > 0 ? c.tempDst : c.tempDst - 23*dstStride;

    //const int mbWidth= isColor ? (width+7)>>3 : (width+15)>>4;

#if HAVE_MMX_INLINE

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

        int offset= ((i*c.ppMode.baseDcDiff)>>8) + 1;

        int threshold= offset*2 + 1;

        c.mmxDcOffset[i]= 0x7F - offset;

        c.mmxDcThreshold[i]= 0x7F - threshold;

        c.mmxDcOffset[i]*= 0x0101010101010101LL;

        c.mmxDcThreshold[i]*= 0x0101010101010101LL;

    }

#endif

    if(mode & CUBIC_IPOL_DEINT_FILTER) copyAhead=16;

    else if(   (mode & LINEAR_BLEND_DEINT_FILTER)

            || (mode & FFMPEG_DEINT_FILTER)

            || (mode & LOWPASS5_DEINT_FILTER)) copyAhead=14;

    else if(   (mode & V_DEBLOCK)

            || (mode & LINEAR_IPOL_DEINT_FILTER)

            || (mode & MEDIAN_DEINT_FILTER)

            || (mode & V_A_DEBLOCK)) copyAhead=13;

    else if(mode & V_X1_FILTER) copyAhead=11;

//    else if(mode & V_RK1_FILTER) copyAhead=10;

    else if(mode & DERING) copyAhead=9;

    else copyAhead=8;

    copyAhead-= 8;

    if(!isColor){

        uint64_t sum= 0;

        int i;

        uint64_t maxClipped;

        uint64_t clipped;

        double scale;

        c.frameNum++;

        // first frame is fscked so we ignore it

        if(c.frameNum == 1) yHistogram[0]= width*height/64*15/256;

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

            sum+= yHistogram[i];

        }

        /* We always get a completely black picture first. */

        maxClipped= (uint64_t)(sum * c.ppMode.maxClippedThreshold);

        clipped= sum;

        for(black=255; black>0; black--){

            if(clipped < maxClipped) break;

            clipped-= yHistogram[black];

        }

        clipped= sum;

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

            if(clipped < maxClipped) break;

            clipped-= yHistogram[white];

        }

        scale= (double)(c.ppMode.maxAllowedY - c.ppMode.minAllowedY) / (double)(white-black);

#if HAVE_MMXEXT_INLINE

        c.packedYScale= (uint16_t)(scale*256.0 + 0.5);

        c.packedYOffset= (((black*c.packedYScale)>>8) - c.ppMode.minAllowedY) & 0xFFFF;

#else

        c.packedYScale= (uint16_t)(scale*1024.0 + 0.5);

        c.packedYOffset= (black - c.ppMode.minAllowedY) & 0xFFFF;

#endif

        c.packedYOffset|= c.packedYOffset<<32;

        c.packedYOffset|= c.packedYOffset<<16;

        c.packedYScale|= c.packedYScale<<32;

        c.packedYScale|= c.packedYScale<<16;

        if(mode & LEVEL_FIX)        QPCorrecture= (int)(scale*256*256 + 0.5);

        else                        QPCorrecture= 256*256;

    }else{

        c.packedYScale= 0x0100010001000100LL;

        c.packedYOffset= 0;

        QPCorrecture= 256*256;

    }

    /* copy & deinterlace first row of blocks */

    y=-BLOCK_SIZE;

    {

        const uint8_t *srcBlock= &(src[y*srcStride]);

        uint8_t *dstBlock= tempDst + dstStride;

        // From this point on it is guaranteed that we can read and write 16 lines downward

        // finish 1 block before the next otherwise we might have a problem

        // with the L1 Cache of the P4 ... or only a few blocks at a time or soemthing

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

#if HAVE_MMXEXT_INLINE

/*

            prefetchnta(srcBlock + (((x>>2)&6) + 5)*srcStride + 32);

            prefetchnta(srcBlock + (((x>>2)&6) + 6)*srcStride + 32);

            prefetcht0(dstBlock + (((x>>2)&6) + 5)*dstStride + 32);

            prefetcht0(dstBlock + (((x>>2)&6) + 6)*dstStride + 32);

*/

            __asm__(

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

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

                "and $6, %%"REG_a"              \n\t"

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

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

                "imul %1, %%"REG_a"             \n\t"

                "imul %3, %%"REG_d"             \n\t"

                "prefetchnta 32(%%"REG_a", %0)  \n\t"

                "prefetcht0 32(%%"REG_d", %2)   \n\t"

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

                "add %3, %%"REG_d"              \n\t"

                "prefetchnta 32(%%"REG_a", %0)  \n\t"

                "prefetcht0 32(%%"REG_d", %2)   \n\t"

                :: "r" (srcBlock), "r" ((x86_reg)srcStride), "r" (dstBlock), "r" ((x86_reg)dstStride),

                "g" ((x86_reg)x), "g" ((x86_reg)copyAhead)

                : "%"REG_a, "%"REG_d

            );

#elif HAVE_AMD3DNOW_INLINE

//FIXME check if this is faster on an 3dnow chip or if it is faster without the prefetch or ...

/*          prefetch(srcBlock + (((x>>3)&3) + 5)*srcStride + 32);

            prefetch(srcBlock + (((x>>3)&3) + 9)*srcStride + 32);

            prefetchw(dstBlock + (((x>>3)&3) + 5)*dstStride + 32);

            prefetchw(dstBlock + (((x>>3)&3) + 9)*dstStride + 32);

*/

#endif

            RENAME(blockCopy)(dstBlock + dstStride*8, dstStride,

                              srcBlock + srcStride*8, srcStride, mode & LEVEL_FIX, &c.packedYOffset);

            RENAME(duplicate)(dstBlock + dstStride*8, dstStride);

            if(mode & LINEAR_IPOL_DEINT_FILTER)

                RENAME(deInterlaceInterpolateLinear)(dstBlock, dstStride);

            else if(mode & LINEAR_BLEND_DEINT_FILTER)

                RENAME(deInterlaceBlendLinear)(dstBlock, dstStride, c.deintTemp + x);

            else if(mode & MEDIAN_DEINT_FILTER)

                RENAME(deInterlaceMedian)(dstBlock, dstStride);

            else if(mode & CUBIC_IPOL_DEINT_FILTER)

                RENAME(deInterlaceInterpolateCubic)(dstBlock, dstStride);

            else if(mode & FFMPEG_DEINT_FILTER)

                RENAME(deInterlaceFF)(dstBlock, dstStride, c.deintTemp + x);

            else if(mode & LOWPASS5_DEINT_FILTER)

                RENAME(deInterlaceL5)(dstBlock, dstStride, c.deintTemp + x, c.deintTemp + width + x);

/*          else if(mode & CUBIC_BLEND_DEINT_FILTER)

                RENAME(deInterlaceBlendCubic)(dstBlock, dstStride);

*/

            dstBlock+=8;

            srcBlock+=8;

        }

        if(width==FFABS(dstStride))

            linecpy(dst, tempDst + 9*dstStride, copyAhead, dstStride);

        else{

            int i;

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

                memcpy(dst + i*dstStride, tempDst + (9+i)*dstStride, width);

            }

        }

    }

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

        //1% speedup if these are here instead of the inner loop

        const uint8_t *srcBlock= &(src[y*srcStride]);

        uint8_t *dstBlock= &(dst[y*dstStride]);

#if HAVE_MMX_INLINE

        uint8_t *tempBlock1= c.tempBlocks;

        uint8_t *tempBlock2= c.tempBlocks + 8;

#endif

        const int8_t *QPptr= &QPs[(y>>qpVShift)*QPStride];

        int8_t *nonBQPptr= &c.nonBQPTable[(y>>qpVShift)*FFABS(QPStride)];

        int QP=0;

        /* can we mess with a 8x16 block from srcBlock/dstBlock downwards and 1 line upwards

           if not than use a temporary buffer */

        if(y+15 >= height){

            int i;

            /* copy from line (copyAhead) to (copyAhead+7) of src, these will be copied with

               blockcopy to dst later */

            linecpy(tempSrc + srcStride*copyAhead, srcBlock + srcStride*copyAhead,

                    FFMAX(height-y-copyAhead, 0), srcStride);

            /* duplicate last line of src to fill the void up to line (copyAhead+7) */

            for(i=FFMAX(height-y, 8); i<copyAhead+8; i++)

                    memcpy(tempSrc + srcStride*i, src + srcStride*(height-1), FFABS(srcStride));

            /* copy up to (copyAhead+1) lines of dst (line -1 to (copyAhead-1))*/

            linecpy(tempDst, dstBlock - dstStride, FFMIN(height-y+1, copyAhead+1), dstStride);

            /* duplicate last line of dst to fill the void up to line (copyAhead) */

            for(i=height-y+1; i<=copyAhead; i++)

                    memcpy(tempDst + dstStride*i, dst + dstStride*(height-1), FFABS(dstStride));

            dstBlock= tempDst + dstStride;

            srcBlock= tempSrc;

        }

        // From this point on it is guaranteed that we can read and write 16 lines downward

        // finish 1 block before the next otherwise we might have a problem

        // with the L1 Cache of the P4 ... or only a few blocks at a time or soemthing

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

            const int stride= dstStride;

#if HAVE_MMX_INLINE

            uint8_t *tmpXchg;

#endif

            if(isColor){

                QP= QPptr[x>>qpHShift];

                c.nonBQP= nonBQPptr[x>>qpHShift];

            }else{

                QP= QPptr[x>>4];

                QP= (QP* QPCorrecture + 256*128)>>16;

                c.nonBQP= nonBQPptr[x>>4];

                c.nonBQP= (c.nonBQP* QPCorrecture + 256*128)>>16;

                yHistogram[ srcBlock[srcStride*12 + 4] ]++;

            }

            c.QP= QP;

#if HAVE_MMX_INLINE

            __asm__ volatile(

                "movd %1, %%mm7         \n\t"

                "packuswb %%mm7, %%mm7  \n\t" // 0, 0, 0, QP, 0, 0, 0, QP

                "packuswb %%mm7, %%mm7  \n\t" // 0,QP, 0, QP, 0,QP, 0, QP

                "packuswb %%mm7, %%mm7  \n\t" // QP,..., QP

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

                : "=m" (c.pQPb)

                : "r" (QP)

            );

#endif

#if HAVE_MMXEXT_INLINE

/*

            prefetchnta(srcBlock + (((x>>2)&6) + 5)*srcStride + 32);

            prefetchnta(srcBlock + (((x>>2)&6) + 6)*srcStride + 32);

            prefetcht0(dstBlock + (((x>>2)&6) + 5)*dstStride + 32);

            prefetcht0(dstBlock + (((x>>2)&6) + 6)*dstStride + 32);

*/

            __asm__(

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

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

                "and $6, %%"REG_a"              \n\t"

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

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

                "imul %1, %%"REG_a"             \n\t"

                "imul %3, %%"REG_d"             \n\t"

                "prefetchnta 32(%%"REG_a", %0)  \n\t"

                "prefetcht0 32(%%"REG_d", %2)   \n\t"

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

                "add %3, %%"REG_d"              \n\t"

                "prefetchnta 32(%%"REG_a", %0)  \n\t"

                "prefetcht0 32(%%"REG_d", %2)   \n\t"

                :: "r" (srcBlock), "r" ((x86_reg)srcStride), "r" (dstBlock), "r" ((x86_reg)dstStride),

                "g" ((x86_reg)x), "g" ((x86_reg)copyAhead)

                : "%"REG_a, "%"REG_d

            );

#elif HAVE_AMD3DNOW_INLINE

//FIXME check if this is faster on an 3dnow chip or if it is faster without the prefetch or ...

/*          prefetch(srcBlock + (((x>>3)&3) + 5)*srcStride + 32);

            prefetch(srcBlock + (((x>>3)&3) + 9)*srcStride + 32);

            prefetchw(dstBlock + (((x>>3)&3) + 5)*dstStride + 32);

            prefetchw(dstBlock + (((x>>3)&3) + 9)*dstStride + 32);

*/

#endif

            RENAME(blockCopy)(dstBlock + dstStride*copyAhead, dstStride,

                              srcBlock + srcStride*copyAhead, srcStride, mode & LEVEL_FIX, &c.packedYOffset);

            if(mode & LINEAR_IPOL_DEINT_FILTER)

                RENAME(deInterlaceInterpolateLinear)(dstBlock, dstStride);

            else if(mode & LINEAR_BLEND_DEINT_FILTER)

                RENAME(deInterlaceBlendLinear)(dstBlock, dstStride, c.deintTemp + x);

            else if(mode & MEDIAN_DEINT_FILTER)

                RENAME(deInterlaceMedian)(dstBlock, dstStride);

            else if(mode & CUBIC_IPOL_DEINT_FILTER)

                RENAME(deInterlaceInterpolateCubic)(dstBlock, dstStride);

            else if(mode & FFMPEG_DEINT_FILTER)

                RENAME(deInterlaceFF)(dstBlock, dstStride, c.deintTemp + x);

            else if(mode & LOWPASS5_DEINT_FILTER)

                RENAME(deInterlaceL5)(dstBlock, dstStride, c.deintTemp + x, c.deintTemp + width + x);

/*          else if(mode & CUBIC_BLEND_DEINT_FILTER)

                RENAME(deInterlaceBlendCubic)(dstBlock, dstStride);

*/

            /* only deblock if we have 2 blocks */

            if(y + 8 < height){

                if(mode & V_X1_FILTER)

                    RENAME(vertX1Filter)(dstBlock, stride, &c);

                else if(mode & V_DEBLOCK){

                    const int t= RENAME(vertClassify)(dstBlock, stride, &c);

                    if(t==1)

                        RENAME(doVertLowPass)(dstBlock, stride, &c);

                    else if(t==2)

                        RENAME(doVertDefFilter)(dstBlock, stride, &c);

                }else if(mode & V_A_DEBLOCK){

                    RENAME(do_a_deblock)(dstBlock, stride, 1, &c);

                }

            }

#if HAVE_MMX_INLINE

            RENAME(transpose1)(tempBlock1, tempBlock2, dstBlock, dstStride);

#endif

            /* check if we have a previous block to deblock it with dstBlock */

            if(x - 8 >= 0){

#if HAVE_MMX_INLINE

                if(mode & H_X1_FILTER)

                        RENAME(vertX1Filter)(tempBlock1, 16, &c);

                else if(mode & H_DEBLOCK){

//START_TIMER

                    const int t= RENAME(vertClassify)(tempBlock1, 16, &c);

//STOP_TIMER("dc & minmax")

                    if(t==1)

                        RENAME(doVertLowPass)(tempBlock1, 16, &c);

                    else if(t==2)

                        RENAME(doVertDefFilter)(tempBlock1, 16, &c);

                }else if(mode & H_A_DEBLOCK){

                        RENAME(do_a_deblock)(tempBlock1, 16, 1, &c);

                }

                RENAME(transpose2)(dstBlock-4, dstStride, tempBlock1 + 4*16);

#else

                if(mode & H_X1_FILTER)

                    horizX1Filter(dstBlock-4, stride, QP);

                else if(mode & H_DEBLOCK){

#if HAVE_ALTIVEC

                    DECLARE_ALIGNED(16, unsigned char, tempBlock)[272];

                    int t;

                    transpose_16x8_char_toPackedAlign_altivec(tempBlock, dstBlock - (4 + 1), stride);

                    t = vertClassify_altivec(tempBlock-48, 16, &c);

                    if(t==1) {

                        doVertLowPass_altivec(tempBlock-48, 16, &c);

                        transpose_8x16_char_fromPackedAlign_altivec(dstBlock - (4 + 1), tempBlock, stride);

                    }

                    else if(t==2) {

                        doVertDefFilter_altivec(tempBlock-48, 16, &c);

                        transpose_8x16_char_fromPackedAlign_altivec(dstBlock - (4 + 1), tempBlock, stride);

                    }

#else

                    const int t= RENAME(horizClassify)(dstBlock-4, stride, &c);

                    if(t==1)

                        RENAME(doHorizLowPass)(dstBlock-4, stride, &c);

                    else if(t==2)

                        RENAME(doHorizDefFilter)(dstBlock-4, stride, &c);

#endif

                }else if(mode & H_A_DEBLOCK){

                    RENAME(do_a_deblock)(dstBlock-8, 1, stride, &c);

                }

#endif //HAVE_MMX_INLINE

                if(mode & DERING){

                //FIXME filter first line

                    if(y>0) RENAME(dering)(dstBlock - stride - 8, stride, &c);

                }

                if(mode & TEMP_NOISE_FILTER)

                {

                    RENAME(tempNoiseReducer)(dstBlock-8, stride,

                            c.tempBlurred[isColor] + y*dstStride + x,

                            c.tempBlurredPast[isColor] + (y>>3)*256 + (x>>3) + 256,

                            c.ppMode.maxTmpNoise);

                }

            }

            dstBlock+=8;

            srcBlock+=8;

#if HAVE_MMX_INLINE

            tmpXchg= tempBlock1;

            tempBlock1= tempBlock2;

            tempBlock2 = tmpXchg;

#endif

        }

        if(mode & DERING){

            if(y > 0) RENAME(dering)(dstBlock - dstStride - 8, dstStride, &c);

        }

        if((mode & TEMP_NOISE_FILTER)){

            RENAME(tempNoiseReducer)(dstBlock-8, dstStride,

                    c.tempBlurred[isColor] + y*dstStride + x,

                    c.tempBlurredPast[isColor] + (y>>3)*256 + (x>>3) + 256,

                    c.ppMode.maxTmpNoise);

        }

        /* did we use a tmp buffer for the last lines*/

        if(y+15 >= height){

            uint8_t *dstBlock= &(dst[y*dstStride]);

            if(width==FFABS(dstStride))

                linecpy(dstBlock, tempDst + dstStride, height-y, dstStride);

            else{

                int i;

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

                    memcpy(dstBlock + i*dstStride, tempDst + (i+1)*dstStride, width);

                }

            }

        }

/*

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

            volatile int i;

            i+=   dstBlock[x + 7*dstStride] + dstBlock[x + 8*dstStride]

                + dstBlock[x + 9*dstStride] + dstBlock[x +10*dstStride]

                + dstBlock[x +11*dstStride] + dstBlock[x +12*dstStride];

                + dstBlock[x +13*dstStride]

                + dstBlock[x +14*dstStride] + dstBlock[x +15*dstStride];

        }*/

    }

#if   HAVE_AMD3DNOW_INLINE

    __asm__ volatile("femms");

#elif HAVE_MMX_INLINE

    __asm__ volatile("emms");

#endif

#ifdef DEBUG_BRIGHTNESS

    if(!isColor){

        int max=1;

        int i;

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

            if(yHistogram[i] > max) max=yHistogram[i];

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

            int x;

            int start=yHistogram[i-1]/(max/256+1);

            int end=yHistogram[i]/(max/256+1);

            int inc= end > start ? 1 : -1;

            for(x=start; x!=end+inc; x+=inc)

                dst[ i*dstStride + x]+=128;

        }

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

            dst[ (white)*dstStride + i]+=128;

            dst[ (black)*dstStride + i]+=128;

        }

    }

#endif

    *c2= c; //copy local context back

}


static int qemu_shutdown_requested(void)

{

    return atomic_xchg(&shutdown_requested, 0);

}


static int socket_close(void *opaque)

{

    QEMUFileSocket *s = opaque;

    closesocket(s->fd);

    g_free(s);

    return 0;

}


static int cpu_pre_load(void *opaque)

{

    CPUState *env = opaque;

    cpu_synchronize_state(env);

    return 0;

}


static int cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t *buf_end)
{
    int pal_start, pal_count, i, ret, fps;
    if(buf_end - buf < 16) {
        av_log(s->avctx, AV_LOG_WARNING, "truncated header\n");
        return AVERROR_INVALIDDATA;
    s->width  = AV_RL16(&buf[4]);
    s->height = AV_RL16(&buf[6]);
    ret = ff_set_dimensions(s->avctx, s->width, s->height);
    if (ret < 0)
        return ret;
    fps = AV_RL16(&buf[10]);
    if (fps > 0)
        s->avctx->time_base = (AVRational){ 1, fps };
    pal_start = AV_RL16(&buf[12]);
    pal_count = AV_RL16(&buf[14]);
    buf += 16;
    for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) {
        s->palette[i] = AV_RB24(buf);
        buf += 3;
    return 0;


static target_ulong h_register_process_table(PowerPCCPU *cpu,

                                             sPAPRMachineState *spapr,

                                             target_ulong opcode,

                                             target_ulong *args)

{

    qemu_log_mask(LOG_UNIMP, "Unimplemented SPAPR hcall 0x"TARGET_FMT_lx"%s\n",

                  opcode, " (H_REGISTER_PROC_TBL)");

    return H_FUNCTION;

}


static void uhci_async_cancel_all(UHCIState *s)

{

    UHCIQueue *queue, *nq;

    QTAILQ_FOREACH_SAFE(queue, &s->queues, next, nq) {

        uhci_queue_free(queue);

    }

}


static uint64_t get_migration_pass(void)

{

    QDict *rsp, *rsp_return, *rsp_ram;

    uint64_t result;

    rsp = return_or_event(qmp("{ 'execute': 'query-migrate' }"));

    rsp_return = qdict_get_qdict(rsp, "return");

    if (!qdict_haskey(rsp_return, "ram")) {

        /* Still in setup */

        result = 0;

    } else {

        rsp_ram = qdict_get_qdict(rsp_return, "ram");

        result = qdict_get_try_int(rsp_ram, "dirty-sync-count", 0);

        QDECREF(rsp);

    }

    return result;

}


static int img_compare(int argc, char **argv)

{

    const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;

    BlockBackend *blk1, *blk2;

    BlockDriverState *bs1, *bs2;

    int64_t total_sectors1, total_sectors2;

    uint8_t *buf1 = NULL, *buf2 = NULL;

    int pnum1, pnum2;

    int allocated1, allocated2;

    int ret = 0; /* return value - 0 Ident, 1 Different, >1 Error */

    bool progress = false, quiet = false, strict = false;

    int flags;

    bool writethrough;

    int64_t total_sectors;

    int64_t sector_num = 0;

    int64_t nb_sectors;

    int c, pnum;

    uint64_t progress_base;

    bool image_opts = false;

    cache = BDRV_DEFAULT_CACHE;

    for (;;) {

        static const struct option long_options[] = {

            {"help", no_argument, 0, 'h'},

            {"object", required_argument, 0, OPTION_OBJECT},

            {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},

            {0, 0, 0, 0}

        };

        c = getopt_long(argc, argv, "hf:F:T:pqs",

                        long_options, NULL);

        if (c == -1) {

            break;

        }

        switch (c) {

        case '?':

        case 'h':

            help();

            break;

        case 'f':

            fmt1 = optarg;

            break;

        case 'F':

            fmt2 = optarg;

            break;

        case 'T':

            cache = optarg;

            break;

        case 'p':

            progress = true;

            break;

        case 'q':

            quiet = true;

            break;

        case 's':

            strict = true;

            break;

        case OPTION_OBJECT: {

            QemuOpts *opts;

            opts = qemu_opts_parse_noisily(&qemu_object_opts,

                                           optarg, true);

            if (!opts) {

                ret = 2;

                goto out4;

            }

        }   break;

        case OPTION_IMAGE_OPTS:

            image_opts = true;

            break;

        }

    }

    /* Progress is not shown in Quiet mode */

    if (quiet) {

        progress = false;

    }

    if (optind != argc - 2) {

        error_exit("Expecting two image file names");

    }

    filename1 = argv[optind++];

    filename2 = argv[optind++];

    if (qemu_opts_foreach(&qemu_object_opts,

                          user_creatable_add_opts_foreach,

                          NULL, NULL)) {

        ret = 2;

        goto out4;

    }

    /* Initialize before goto out */

    qemu_progress_init(progress, 2.0);

    flags = 0;

    ret = bdrv_parse_cache_mode(cache, &flags, &writethrough);

    if (ret < 0) {

        error_report("Invalid source cache option: %s", cache);

        ret = 2;

        goto out3;

    }

    blk1 = img_open(image_opts, filename1, fmt1, flags, writethrough, quiet);

    if (!blk1) {

        ret = 2;

        goto out3;

    }

    blk2 = img_open(image_opts, filename2, fmt2, flags, writethrough, quiet);

    if (!blk2) {

        ret = 2;

        goto out2;

    }

    bs1 = blk_bs(blk1);

    bs2 = blk_bs(blk2);

    buf1 = blk_blockalign(blk1, IO_BUF_SIZE);

    buf2 = blk_blockalign(blk2, IO_BUF_SIZE);

    total_sectors1 = blk_nb_sectors(blk1);

    if (total_sectors1 < 0) {

        error_report("Can't get size of %s: %s",

                     filename1, strerror(-total_sectors1));

        ret = 4;

        goto out;

    }

    total_sectors2 = blk_nb_sectors(blk2);

    if (total_sectors2 < 0) {

        error_report("Can't get size of %s: %s",

                     filename2, strerror(-total_sectors2));

        ret = 4;

        goto out;

    }

    total_sectors = MIN(total_sectors1, total_sectors2);

    progress_base = MAX(total_sectors1, total_sectors2);

    qemu_progress_print(0, 100);

    if (strict && total_sectors1 != total_sectors2) {

        ret = 1;

        qprintf(quiet, "Strict mode: Image size mismatch!\n");

        goto out;

    }

    for (;;) {

        int64_t status1, status2;

        BlockDriverState *file;

        nb_sectors = sectors_to_process(total_sectors, sector_num);

        if (nb_sectors <= 0) {

            break;

        }

        status1 = bdrv_get_block_status_above(bs1, NULL, sector_num,

                                              total_sectors1 - sector_num,

                                              &pnum1, &file);

        if (status1 < 0) {

            ret = 3;

            error_report("Sector allocation test failed for %s", filename1);

            goto out;

        }

        allocated1 = status1 & BDRV_BLOCK_ALLOCATED;

        status2 = bdrv_get_block_status_above(bs2, NULL, sector_num,

                                              total_sectors2 - sector_num,

                                              &pnum2, &file);

        if (status2 < 0) {

            ret = 3;

            error_report("Sector allocation test failed for %s", filename2);

            goto out;

        }

        allocated2 = status2 & BDRV_BLOCK_ALLOCATED;

        if (pnum1) {

            nb_sectors = MIN(nb_sectors, pnum1);

        }

        if (pnum2) {

            nb_sectors = MIN(nb_sectors, pnum2);

        }

        if (strict) {

            if ((status1 & ~BDRV_BLOCK_OFFSET_MASK) !=

                (status2 & ~BDRV_BLOCK_OFFSET_MASK)) {

                ret = 1;

                qprintf(quiet, "Strict mode: Offset %" PRId64

                        " block status mismatch!\n",

                        sectors_to_bytes(sector_num));

                goto out;

            }

        }

        if ((status1 & BDRV_BLOCK_ZERO) && (status2 & BDRV_BLOCK_ZERO)) {

            nb_sectors = MIN(pnum1, pnum2);

        } else if (allocated1 == allocated2) {

            if (allocated1) {

                ret = blk_pread(blk1, sector_num << BDRV_SECTOR_BITS, buf1,

                                nb_sectors << BDRV_SECTOR_BITS);

                if (ret < 0) {

                    error_report("Error while reading offset %" PRId64 " of %s:"

                                 " %s", sectors_to_bytes(sector_num), filename1,

                                 strerror(-ret));

                    ret = 4;

                    goto out;

                }

                ret = blk_pread(blk2, sector_num << BDRV_SECTOR_BITS, buf2,

                                nb_sectors << BDRV_SECTOR_BITS);

                if (ret < 0) {

                    error_report("Error while reading offset %" PRId64

                                 " of %s: %s", sectors_to_bytes(sector_num),

                                 filename2, strerror(-ret));

                    ret = 4;

                    goto out;

                }

                ret = compare_sectors(buf1, buf2, nb_sectors, &pnum);

                if (ret || pnum != nb_sectors) {

                    qprintf(quiet, "Content mismatch at offset %" PRId64 "!\n",

                            sectors_to_bytes(

                                ret ? sector_num : sector_num + pnum));

                    ret = 1;

                    goto out;

                }

            }

        } else {

            if (allocated1) {

                ret = check_empty_sectors(blk1, sector_num, nb_sectors,

                                          filename1, buf1, quiet);

            } else {

                ret = check_empty_sectors(blk2, sector_num, nb_sectors,

                                          filename2, buf1, quiet);

            }

            if (ret) {

                if (ret < 0) {

                    error_report("Error while reading offset %" PRId64 ": %s",

                                 sectors_to_bytes(sector_num), strerror(-ret));

                    ret = 4;

                }

                goto out;

            }

        }

        sector_num += nb_sectors;

        qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);

    }

    if (total_sectors1 != total_sectors2) {

        BlockBackend *blk_over;

        int64_t total_sectors_over;

        const char *filename_over;

        qprintf(quiet, "Warning: Image size mismatch!\n");

        if (total_sectors1 > total_sectors2) {

            total_sectors_over = total_sectors1;

            blk_over = blk1;

            filename_over = filename1;

        } else {

            total_sectors_over = total_sectors2;

            blk_over = blk2;

            filename_over = filename2;

        }

        for (;;) {

            nb_sectors = sectors_to_process(total_sectors_over, sector_num);

            if (nb_sectors <= 0) {

                break;

            }

            ret = bdrv_is_allocated_above(blk_bs(blk_over), NULL, sector_num,

                                          nb_sectors, &pnum);

            if (ret < 0) {

                ret = 3;

                error_report("Sector allocation test failed for %s",

                             filename_over);

                goto out;

            }

            nb_sectors = pnum;

            if (ret) {

                ret = check_empty_sectors(blk_over, sector_num, nb_sectors,

                                          filename_over, buf1, quiet);

                if (ret) {

                    if (ret < 0) {

                        error_report("Error while reading offset %" PRId64

                                     " of %s: %s", sectors_to_bytes(sector_num),

                                     filename_over, strerror(-ret));

                        ret = 4;

                    }

                    goto out;

                }

            }

            sector_num += nb_sectors;

            qemu_progress_print(((float) nb_sectors / progress_base)*100, 100);

        }

    }

    qprintf(quiet, "Images are identical.\n");

    ret = 0;

out:

    qemu_vfree(buf1);

    qemu_vfree(buf2);

    blk_unref(blk2);

out2:

    blk_unref(blk1);

out3:

    qemu_progress_end();

out4:

    return ret;

}


vmxnet3_io_bar0_write(void *opaque, hwaddr addr,
                      uint64_t val, unsigned size)
{
    VMXNET3State *s = opaque;
    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_TXPROD,
                        VMXNET3_DEVICE_MAX_TX_QUEUES, VMXNET3_REG_ALIGN)) {
        int tx_queue_idx =
            VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_TXPROD,
                                     VMXNET3_REG_ALIGN);
        assert(tx_queue_idx <= s->txq_num);
        vmxnet3_process_tx_queue(s, tx_queue_idx);
    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR,
                        VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) {
        int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR,
                                         VMXNET3_REG_ALIGN);
        VMW_CBPRN("Interrupt mask for line %d written: 0x%" PRIx64, l, val);
        vmxnet3_on_interrupt_mask_changed(s, l, val);
    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_RXPROD,
                        VMXNET3_DEVICE_MAX_RX_QUEUES, VMXNET3_REG_ALIGN) ||
       VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_RXPROD2,
                        VMXNET3_DEVICE_MAX_RX_QUEUES, VMXNET3_REG_ALIGN)) {
    VMW_WRPRN("BAR0 unknown write [%" PRIx64 "] = %" PRIx64 ", size %d",
              (uint64_t) addr, val, size);


static av_cold int hevc_decode_free(AVCodecContext *avctx)

{

    HEVCContext       *s = avctx->priv_data;

    HEVCLocalContext *lc = s->HEVClc;

    int i;

    pic_arrays_free(s);

    av_freep(&lc->edge_emu_buffer);

    av_freep(&s->md5_ctx);

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

        av_freep(&s->skipped_bytes_pos_nal[i]);

    }

    av_freep(&s->skipped_bytes_pos_size_nal);

    av_freep(&s->skipped_bytes_nal);

    av_freep(&s->skipped_bytes_pos_nal);

    av_freep(&s->cabac_state);

    av_frame_free(&s->tmp_frame);

    av_frame_free(&s->output_frame);

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

        ff_hevc_unref_frame(s, &s->DPB[i], ~0);

        av_frame_free(&s->DPB[i].frame);

    }

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

        av_freep(&s->vps_list[i]);

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

        av_buffer_unref(&s->sps_list[i]);

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

        av_buffer_unref(&s->pps_list[i]);

    av_freep(&s->sh.entry_point_offset);

    av_freep(&s->sh.offset);

    av_freep(&s->sh.size);

    for (i = 1; i < s->threads_number; i++) {

        lc = s->HEVClcList[i];

        if (lc) {

            av_freep(&lc->edge_emu_buffer);

            av_freep(&s->HEVClcList[i]);

            av_freep(&s->sList[i]);

        }

    }

    av_freep(&s->HEVClcList[0]);

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

        av_freep(&s->nals[i].rbsp_buffer);

    av_freep(&s->nals);

    s->nals_allocated = 0;

    return 0;

}


static void handle_child_exit(int sig)

{

    pid_t pid;

    int status;

    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {

        FFServerStream *feed;

        for (feed = config.first_feed; feed; feed = feed->next) {

            if (feed->pid == pid) {

                int uptime = time(0) - feed->pid_start;

                feed->pid = 0;

                fprintf(stderr, "%s: Pid %d exited with status %d after %d seconds\n", feed->filename, pid, status, uptime);

                if (uptime < 30)

                    /* Turn off any more restarts */

                    feed->child_argv = 0;

            }

        }

    }

    need_to_start_children = 1;

}


static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,

                            ram_addr_t current_addr, RAMBlock *block,

                            ram_addr_t offset, int cont, bool last_stage)

{

    int encoded_len = 0, bytes_sent = -1;

    uint8_t *prev_cached_page;

    if (!cache_is_cached(XBZRLE.cache, current_addr)) {

        if (!last_stage) {

            if (cache_insert(XBZRLE.cache, current_addr, current_data) == -1) {

                return -1;

            }

        }

        acct_info.xbzrle_cache_miss++;

        return -1;

    }

    prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);

    /* save current buffer into memory */

    memcpy(XBZRLE.current_buf, current_data, TARGET_PAGE_SIZE);

    /* XBZRLE encoding (if there is no overflow) */

    encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,

                                       TARGET_PAGE_SIZE, XBZRLE.encoded_buf,

                                       TARGET_PAGE_SIZE);

    if (encoded_len == 0) {

        DPRINTF("Skipping unmodified page\n");

        return 0;

    } else if (encoded_len == -1) {

        DPRINTF("Overflow\n");

        acct_info.xbzrle_overflows++;

        /* update data in the cache */

        memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);

        return -1;

    }

    /* we need to update the data in the cache, in order to get the same data */

    if (!last_stage) {

        memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);

    }

    /* Send XBZRLE based compressed page */

    bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);

    qemu_put_byte(f, ENCODING_FLAG_XBZRLE);

    qemu_put_be16(f, encoded_len);

    qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);

    bytes_sent += encoded_len + 1 + 2;

    acct_info.xbzrle_pages++;

    acct_info.xbzrle_bytes += bytes_sent;

    return bytes_sent;

}


static void do_info_registers(Monitor *mon)

{

    CPUState *env;

    env = mon_get_cpu();

    if (!env)

        return;

#ifdef TARGET_I386

    cpu_dump_state(env, (FILE *)mon, monitor_fprintf,

                   X86_DUMP_FPU);

#else

    cpu_dump_state(env, (FILE *)mon, monitor_fprintf,

                   0);

#endif

}


static int wsaud_read_packet(AVFormatContext *s,
                             AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
    unsigned int chunk_size;
    int ret = 0;
    AVStream *st = s->streams[0];
    if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
        AUD_CHUNK_PREAMBLE_SIZE)
        return AVERROR(EIO);
    /* validate the chunk */
    if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE)
    chunk_size = AV_RL16(&preamble[0]);
    if (st->codecpar->codec_id == AV_CODEC_ID_WESTWOOD_SND1) {
        /* For Westwood SND1 audio we need to add the output size and input
           size to the start of the packet to match what is in VQA.
           Specifically, this is needed to signal when a packet should be
           decoding as raw 8-bit pcm or variable-size ADPCM. */
        int out_size = AV_RL16(&preamble[2]);
        if ((ret = av_new_packet(pkt, chunk_size + 4)) < 0)
            return ret;
        if ((ret = avio_read(pb, &pkt->data[4], chunk_size)) != chunk_size)
            return ret < 0 ? ret : AVERROR(EIO);
        AV_WL16(&pkt->data[0], out_size);
        AV_WL16(&pkt->data[2], chunk_size);
        pkt->duration = out_size;
    } else {
        ret = av_get_packet(pb, pkt, chunk_size);
        if (ret != chunk_size)
            return AVERROR(EIO);
        /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
        pkt->duration = (chunk_size * 2) / st->codecpar->channels;
    pkt->stream_index = st->index;
    return ret;


static int qemu_chr_open_win(QemuOpts *opts, CharDriverState **_chr)

{

    const char *filename = qemu_opt_get(opts, "path");

    CharDriverState *chr;

    WinCharState *s;

    chr = g_malloc0(sizeof(CharDriverState));

    s = g_malloc0(sizeof(WinCharState));

    chr->opaque = s;

    chr->chr_write = win_chr_write;

    chr->chr_close = win_chr_close;

    if (win_chr_init(chr, filename) < 0) {

        g_free(s);

        g_free(chr);

        return -EIO;

    }

    qemu_chr_generic_open(chr);

    *_chr = chr;

    return 0;

}