int ff_hevc_decode_nal_sps(HEVCContext *s)

{

    const AVPixFmtDescriptor *desc;

    GetBitContext *gb = &s->HEVClc->gb;

    int ret    = 0;

    int sps_id = 0;

    int log2_diff_max_min_transform_block_size;

    int bit_depth_chroma, start, vui_present, sublayer_ordering_info;

    int i;

    HEVCSPS *sps;

    AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));

    if (!sps_buf)

        return AVERROR(ENOMEM);

    sps = (HEVCSPS*)sps_buf->data;

    av_log(s->avctx, AV_LOG_DEBUG, "Decoding SPS\n");

    // Coded parameters

    sps->vps_id = get_bits(gb, 4);

    if (sps->vps_id >= MAX_VPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    if (!s->vps_list[sps->vps_id]) {

        av_log(s->avctx, AV_LOG_ERROR, "VPS does not exist \n");

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sps->max_sub_layers = get_bits(gb, 3) + 1;

    if (sps->max_sub_layers > MAX_SUB_LAYERS) {

        av_log(s->avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",

               sps->max_sub_layers);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    skip_bits1(gb); // temporal_id_nesting_flag

    parse_ptl(s, &sps->ptl, sps->max_sub_layers);

    sps_id = get_ue_golomb_long(gb);

    if (sps_id >= MAX_SPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", sps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sps->chroma_format_idc = get_ue_golomb_long(gb);

    if (sps->chroma_format_idc != 1) {

        avpriv_report_missing_feature(s->avctx, "chroma_format_idc != 1\n");

        ret = AVERROR_PATCHWELCOME;

        goto err;

    }

    if (sps->chroma_format_idc == 3)

        sps->separate_colour_plane_flag = get_bits1(gb);

    sps->width  = get_ue_golomb_long(gb);

    sps->height = get_ue_golomb_long(gb);

    if ((ret = av_image_check_size(sps->width,

                                   sps->height, 0, s->avctx)) < 0)

        goto err;

    if (get_bits1(gb)) { // pic_conformance_flag

        //TODO: * 2 is only valid for 420

        sps->pic_conf_win.left_offset   = get_ue_golomb_long(gb) * 2;

        sps->pic_conf_win.right_offset  = get_ue_golomb_long(gb) * 2;

        sps->pic_conf_win.top_offset    = get_ue_golomb_long(gb) * 2;

        sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * 2;

        if (s->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {

            av_log(s->avctx, AV_LOG_DEBUG,

                   "discarding sps conformance window, "

                   "original values are l:%u r:%u t:%u b:%u\n",

                   sps->pic_conf_win.left_offset,

                   sps->pic_conf_win.right_offset,

                   sps->pic_conf_win.top_offset,

                   sps->pic_conf_win.bottom_offset);

            sps->pic_conf_win.left_offset   =

            sps->pic_conf_win.right_offset  =

            sps->pic_conf_win.top_offset    =

            sps->pic_conf_win.bottom_offset = 0;

        }

        sps->output_window = sps->pic_conf_win;

    }

    sps->bit_depth   = get_ue_golomb_long(gb) + 8;

    bit_depth_chroma = get_ue_golomb_long(gb) + 8;

    if (bit_depth_chroma != sps->bit_depth) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Luma bit depth (%d) is different from chroma bit depth (%d), "

               "this is unsupported.\n",

               sps->bit_depth, bit_depth_chroma);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    if (sps->chroma_format_idc == 1) {

        switch (sps->bit_depth) {

        case 8:  sps->pix_fmt = AV_PIX_FMT_YUV420P;   break;

        case 9:  sps->pix_fmt = AV_PIX_FMT_YUV420P9;  break;

        case 10: sps->pix_fmt = AV_PIX_FMT_YUV420P10; break;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n",

                   sps->bit_depth);

            ret = AVERROR_PATCHWELCOME;

            goto err;

        }

    } else {

        av_log(s->avctx, AV_LOG_ERROR,

               "non-4:2:0 support is currently unspecified.\n");

        return AVERROR_PATCHWELCOME;

    }

    desc = av_pix_fmt_desc_get(sps->pix_fmt);

    if (!desc) {

        ret = AVERROR(EINVAL);

        goto err;

    }

    sps->hshift[0] = sps->vshift[0] = 0;

    sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;

    sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;

    sps->pixel_shift = sps->bit_depth > 8;

    sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4;

    if (sps->log2_max_poc_lsb > 16) {

        av_log(s->avctx, AV_LOG_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",

               sps->log2_max_poc_lsb - 4);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sublayer_ordering_info = get_bits1(gb);

    start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;

    for (i = start; i < sps->max_sub_layers; i++) {

        sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1;

        sps->temporal_layer[i].num_reorder_pics      = get_ue_golomb_long(gb);

        sps->temporal_layer[i].max_latency_increase  = get_ue_golomb_long(gb) - 1;

        if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {

            av_log(s->avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n",

                   sps->temporal_layer[i].max_dec_pic_buffering - 1);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {

            av_log(s->avctx, AV_LOG_ERROR, "sps_max_num_reorder_pics out of range: %d\n",

                   sps->temporal_layer[i].num_reorder_pics);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

    }

    if (!sublayer_ordering_info) {

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

            sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering;

            sps->temporal_layer[i].num_reorder_pics      = sps->temporal_layer[start].num_reorder_pics;

            sps->temporal_layer[i].max_latency_increase  = sps->temporal_layer[start].max_latency_increase;

        }

    }

    sps->log2_min_cb_size                    = get_ue_golomb_long(gb) + 3;

    sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb);

    sps->log2_min_tb_size                    = get_ue_golomb_long(gb) + 2;

    log2_diff_max_min_transform_block_size   = get_ue_golomb_long(gb);

    sps->log2_max_trafo_size                 = log2_diff_max_min_transform_block_size +

                                               sps->log2_min_tb_size;

    if (sps->log2_min_tb_size >= sps->log2_min_cb_size) {

        av_log(s->avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);

    sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);

    sps->scaling_list_enable_flag = get_bits1(gb);

    if (sps->scaling_list_enable_flag) {

        set_default_scaling_list_data(&sps->scaling_list);

        if (get_bits1(gb)) {

            ret = scaling_list_data(s, &sps->scaling_list);

            if (ret < 0)

                goto err;

        }

    }

    sps->amp_enabled_flag = get_bits1(gb);

    sps->sao_enabled      = get_bits1(gb);

    sps->pcm_enabled_flag = get_bits1(gb);

    if (sps->pcm_enabled_flag) {

        sps->pcm.bit_depth   = get_bits(gb, 4) + 1;

        sps->pcm.bit_depth_chroma = get_bits(gb, 4) + 1;

        sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3;

        sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +

                                        get_ue_golomb_long(gb);

        if (sps->pcm.bit_depth > sps->bit_depth) {

            av_log(s->avctx, AV_LOG_ERROR,

                   "PCM bit depth (%d) is greater than normal bit depth (%d)\n",

                   sps->pcm.bit_depth, sps->bit_depth);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        sps->pcm.loop_filter_disable_flag = get_bits1(gb);

    }

    sps->nb_st_rps = get_ue_golomb_long(gb);

    if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",

               sps->nb_st_rps);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    for (i = 0; i < sps->nb_st_rps; i++) {

        if ((ret = ff_hevc_decode_short_term_rps(s, &sps->st_rps[i],

                                                 sps, 0)) < 0)

            goto err;

    }

    sps->long_term_ref_pics_present_flag = get_bits1(gb);

    if (sps->long_term_ref_pics_present_flag) {

        sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);

        for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {

            sps->lt_ref_pic_poc_lsb_sps[i]       = get_bits(gb, sps->log2_max_poc_lsb);

            sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);

        }

    }

    sps->sps_temporal_mvp_enabled_flag          = get_bits1(gb);

    sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);

    sps->vui.sar = (AVRational){0, 1};

    vui_present = get_bits1(gb);

    if (vui_present)

        decode_vui(s, sps);

    skip_bits1(gb); // sps_extension_flag

    if (s->apply_defdispwin) {

        sps->output_window.left_offset   += sps->vui.def_disp_win.left_offset;

        sps->output_window.right_offset  += sps->vui.def_disp_win.right_offset;

        sps->output_window.top_offset    += sps->vui.def_disp_win.top_offset;

        sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;

    }

    if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&

        !(s->avctx->flags & CODEC_FLAG_UNALIGNED)) {

        sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));

        av_log(s->avctx, AV_LOG_WARNING, "Reducing left output window to %d "

               "chroma samples to preserve alignment.\n",

               sps->output_window.left_offset);

    }

    sps->output_width  = sps->width -

                         (sps->output_window.left_offset + sps->output_window.right_offset);

    sps->output_height = sps->height -

                         (sps->output_window.top_offset + sps->output_window.bottom_offset);

    if (sps->output_width <= 0 || sps->output_height <= 0) {

        av_log(s->avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",

               sps->output_width, sps->output_height);

        if (s->avctx->err_recognition & AV_EF_EXPLODE) {

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        av_log(s->avctx, AV_LOG_WARNING,

               "Displaying the whole video surface.\n");

        sps->pic_conf_win.left_offset   =

        sps->pic_conf_win.right_offset  =

        sps->pic_conf_win.top_offset    =

        sps->pic_conf_win.bottom_offset = 0;

        sps->output_width               = sps->width;

        sps->output_height              = sps->height;

    }

    // Inferred parameters

    sps->log2_ctb_size = sps->log2_min_cb_size +

                         sps->log2_diff_max_min_coding_block_size;

    sps->log2_min_pu_size = sps->log2_min_cb_size - 1;

    sps->ctb_width  = (sps->width  + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;

    sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;

    sps->ctb_size   = sps->ctb_width * sps->ctb_height;

    sps->min_cb_width  = sps->width  >> sps->log2_min_cb_size;

    sps->min_cb_height = sps->height >> sps->log2_min_cb_size;

    sps->min_tb_width  = sps->width  >> sps->log2_min_tb_size;

    sps->min_tb_height = sps->height >> sps->log2_min_tb_size;

    sps->min_pu_width  = sps->width  >> sps->log2_min_pu_size;

    sps->min_pu_height = sps->height >> sps->log2_min_pu_size;

    sps->qp_bd_offset = 6 * (sps->bit_depth - 8);

    if (sps->width  & ((1 << sps->log2_min_cb_size) - 1) ||

        sps->height & ((1 << sps->log2_min_cb_size) - 1)) {

        av_log(s->avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");

        goto err;

    }

    if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {

        av_log(s->avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);

        goto err;

    }

    if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {

        av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",

               sps->max_transform_hierarchy_depth_inter);

        goto err;

    }

    if (sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_size) {

        av_log(s->avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n",

               sps->max_transform_hierarchy_depth_intra);

        goto err;

    }

    if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) {

        av_log(s->avctx, AV_LOG_ERROR,

               "max transform block size out of range: %d\n",

               sps->log2_max_trafo_size);

        goto err;

    }

    if (s->avctx->debug & FF_DEBUG_BITSTREAM) {

        av_log(s->avctx, AV_LOG_DEBUG,

               "Parsed SPS: id %d; coded wxh: %dx%d; "

               "cropped wxh: %dx%d; pix_fmt: %s.\n",

               sps_id, sps->width, sps->height,

               sps->output_width, sps->output_height,

               av_get_pix_fmt_name(sps->pix_fmt));

    }

    /* check if this is a repeat of an already parsed SPS, then keep the

     * original one.

     * otherwise drop all PPSes that depend on it */

    if (s->sps_list[sps_id] &&

        !memcmp(s->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {

        av_buffer_unref(&sps_buf);

    } else {

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

            if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == sps_id)

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

        }

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

        s->sps_list[sps_id] = sps_buf;

    }

    return 0;

err:

    av_buffer_unref(&sps_buf);

    return ret;

}


static void do_audio_out(AVFormatContext *s, OutputStream *ost,

                         InputStream *ist, AVFrame *decoded_frame)

{

    uint8_t *buftmp;

    int size_out, frame_bytes, resample_changed;

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

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

    int osize = av_get_bytes_per_sample(enc->sample_fmt);

    int isize = av_get_bytes_per_sample(dec->sample_fmt);

    uint8_t *buf = decoded_frame->data[0];

    int size     = decoded_frame->nb_samples * dec->channels * isize;

    if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples) < 0) {

        av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n");

        exit_program(1);

    }

    if (enc->channels != dec->channels || enc->sample_rate != dec->sample_rate)

        ost->audio_resample = 1;

    resample_changed = ost->resample_sample_fmt  != dec->sample_fmt ||

                       ost->resample_channels    != dec->channels   ||

                       ost->resample_sample_rate != dec->sample_rate;

    if ((ost->audio_resample && !ost->resample) || resample_changed) {

        if (resample_changed) {

            av_log(NULL, AV_LOG_INFO, "Input stream #%d:%d frame changed from rate:%d fmt:%s ch:%d to rate:%d fmt:%s ch:%d\n",

                   ist->file_index, ist->st->index,

                   ost->resample_sample_rate, av_get_sample_fmt_name(ost->resample_sample_fmt), ost->resample_channels,

                   dec->sample_rate, av_get_sample_fmt_name(dec->sample_fmt), dec->channels);

            ost->resample_sample_fmt  = dec->sample_fmt;

            ost->resample_channels    = dec->channels;

            ost->resample_sample_rate = dec->sample_rate;

            if (ost->resample)

                audio_resample_close(ost->resample);

        }

        /* if audio_sync_method is >1 the resampler is needed for audio drift compensation */

        if (audio_sync_method <= 1 &&

            ost->resample_sample_fmt  == enc->sample_fmt &&

            ost->resample_channels    == enc->channels   &&

            ost->resample_sample_rate == enc->sample_rate) {

            ost->resample = NULL;

            ost->audio_resample = 0;

        } else if (ost->audio_resample) {

            if (dec->sample_fmt != AV_SAMPLE_FMT_S16)

                av_log(NULL, AV_LOG_WARNING, "Using s16 intermediate sample format for resampling\n");

            ost->resample = av_audio_resample_init(enc->channels,    dec->channels,

                                                   enc->sample_rate, dec->sample_rate,

                                                   enc->sample_fmt,  dec->sample_fmt,

                                                   16, 10, 0, 0.8);

            if (!ost->resample) {

                av_log(NULL, AV_LOG_FATAL, "Can not resample %d channels @ %d Hz to %d channels @ %d Hz\n",

                       dec->channels, dec->sample_rate,

                       enc->channels, enc->sample_rate);

                exit_program(1);

            }

        }

    }

#define MAKE_SFMT_PAIR(a,b) ((a)+AV_SAMPLE_FMT_NB*(b))

    if (!ost->audio_resample && dec->sample_fmt != enc->sample_fmt &&

        MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt) != ost->reformat_pair) {

        if (ost->reformat_ctx)

            av_audio_convert_free(ost->reformat_ctx);

        ost->reformat_ctx = av_audio_convert_alloc(enc->sample_fmt, 1,

                                                   dec->sample_fmt, 1, NULL, 0);

        if (!ost->reformat_ctx) {

            av_log(NULL, AV_LOG_FATAL, "Cannot convert %s sample format to %s sample format\n",

                   av_get_sample_fmt_name(dec->sample_fmt),

                   av_get_sample_fmt_name(enc->sample_fmt));

            exit_program(1);

        }

        ost->reformat_pair = MAKE_SFMT_PAIR(enc->sample_fmt,dec->sample_fmt);

    }

    if (audio_sync_method) {

        double delta = get_sync_ipts(ost, ist->last_dts) * enc->sample_rate - ost->sync_opts -

                       av_fifo_size(ost->fifo) / (enc->channels * osize);

        int idelta = delta * dec->sample_rate / enc->sample_rate;

        int byte_delta = idelta * isize * dec->channels;

        // FIXME resample delay

        if (fabs(delta) > 50) {

            if (ist->is_start || fabs(delta) > audio_drift_threshold*enc->sample_rate) {

                if (byte_delta < 0) {

                    byte_delta = FFMAX(byte_delta, -size);

                    size += byte_delta;

                    buf  -= byte_delta;

                    av_log(NULL, AV_LOG_VERBOSE, "discarding %d audio samples\n",

                           -byte_delta / (isize * dec->channels));

                    if (!size)

                        return;

                    ist->is_start = 0;

                } else {

                    av_fast_malloc(&async_buf, &allocated_async_buf_size,

                                   byte_delta + size);

                    if (!async_buf) {

                        av_log(NULL, AV_LOG_FATAL, "Out of memory in do_audio_out\n");

                        exit_program(1);

                    }

                    if (alloc_audio_output_buf(dec, enc, decoded_frame->nb_samples + idelta) < 0) {

                        av_log(NULL, AV_LOG_FATAL, "Error allocating audio buffer\n");

                        exit_program(1);

                    }

                    ist->is_start = 0;

                    generate_silence(async_buf, dec->sample_fmt, byte_delta);

                    memcpy(async_buf + byte_delta, buf, size);

                    buf = async_buf;

                    size += byte_delta;

                    av_log(NULL, AV_LOG_VERBOSE, "adding %d audio samples of silence\n", idelta);

                }

            } else if (audio_sync_method > 1) {

                int comp = av_clip(delta, -audio_sync_method, audio_sync_method);

                av_assert0(ost->audio_resample);

                av_log(NULL, AV_LOG_VERBOSE, "compensating audio timestamp drift:%f compensation:%d in:%d\n",

                       delta, comp, enc->sample_rate);

//                fprintf(stderr, "drift:%f len:%d opts:%"PRId64" ipts:%"PRId64" fifo:%d\n", delta, -1, ost->sync_opts, (int64_t)(get_sync_ipts(ost) * enc->sample_rate), av_fifo_size(ost->fifo)/(ost->st->codec->channels * 2));

                av_resample_compensate(*(struct AVResampleContext**)ost->resample, comp, enc->sample_rate);

            }

        }

    } else

        ost->sync_opts = lrintf(get_sync_ipts(ost, ist->last_dts) * enc->sample_rate) -

                                av_fifo_size(ost->fifo) / (enc->channels * osize); // FIXME wrong

    if (ost->audio_resample) {

        buftmp = audio_buf;

        size_out = audio_resample(ost->resample,

                                  (short *)buftmp, (short *)buf,

                                  size / (dec->channels * isize));

        size_out = size_out * enc->channels * osize;

    } else {

        buftmp = buf;

        size_out = size;

    }

    if (!ost->audio_resample && dec->sample_fmt != enc->sample_fmt) {

        const void *ibuf[6] = { buftmp };

        void *obuf[6]  = { audio_buf };

        int istride[6] = { isize };

        int ostride[6] = { osize };

        int len = size_out / istride[0];

        if (av_audio_convert(ost->reformat_ctx, obuf, ostride, ibuf, istride, len) < 0) {

            printf("av_audio_convert() failed\n");

            if (exit_on_error)

                exit_program(1);

            return;

        }

        buftmp = audio_buf;

        size_out = len * osize;

    }

    /* now encode as many frames as possible */

    if (!(enc->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) {

        /* output resampled raw samples */

        if (av_fifo_realloc2(ost->fifo, av_fifo_size(ost->fifo) + size_out) < 0) {

            av_log(NULL, AV_LOG_FATAL, "av_fifo_realloc2() failed\n");

            exit_program(1);

        }

        av_fifo_generic_write(ost->fifo, buftmp, size_out, NULL);

        frame_bytes = enc->frame_size * osize * enc->channels;

        while (av_fifo_size(ost->fifo) >= frame_bytes) {

            av_fifo_generic_read(ost->fifo, audio_buf, frame_bytes, NULL);

            encode_audio_frame(s, ost, audio_buf, frame_bytes);

        }

    } else {

        encode_audio_frame(s, ost, buftmp, size_out);

    }

}


void v9fs_string_init(V9fsString *str)

{

    str->data = NULL;

    str->size = 0;

}


static void do_spawn_thread(ThreadPool *pool)

{

    QemuThread t;

    /* Runs with lock taken.  */

    if (!pool->new_threads) {

        return;

    }

    pool->new_threads--;

    pool->pending_threads++;

    qemu_thread_create(&t, "worker", worker_thread, pool, QEMU_THREAD_DETACHED);

}


icmp_input(struct mbuf *m, int hlen)

{

  register struct icmp *icp;

  register struct ip *ip=mtod(m, struct ip *);

  int icmplen=ip->ip_len;

  Slirp *slirp = m->slirp;

  DEBUG_CALL("icmp_input");

  DEBUG_ARG("m = %p", m);

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

  /*

   * Locate icmp structure in mbuf, and check

   * that its not corrupted and of at least minimum length.

   */

  if (icmplen < ICMP_MINLEN) {          /* min 8 bytes payload */

  freeit:

    m_free(m);

    goto end_error;

  }

  m->m_len -= hlen;

  m->m_data += hlen;

  icp = mtod(m, struct icmp *);

  if (cksum(m, icmplen)) {

    goto freeit;

  }

  m->m_len += hlen;

  m->m_data -= hlen;

  DEBUG_ARG("icmp_type = %d", icp->icmp_type);

  switch (icp->icmp_type) {

  case ICMP_ECHO:

    ip->ip_len += hlen;	             /* since ip_input subtracts this */

    if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) {

      icmp_reflect(m);

    } else if (slirp->restricted) {

        goto freeit;

    } else {

      struct socket *so;

      struct sockaddr_in addr;

      if ((so = socreate(slirp)) == NULL) goto freeit;

      if (icmp_send(so, m, hlen) == 0) {

        return;

      }

      if(udp_attach(so) == -1) {

	DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",

		    errno,strerror(errno)));

	sofree(so);

	m_free(m);

	goto end_error;

      }

      so->so_m = m;

      so->so_ffamily = AF_INET;

      so->so_faddr = ip->ip_dst;

      so->so_fport = htons(7);

      so->so_lfamily = AF_INET;

      so->so_laddr = ip->ip_src;

      so->so_lport = htons(9);

      so->so_iptos = ip->ip_tos;

      so->so_type = IPPROTO_ICMP;

      so->so_state = SS_ISFCONNECTED;

      /* Send the packet */

      addr.sin_family = AF_INET;

      if ((so->so_faddr.s_addr & slirp->vnetwork_mask.s_addr) ==

          slirp->vnetwork_addr.s_addr) {

	/* It's an alias */

	if (so->so_faddr.s_addr == slirp->vnameserver_addr.s_addr) {

	  if (get_dns_addr(&addr.sin_addr) < 0)

	    addr.sin_addr = loopback_addr;

	} else {

	  addr.sin_addr = loopback_addr;

	}

      } else {

	addr.sin_addr = so->so_faddr;

      }

      addr.sin_port = so->so_fport;

      if(sendto(so->s, icmp_ping_msg, strlen(icmp_ping_msg), 0,

		(struct sockaddr *)&addr, sizeof(addr)) == -1) {

	DEBUG_MISC((dfd,"icmp_input udp sendto tx errno = %d-%s\n",

		    errno,strerror(errno)));

	icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno));

	udp_detach(so);

      }

    } /* if ip->ip_dst.s_addr == alias_addr.s_addr */

    break;

  case ICMP_UNREACH:

    /* XXX? report error? close socket? */

  case ICMP_TIMXCEED:

  case ICMP_PARAMPROB:

  case ICMP_SOURCEQUENCH:

  case ICMP_TSTAMP:

  case ICMP_MASKREQ:

  case ICMP_REDIRECT:

    m_free(m);

    break;

  default:

    m_free(m);

  } /* swith */

end_error:

  /* m is m_free()'d xor put in a socket xor or given to ip_send */

  return;

}


static void virtio_net_tx_complete(NetClientState *nc, ssize_t len)

{

    VirtIONet *n = qemu_get_nic_opaque(nc);

    VirtIONetQueue *q = virtio_net_get_subqueue(nc);

    VirtIODevice *vdev = VIRTIO_DEVICE(n);

    virtqueue_push(q->tx_vq, &q->async_tx.elem, 0);

    virtio_notify(vdev, q->tx_vq);

    q->async_tx.elem.out_num = 0;

    virtio_queue_set_notification(q->tx_vq, 1);

    virtio_net_flush_tx(q);

}


static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx,

                       Plane *plane, Cell *cell, const uint8_t *data_ptr,

                       const uint8_t *last_ptr)

{

    int           x, mv_x, mv_y, mode, vq_index, prim_indx, second_indx;

    int           zoom_fac;

    int           offset, error = 0, swap_quads[2];

    uint8_t       code, *block, *ref_block = 0;

    const vqEntry *delta[2];

    const uint8_t *data_start = data_ptr;

    /* get coding mode and VQ table index from the VQ descriptor byte */

    code     = *data_ptr++;

    mode     = code >> 4;

    vq_index = code & 0xF;

    /* setup output and reference pointers */

    offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);

    block  =  plane->pixels[ctx->buf_sel] + offset;

    if (!cell->mv_ptr) {

        /* use previous line as reference for INTRA cells */

        ref_block = block - plane->pitch;

    } else if (mode >= 10) {

        /* for mode 10 and 11 INTER first copy the predicted cell into the current one */

        /* so we don't need to do data copying for each RLE code later */

        copy_cell(ctx, plane, cell);

    } else {

        /* set the pointer to the reference pixels for modes 0-4 INTER */

        mv_y      = cell->mv_ptr[0];

        mv_x      = cell->mv_ptr[1];

        if (   mv_x + 4*cell->xpos < 0

            || mv_y + 4*cell->ypos < 0

            || mv_x + 4*cell->xpos + 4*cell->width  > plane->width

            || mv_y + 4*cell->ypos + 4*cell->height > plane->height) {

            av_log(avctx, AV_LOG_ERROR, "motion vector %d %d outside reference\n", mv_x + 4*cell->xpos, mv_y + 4*cell->ypos);

            return AVERROR_INVALIDDATA;

        }

        offset   += mv_y * plane->pitch + mv_x;

        ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;

    }

    /* select VQ tables as follows: */

    /* modes 0 and 3 use only the primary table for all lines in a block */

    /* while modes 1 and 4 switch between primary and secondary tables on alternate lines */

    if (mode == 1 || mode == 4) {

        code        = ctx->alt_quant[vq_index];

        prim_indx   = (code >> 4)  + ctx->cb_offset;

        second_indx = (code & 0xF) + ctx->cb_offset;

    } else {

        vq_index += ctx->cb_offset;

        prim_indx = second_indx = vq_index;

    }

    if (prim_indx >= 24 || second_indx >= 24) {

        av_log(avctx, AV_LOG_ERROR, "Invalid VQ table indexes! Primary: %d, secondary: %d!\n",

               prim_indx, second_indx);

        return AVERROR_INVALIDDATA;

    }

    delta[0] = &vq_tab[second_indx];

    delta[1] = &vq_tab[prim_indx];

    swap_quads[0] = second_indx >= 16;

    swap_quads[1] = prim_indx   >= 16;

    /* requantize the prediction if VQ index of this cell differs from VQ index */

    /* of the predicted cell in order to avoid overflows. */

    if (vq_index >= 8 && ref_block) {

        for (x = 0; x < cell->width << 2; x++)

            ref_block[x] = requant_tab[vq_index & 7][ref_block[x] & 127];

    }

    error = IV3_NOERR;

    switch (mode) {

    case 0: /*------------------ MODES 0 & 1 (4x4 block processing) --------------------*/

    case 1:

    case 3: /*------------------ MODES 3 & 4 (4x8 block processing) --------------------*/

    case 4:

        if (mode >= 3 && cell->mv_ptr) {

            av_log(avctx, AV_LOG_ERROR, "Attempt to apply Mode 3/4 to an INTER cell!\n");

            return AVERROR_INVALIDDATA;

        }

        zoom_fac = mode >= 3;

        error = decode_cell_data(cell, block, ref_block, plane->pitch, 0, zoom_fac,

                                 mode, delta, swap_quads, &data_ptr, last_ptr);

        break;

    case 10: /*-------------------- MODE 10 (8x8 block processing) ---------------------*/

    case 11: /*----------------- MODE 11 (4x8 INTER block processing) ------------------*/

        if (mode == 10 && !cell->mv_ptr) { /* MODE 10 INTRA processing */

            error = decode_cell_data(cell, block, ref_block, plane->pitch, 1, 1,

                                     mode, delta, swap_quads, &data_ptr, last_ptr);

        } else { /* mode 10 and 11 INTER processing */

            if (mode == 11 && !cell->mv_ptr) {

               av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");

               return AVERROR_INVALIDDATA;

            }

            zoom_fac = mode == 10;

            error = decode_cell_data(cell, block, ref_block, plane->pitch,

                                     zoom_fac, 1, mode, delta, swap_quads,

                                     &data_ptr, last_ptr);

        }

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unsupported coding mode: %d\n", mode);

        return AVERROR_INVALIDDATA;

    }//switch mode

    switch (error) {

    case IV3_BAD_RLE:

        av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE code %X is not allowed at the current line\n",

               mode, data_ptr[-1]);

        return AVERROR_INVALIDDATA;

    case IV3_BAD_DATA:

        av_log(avctx, AV_LOG_ERROR, "Mode %d: invalid VQ data\n", mode);

        return AVERROR_INVALIDDATA;

    case IV3_BAD_COUNTER:

        av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE-FB invalid counter: %d\n", mode, code);

        return AVERROR_INVALIDDATA;

    case IV3_UNSUPPORTED:

        av_log(avctx, AV_LOG_ERROR, "Mode %d: unsupported RLE code: %X\n", mode, data_ptr[-1]);

        return AVERROR_INVALIDDATA;

    case IV3_OUT_OF_DATA:

        av_log(avctx, AV_LOG_ERROR, "Mode %d: attempt to read past end of buffer\n", mode);

        return AVERROR_INVALIDDATA;

    }

    return data_ptr - data_start; /* report number of bytes consumed from the input buffer */

}


static int net_socket_mcast_init(NetClientState *peer,

                                 const char *model,

                                 const char *name,

                                 const char *host_str,

                                 const char *localaddr_str)

{

    NetSocketState *s;

    int fd;

    struct sockaddr_in saddr;

    struct in_addr localaddr, *param_localaddr;

    if (parse_host_port(&saddr, host_str) < 0)

        return -1;

    if (localaddr_str != NULL) {

        if (inet_aton(localaddr_str, &localaddr) == 0)

            return -1;

        param_localaddr = &localaddr;

    } else {

        param_localaddr = NULL;

    }

    fd = net_socket_mcast_create(&saddr, param_localaddr);

    if (fd < 0)

        return -1;

    s = net_socket_fd_init(peer, model, name, fd, 0);

    if (!s)

        return -1;

    s->dgram_dst = saddr;

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

             "socket: mcast=%s:%d",

             inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

    return 0;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = pl041_init;

    set_bit(DEVICE_CATEGORY_SOUND, dc->categories);

    dc->no_user = 1;

    dc->reset = pl041_device_reset;

    dc->vmsd = &vmstate_pl041;

    dc->props = pl041_device_properties;

}


static void reduce_matrix(AudioMix *am, const double *matrix, int stride)

{

    int i, o;

    memset(am->output_zero, 0, sizeof(am->output_zero));

    memset(am->input_skip,  0, sizeof(am->input_skip));

    memset(am->output_skip, 0, sizeof(am->output_skip));

    /* exclude output channels if they can be zeroed instead of mixed */

    for (o = 0; o < am->out_channels; o++) {

        int zero = 1;

        /* check if the output is always silent */

        for (i = 0; i < am->in_channels; i++) {

            if (matrix[o * stride + i] != 0.0) {

                zero = 0;

                break;

            }

        }

        /* check if the corresponding input channel makes a contribution to

           any output channel */

        if (o < am->in_channels) {

            for (i = 0; i < am->out_channels; i++) {

                if (matrix[i * stride + o] != 0.0) {

                    zero = 0;

                    break;

                }

            }

        }

        if (zero) {

            am->output_zero[o] = 1;

            am->out_matrix_channels--;

        }

    }

    if (am->out_matrix_channels == 0) {

        am->in_matrix_channels = 0;

        return;

    }

    /* skip input channels that contribute fully only to the corresponding

       output channel */

    for (i = 0; i < FFMIN(am->in_channels, am->out_channels); i++) {

        int skip = 1;

        for (o = 0; o < am->out_channels; o++) {

            int i0;

            if ((o != i && matrix[o * stride + i] != 0.0) ||

                (o == i && matrix[o * stride + i] != 1.0)) {

                skip = 0;

                break;

            }

            /* if the input contributes fully to the output, also check that no

               other inputs contribute to this output */

            if (o == i) {

                for (i0 = 0; i0 < am->in_channels; i0++) {

                    if (i0 != i && matrix[o * stride + i0] != 0.0) {

                        skip = 0;

                        break;

                    }

                }

            }

        }

        if (skip) {

            am->input_skip[i] = 1;

            am->in_matrix_channels--;

        }

    }

    /* skip input channels that do not contribute to any output channel */

    for (; i < am->in_channels; i++) {

        int contrib = 0;

        for (o = 0; o < am->out_channels; o++) {

            if (matrix[o * stride + i] != 0.0) {

                contrib = 1;

                break;

            }

        }

        if (!contrib) {

            am->input_skip[i] = 1;

            am->in_matrix_channels--;

        }

    }

    if (am->in_matrix_channels == 0) {

        am->out_matrix_channels = 0;

        return;

    }

    /* skip output channels that only get full contribution from the

       corresponding input channel */

    for (o = 0; o < FFMIN(am->in_channels, am->out_channels); o++) {

        int skip = 1;

        int o0;

        for (i = 0; i < am->in_channels; i++) {

            if ((o != i && matrix[o * stride + i] != 0.0) ||

                (o == i && matrix[o * stride + i] != 1.0)) {

                skip = 0;

                break;

            }

        }

        /* check if the corresponding input channel makes a contribution to

           any other output channel */

        i = o;

        for (o0 = 0; o0 < am->out_channels; o0++) {

            if (o0 != i && matrix[o0 * stride + i] != 0.0) {

                skip = 0;

                break;

            }

        }

        if (skip) {

            am->output_skip[o] = 1;

            am->out_matrix_channels--;

        }

    }

    if (am->out_matrix_channels == 0) {

        am->in_matrix_channels = 0;

        return;

    }

}


static SpiceChannelList *qmp_query_spice_channels(void)

{

    SpiceChannelList *cur_item = NULL, *head = NULL;

    ChannelList *item;

    QTAILQ_FOREACH(item, &channel_list, link) {

        SpiceChannelList *chan;

        char host[NI_MAXHOST], port[NI_MAXSERV];

        struct sockaddr *paddr;

        socklen_t plen;

        if (!(item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT)) {

            error_report("invalid channel event");

            return NULL;

        }

        chan = g_malloc0(sizeof(*chan));

        chan->value = g_malloc0(sizeof(*chan->value));

        chan->value->base = g_malloc0(sizeof(*chan->value->base));

        paddr = (struct sockaddr *)&item->info->paddr_ext;

        plen = item->info->plen_ext;

        getnameinfo(paddr, plen,

                    host, sizeof(host), port, sizeof(port),

                    NI_NUMERICHOST | NI_NUMERICSERV);

        chan->value->base->host = g_strdup(host);

        chan->value->base->port = g_strdup(port);

        chan->value->base->family = inet_netfamily(paddr->sa_family);

        chan->value->connection_id = item->info->connection_id;

        chan->value->channel_type = item->info->type;

        chan->value->channel_id = item->info->id;

        chan->value->tls = item->info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS;

       /* XXX: waiting for the qapi to support GSList */

        if (!cur_item) {

            head = cur_item = chan;

        } else {

            cur_item->next = chan;

            cur_item = chan;

        }

    }

    return head;

}


static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size)

{

    int ret;

    switch(sector_size) {

    case 2048:

        block_acct_start(blk_get_stats(s->blk), &s->acct,

                         4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);

        ret = blk_read(s->blk, (int64_t)lba << 2, buf, 4);

        block_acct_done(blk_get_stats(s->blk), &s->acct);

        break;

    case 2352:

        block_acct_start(blk_get_stats(s->blk), &s->acct,

                         4 * BDRV_SECTOR_SIZE, BLOCK_ACCT_READ);

        ret = blk_read(s->blk, (int64_t)lba << 2, buf + 16, 4);

        block_acct_done(blk_get_stats(s->blk), &s->acct);

        if (ret < 0)

            return ret;

        cd_data_to_raw(buf, lba);

        break;

    default:

        ret = -EIO;

        break;

    }

    return ret;

}


static int cow_read(BlockDriverState *bs, int64_t sector_num,

                    uint8_t *buf, int nb_sectors)

{

    BDRVCowState *s = bs->opaque;

    int ret, n;

    while (nb_sectors > 0) {

        if (cow_is_allocated(bs, sector_num, nb_sectors, &n)) {

            ret = bdrv_pread(bs->file,

                        s->cow_sectors_offset + sector_num * 512,

                        buf, n * 512);

            if (ret != n * 512)

                return -1;

        } else {

            if (bs->backing_hd) {

                /* read from the base image */

                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);

                if (ret < 0)

                    return -1;

            } else {

            memset(buf, 0, n * 512);

        }

        }

        nb_sectors -= n;

        sector_num += n;

        buf += n * 512;

    }

    return 0;

}


static int decode_slice_header(H264Context *h, H264Context *h0){

    MpegEncContext * const s = &h->s;

    MpegEncContext * const s0 = &h0->s;

    unsigned int first_mb_in_slice;

    unsigned int pps_id;

    int num_ref_idx_active_override_flag;

    unsigned int slice_type, tmp, i, j;

    int default_ref_list_done = 0;

    int last_pic_structure;

    s->dropable= h->nal_ref_idc == 0;

    if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc){

        s->me.qpel_put= s->dsp.put_2tap_qpel_pixels_tab;

        s->me.qpel_avg= s->dsp.avg_2tap_qpel_pixels_tab;

    }else{

        s->me.qpel_put= s->dsp.put_h264_qpel_pixels_tab;

        s->me.qpel_avg= s->dsp.avg_h264_qpel_pixels_tab;

    }

    first_mb_in_slice= get_ue_golomb(&s->gb);

    if((s->flags2 & CODEC_FLAG2_CHUNKS) && first_mb_in_slice == 0){

        h0->current_slice = 0;

        if (!s0->first_field)

            s->current_picture_ptr= NULL;

    }

    slice_type= get_ue_golomb_31(&s->gb);

    if(slice_type > 9){

        av_log(h->s.avctx, AV_LOG_ERROR, "slice type too large (%d) at %d %d\n", h->slice_type, s->mb_x, s->mb_y);

        return -1;

    }

    if(slice_type > 4){

        slice_type -= 5;

        h->slice_type_fixed=1;

    }else

        h->slice_type_fixed=0;

    slice_type= golomb_to_pict_type[ slice_type ];

    if (slice_type == FF_I_TYPE

        || (h0->current_slice != 0 && slice_type == h0->last_slice_type) ) {

        default_ref_list_done = 1;

    }

    h->slice_type= slice_type;

    h->slice_type_nos= slice_type & 3;

    s->pict_type= h->slice_type; // to make a few old functions happy, it's wrong though

    if (s->pict_type == FF_B_TYPE && s0->last_picture_ptr == NULL) {

        av_log(h->s.avctx, AV_LOG_ERROR,

               "B picture before any references, skipping\n");

        return -1;

    }

    pps_id= get_ue_golomb(&s->gb);

    if(pps_id>=MAX_PPS_COUNT){

        av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n");

        return -1;

    }

    if(!h0->pps_buffers[pps_id]) {

        av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n");

        return -1;

    }

    h->pps= *h0->pps_buffers[pps_id];

    if(!h0->sps_buffers[h->pps.sps_id]) {

        av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n");

        return -1;

    }

    h->sps = *h0->sps_buffers[h->pps.sps_id];

    if(h == h0 && h->dequant_coeff_pps != pps_id){

        h->dequant_coeff_pps = pps_id;

        init_dequant_tables(h);

    }

    s->mb_width= h->sps.mb_width;

    s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag);

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

    h->b8_stride= s->mb_width*2;

    s->width = 16*s->mb_width - 2*FFMIN(h->sps.crop_right, 7);

    if(h->sps.frame_mbs_only_flag)

        s->height= 16*s->mb_height - 2*FFMIN(h->sps.crop_bottom, 7);

    else

        s->height= 16*s->mb_height - 4*FFMIN(h->sps.crop_bottom, 3);

    if (s->context_initialized

        && (   s->width != s->avctx->width || s->height != s->avctx->height)) {

        if(h != h0)

            return -1;   // width / height changed during parallelized decoding

        free_tables(h);

        flush_dpb(s->avctx);

        MPV_common_end(s);

    }

    if (!s->context_initialized) {

        if(h != h0)

            return -1;  // we cant (re-)initialize context during parallel decoding

        if (MPV_common_init(s) < 0)

            return -1;

        s->first_field = 0;

        init_scan_tables(h);

        alloc_tables(h);

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

            H264Context *c;

            c = h->thread_context[i] = av_malloc(sizeof(H264Context));

            memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext));

            memset(&c->s + 1, 0, sizeof(H264Context) - sizeof(MpegEncContext));

            c->sps = h->sps;

            c->pps = h->pps;

            init_scan_tables(c);

            clone_tables(c, h);

        }

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

            if(context_init(h->thread_context[i]) < 0)

                return -1;

        s->avctx->width = s->width;

        s->avctx->height = s->height;

        s->avctx->sample_aspect_ratio= h->sps.sar;

        if(!s->avctx->sample_aspect_ratio.den)

            s->avctx->sample_aspect_ratio.den = 1;

        if(h->sps.timing_info_present_flag){

            s->avctx->time_base= (AVRational){h->sps.num_units_in_tick * 2, h->sps.time_scale};

            if(h->x264_build > 0 && h->x264_build < 44)

                s->avctx->time_base.den *= 2;

            av_reduce(&s->avctx->time_base.num, &s->avctx->time_base.den,

                      s->avctx->time_base.num, s->avctx->time_base.den, 1<<30);

        }

    }

    h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num);

    h->mb_mbaff = 0;

    h->mb_aff_frame = 0;

    last_pic_structure = s0->picture_structure;

    if(h->sps.frame_mbs_only_flag){

        s->picture_structure= PICT_FRAME;

    }else{

        if(get_bits1(&s->gb)) { //field_pic_flag

            s->picture_structure= PICT_TOP_FIELD + get_bits1(&s->gb); //bottom_field_flag

        } else {

            s->picture_structure= PICT_FRAME;

            h->mb_aff_frame = h->sps.mb_aff;

        }

    }

    h->mb_field_decoding_flag= s->picture_structure != PICT_FRAME;

    if(h0->current_slice == 0){

        while(h->frame_num !=  h->prev_frame_num &&

              h->frame_num != (h->prev_frame_num+1)%(1<<h->sps.log2_max_frame_num)){

            av_log(NULL, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num);

            frame_start(h);

            h->prev_frame_num++;

            h->prev_frame_num %= 1<<h->sps.log2_max_frame_num;

            s->current_picture_ptr->frame_num= h->prev_frame_num;

            execute_ref_pic_marking(h, NULL, 0);

        }

        /* See if we have a decoded first field looking for a pair... */

        if (s0->first_field) {

            assert(s0->current_picture_ptr);

            assert(s0->current_picture_ptr->data[0]);

            assert(s0->current_picture_ptr->reference != DELAYED_PIC_REF);

            /* figure out if we have a complementary field pair */

            if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) {

                /*

                 * Previous field is unmatched. Don't display it, but let it

                 * remain for reference if marked as such.

                 */

                s0->current_picture_ptr = NULL;

                s0->first_field = FIELD_PICTURE;

            } else {

                if (h->nal_ref_idc &&

                        s0->current_picture_ptr->reference &&

                        s0->current_picture_ptr->frame_num != h->frame_num) {

                    /*

                     * This and previous field were reference, but had

                     * different frame_nums. Consider this field first in

                     * pair. Throw away previous field except for reference

                     * purposes.

                     */

                    s0->first_field = 1;

                    s0->current_picture_ptr = NULL;

                } else {

                    /* Second field in complementary pair */

                    s0->first_field = 0;

                }

            }

        } else {

            /* Frame or first field in a potentially complementary pair */

            assert(!s0->current_picture_ptr);

            s0->first_field = FIELD_PICTURE;

        }

        if((!FIELD_PICTURE || s0->first_field) && frame_start(h) < 0) {

            s0->first_field = 0;

            return -1;

        }

    }

    if(h != h0)

        clone_slice(h, h0);

    s->current_picture_ptr->frame_num= h->frame_num; //FIXME frame_num cleanup

    assert(s->mb_num == s->mb_width * s->mb_height);

    if(first_mb_in_slice << FIELD_OR_MBAFF_PICTURE >= s->mb_num ||

       first_mb_in_slice                    >= s->mb_num){

        av_log(h->s.avctx, AV_LOG_ERROR, "first_mb_in_slice overflow\n");

        return -1;

    }

    s->resync_mb_x = s->mb_x = first_mb_in_slice % s->mb_width;

    s->resync_mb_y = s->mb_y = (first_mb_in_slice / s->mb_width) << FIELD_OR_MBAFF_PICTURE;

    if (s->picture_structure == PICT_BOTTOM_FIELD)

        s->resync_mb_y = s->mb_y = s->mb_y + 1;

    assert(s->mb_y < s->mb_height);

    if(s->picture_structure==PICT_FRAME){

        h->curr_pic_num=   h->frame_num;

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

    }else{

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

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

    }

    if(h->nal_unit_type == NAL_IDR_SLICE){

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

    }

    if(h->sps.poc_type==0){

        h->poc_lsb= get_bits(&s->gb, h->sps.log2_max_poc_lsb);

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

            h->delta_poc_bottom= get_se_golomb(&s->gb);

        }

    }

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

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

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

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

    }

    init_poc(h);

    if(h->pps.redundant_pic_cnt_present){

        h->redundant_pic_count= get_ue_golomb(&s->gb);

    }

    //set defaults, might be overridden a few lines later

    h->ref_count[0]= h->pps.ref_count[0];

    h->ref_count[1]= h->pps.ref_count[1];

    if(h->slice_type_nos != FF_I_TYPE){

        if(h->slice_type_nos == FF_B_TYPE){

            h->direct_spatial_mv_pred= get_bits1(&s->gb);

        }

        num_ref_idx_active_override_flag= get_bits1(&s->gb);

        if(num_ref_idx_active_override_flag){

            h->ref_count[0]= get_ue_golomb(&s->gb) + 1;

            if(h->slice_type_nos==FF_B_TYPE)

                h->ref_count[1]= get_ue_golomb(&s->gb) + 1;

            if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){

                av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n");

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

                return -1;

            }

        }

        if(h->slice_type_nos == FF_B_TYPE)

            h->list_count= 2;

        else

            h->list_count= 1;

    }else

        h->list_count= 0;

    if(!default_ref_list_done){

        fill_default_ref_list(h);

    }

    if(h->slice_type_nos!=FF_I_TYPE && decode_ref_pic_list_reordering(h) < 0)

        return -1;

    if(h->slice_type_nos!=FF_I_TYPE){

        s->last_picture_ptr= &h->ref_list[0][0];

        ff_copy_picture(&s->last_picture, s->last_picture_ptr);

    }

    if(h->slice_type_nos==FF_B_TYPE){

        s->next_picture_ptr= &h->ref_list[1][0];

        ff_copy_picture(&s->next_picture, s->next_picture_ptr);

    }

    if(   (h->pps.weighted_pred          && h->slice_type_nos == FF_P_TYPE )

       ||  (h->pps.weighted_bipred_idc==1 && h->slice_type_nos== FF_B_TYPE ) )

        pred_weight_table(h);

    else if(h->pps.weighted_bipred_idc==2 && h->slice_type_nos== FF_B_TYPE)

        implicit_weight_table(h);

    else {

        h->use_weight = 0;

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

            h->luma_weight_flag[i]   = 0;

            h->chroma_weight_flag[i] = 0;

        }

    }

    if(h->nal_ref_idc)

        decode_ref_pic_marking(h0, &s->gb);

    if(FRAME_MBAFF)

        fill_mbaff_ref_list(h);

    if(h->slice_type_nos==FF_B_TYPE && !h->direct_spatial_mv_pred)

        direct_dist_scale_factor(h);

    direct_ref_list_init(h);

    if( h->slice_type_nos != FF_I_TYPE && h->pps.cabac ){

        tmp = get_ue_golomb_31(&s->gb);

        if(tmp > 2){

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

            return -1;

        }

        h->cabac_init_idc= tmp;

    }

    h->last_qscale_diff = 0;

    tmp = h->pps.init_qp + get_se_golomb(&s->gb);

    if(tmp>51){

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

        return -1;

    }

    s->qscale= tmp;

    h->chroma_qp[0] = get_chroma_qp(h, 0, s->qscale);

    h->chroma_qp[1] = get_chroma_qp(h, 1, s->qscale);

    //FIXME qscale / qp ... stuff

    if(h->slice_type == FF_SP_TYPE){

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

    }

    if(h->slice_type==FF_SP_TYPE || h->slice_type == FF_SI_TYPE){

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

    }

    h->deblocking_filter = 1;

    h->slice_alpha_c0_offset = 0;

    h->slice_beta_offset = 0;

    if( h->pps.deblocking_filter_parameters_present ) {

        tmp= get_ue_golomb_31(&s->gb);

        if(tmp > 2){

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

            return -1;

        }

        h->deblocking_filter= tmp;

        if(h->deblocking_filter < 2)

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

        if( h->deblocking_filter ) {

            h->slice_alpha_c0_offset = get_se_golomb(&s->gb) << 1;

            h->slice_beta_offset = get_se_golomb(&s->gb) << 1;

        }

    }

    if(   s->avctx->skip_loop_filter >= AVDISCARD_ALL

       ||(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY && h->slice_type_nos != FF_I_TYPE)

       ||(s->avctx->skip_loop_filter >= AVDISCARD_BIDIR  && h->slice_type_nos == FF_B_TYPE)

       ||(s->avctx->skip_loop_filter >= AVDISCARD_NONREF && h->nal_ref_idc == 0))

        h->deblocking_filter= 0;

    if(h->deblocking_filter == 1 && h0->max_contexts > 1) {

        if(s->avctx->flags2 & CODEC_FLAG2_FAST) {

            /* Cheat slightly for speed:

               Do not bother to deblock across slices. */

            h->deblocking_filter = 2;

        } else {

            h0->max_contexts = 1;

            if(!h0->single_decode_warning) {

                av_log(s->avctx, AV_LOG_INFO, "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n");

                h0->single_decode_warning = 1;

            }

            if(h != h0)

                return 1; // deblocking switched inside frame

        }

    }

#if 0 //FMO

    if( h->pps.num_slice_groups > 1  && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5)

        slice_group_change_cycle= get_bits(&s->gb, ?);

#endif

    h0->last_slice_type = slice_type;

    h->slice_num = ++h0->current_slice;

    if(h->slice_num >= MAX_SLICES){

        av_log(s->avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n");

    }

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

        int *ref2frm= h->ref2frm[h->slice_num&(MAX_SLICES-1)][j];

        ref2frm[0]=

        ref2frm[1]= -1;

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

            ref2frm[i+2]= 4*h->ref_list[j][i].frame_num

                          +(h->ref_list[j][i].reference&3);

        ref2frm[18+0]=

        ref2frm[18+1]= -1;

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

            ref2frm[i+4]= 4*h->ref_list[j][i].frame_num

                          +(h->ref_list[j][i].reference&3);

    }

    h->emu_edge_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16;

    h->emu_edge_height= (FRAME_MBAFF || FIELD_PICTURE) ? 0 : h->emu_edge_width;

    s->avctx->refs= h->sps.ref_frame_count;

    if(s->avctx->debug&FF_DEBUG_PICT_INFO){

        av_log(h->s.avctx, AV_LOG_DEBUG, "slice:%d %s mb:%d %c%s%s pps:%u frame:%d poc:%d/%d ref:%d/%d qp:%d loop:%d:%d:%d weight:%d%s %s\n",

               h->slice_num,

               (s->picture_structure==PICT_FRAME ? "F" : s->picture_structure==PICT_TOP_FIELD ? "T" : "B"),

               first_mb_in_slice,

               av_get_pict_type_char(h->slice_type), h->slice_type_fixed ? " fix" : "", h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",

               pps_id, h->frame_num,

               s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1],

               h->ref_count[0], h->ref_count[1],

               s->qscale,

               h->deblocking_filter, h->slice_alpha_c0_offset/2, h->slice_beta_offset/2,

               h->use_weight,

               h->use_weight==1 && h->use_weight_chroma ? "c" : "",

               h->slice_type == FF_B_TYPE ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : ""

               );

    }

    return 0;

}


static HotplugHandler *spapr_get_hotpug_handler(MachineState *machine,

                                             DeviceState *dev)

{

    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||

        object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) {

        return HOTPLUG_HANDLER(machine);

    }

    return NULL;

}


static void yuvj444p_to_rgb24(AVPicture *dst, AVPicture *src,

                              int width, int height)

{

    uint8_t *y1_ptr, *cb_ptr, *cr_ptr, *d, *d1;

    int w, y, cb, cr, r_add, g_add, b_add;

    uint8_t *cm = cropTbl + MAX_NEG_CROP;

    unsigned int r, g, b;

    d = dst->data[0];

    y1_ptr = src->data[0];

    cb_ptr = src->data[1];

    cr_ptr = src->data[2];

    for(;height > 0; height --) {

        d1 = d;

        for(w = width; w > 0; w--) {

            YUV_TO_RGB1(cb_ptr[0], cr_ptr[0]);

            YUV_TO_RGB2(r, g, b, y1_ptr[0]);

            RGB_OUT(d1, r, g, b);

            d1 += BPP;

            y1_ptr++;

            cb_ptr++;

            cr_ptr++;

        }

        d += dst->linesize[0];

        y1_ptr += src->linesize[0] - width;

        cb_ptr += src->linesize[1] - width;

        cr_ptr += src->linesize[2] - width;

    }

}


void kvm_init_cpu_signals(CPUState *cpu)

{

    int r;

    sigset_t set;

    struct sigaction sigact;

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

    sigact.sa_handler = dummy_signal;

    sigaction(SIG_IPI, &sigact, NULL);

    pthread_sigmask(SIG_BLOCK, NULL, &set);

#if defined KVM_HAVE_MCE_INJECTION

    sigdelset(&set, SIGBUS);

    pthread_sigmask(SIG_SETMASK, &set, NULL);

#endif

    sigdelset(&set, SIG_IPI);

    r = kvm_set_signal_mask(cpu, &set);

    if (r) {

        fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));

        exit(1);

    }

}


static void vfio_disable_msix(VFIODevice *vdev)
{
    msix_unset_vector_notifiers(&vdev->pdev);
    if (vdev->nr_vectors) {
        vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
    vfio_disable_msi_common(vdev);
    DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
            vdev->host.bus, vdev->host.slot, vdev->host.function);


static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int len)

{

    int payload_len;

    while (len >= 2) {

        switch (buf[1]) {

        case RTCP_SR:

            if (len < 16) {

                av_log(NULL, AV_LOG_ERROR, "Invalid length for RTCP SR packet\n");

                return AVERROR_INVALIDDATA;

            }

            payload_len = (AV_RB16(buf + 2) + 1) * 4;

            s->last_rtcp_ntp_time = AV_RB64(buf + 8);

            s->last_rtcp_timestamp = AV_RB32(buf + 16);

            if (s->first_rtcp_ntp_time == AV_NOPTS_VALUE) {

                s->first_rtcp_ntp_time = s->last_rtcp_ntp_time;

                if (!s->base_timestamp)

                    s->base_timestamp = s->last_rtcp_timestamp;

                s->rtcp_ts_offset = s->last_rtcp_timestamp - s->base_timestamp;

            }

            buf += payload_len;

            len -= payload_len;

            break;

        case RTCP_BYE:

            return -RTCP_BYE;

        default:

            return -1;

        }

    }

    return -1;

}


void virtqueue_map_sg(struct iovec *sg, hwaddr *addr,
    size_t num_sg, int is_write)
{
    unsigned int i;
    hwaddr len;
    for (i = 0; i < num_sg; i++) {
        len = sg[i].iov_len;
        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
        if (sg[i].iov_base == NULL || len != sg[i].iov_len) {
            error_report("virtio: trying to map MMIO memory");


static void ehci_async_complete_packet(USBPort *port, USBPacket *packet)

{

    EHCIQueue *q;

    EHCIState *s = port->opaque;

    uint32_t portsc = s->portsc[port->index];

    if (portsc & PORTSC_POWNER) {

        USBPort *companion = s->companion_ports[port->index];

        companion->ops->complete(companion, packet);

        return;

    }

    q = container_of(packet, EHCIQueue, packet);

    trace_usb_ehci_queue_action(q, "wakeup");

    assert(q->async == EHCI_ASYNC_INFLIGHT);

    q->async = EHCI_ASYNC_FINISHED;

    q->usb_status = packet->len;

}


static int mov_read_header(AVFormatContext *s)

{

    MOVContext *mov = s->priv_data;

    AVIOContext *pb = s->pb;

    int j, err;

    MOVAtom atom = { AV_RL32("root") };

    int i;

    if (mov->decryption_key_len != 0 && mov->decryption_key_len != AES_CTR_KEY_SIZE) {

        av_log(s, AV_LOG_ERROR, "Invalid decryption key len %d expected %d\n",

            mov->decryption_key_len, AES_CTR_KEY_SIZE);

        return AVERROR(EINVAL);

    }

    mov->fc = s;

    mov->trak_index = -1;

    /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */

    if (pb->seekable)

        atom.size = avio_size(pb);

    else

        atom.size = INT64_MAX;

    /* check MOV header */

    do {

    if (mov->moov_retry)

        avio_seek(pb, 0, SEEK_SET);

    if ((err = mov_read_default(mov, pb, atom)) < 0) {

        av_log(s, AV_LOG_ERROR, "error reading header\n");

        mov_read_close(s);

        return err;

    }

    } while (pb->seekable && !mov->found_moov && !mov->moov_retry++);

    if (!mov->found_moov) {

        av_log(s, AV_LOG_ERROR, "moov atom not found\n");

        mov_read_close(s);

        return AVERROR_INVALIDDATA;

    }

    av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));

    if (pb->seekable) {

        if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters)

            mov_read_chapters(s);

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

            if (s->streams[i]->codecpar->codec_tag == AV_RL32("tmcd")) {

                mov_read_timecode_track(s, s->streams[i]);

            } else if (s->streams[i]->codecpar->codec_tag == AV_RL32("rtmd")) {

                mov_read_rtmd_track(s, s->streams[i]);

            }

    }

    /* copy timecode metadata from tmcd tracks to the related video streams */

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

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

        MOVStreamContext *sc = st->priv_data;

        if (sc->timecode_track > 0) {

            AVDictionaryEntry *tcr;

            int tmcd_st_id = -1;

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

                if (s->streams[j]->id == sc->timecode_track)

                    tmcd_st_id = j;

            if (tmcd_st_id < 0 || tmcd_st_id == i)

                continue;

            tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);

            if (tcr)

                av_dict_set(&st->metadata, "timecode", tcr->value, 0);

        }

    }

    export_orphan_timecode(s);

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

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

        MOVStreamContext *sc = st->priv_data;

        fix_timescale(mov, sc);

        if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {

            st->skip_samples = sc->start_pad;

        }

        if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)

            av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,

                      sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);

        if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {

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

                st->codecpar->width  = sc->width;

                st->codecpar->height = sc->height;

            }

            if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {

                if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)

                    return err;

            }

        }

        if (mov->handbrake_version &&

            mov->handbrake_version <= 1000000*0 + 1000*10 + 2 &&  // 0.10.2

            st->codecpar->codec_id == AV_CODEC_ID_MP3

        ) {

            av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");

            st->need_parsing = AVSTREAM_PARSE_FULL;

        }

    }

    if (mov->trex_data) {

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

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

            MOVStreamContext *sc = st->priv_data;

            if (st->duration > 0)

                st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;

        }

    }

    if (mov->use_mfra_for > 0) {

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

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

            MOVStreamContext *sc = st->priv_data;

            if (sc->duration_for_fps > 0) {

                st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /

                    sc->duration_for_fps;

            }

        }

    }

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

        if (mov->bitrates[i]) {

            s->streams[i]->codecpar->bit_rate = mov->bitrates[i];

        }

    }

    ff_rfps_calculate(s);

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

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

        MOVStreamContext *sc = st->priv_data;

        switch (st->codecpar->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            err = ff_replaygain_export(st, s->metadata);

            if (err < 0) {

                mov_read_close(s);

                return err;

            }

            break;

        case AVMEDIA_TYPE_VIDEO:

            if (sc->display_matrix) {

                err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,

                                              sizeof(int32_t) * 9);

                if (err < 0)

                    return err;

                sc->display_matrix = NULL;

            }

            if (sc->stereo3d) {

                err = av_stream_add_side_data(st, AV_PKT_DATA_STEREO3D,

                                              (uint8_t *)sc->stereo3d,

                                              sizeof(*sc->stereo3d));

                if (err < 0)

                    return err;

                sc->stereo3d = NULL;

            }

            if (sc->spherical) {

                err = av_stream_add_side_data(st, AV_PKT_DATA_SPHERICAL,

                                              (uint8_t *)sc->spherical,

                                              sc->spherical_size);

                if (err < 0)

                    return err;

                sc->spherical = NULL;

            }

            break;

        }

    }

    ff_configure_buffers_for_index(s, AV_TIME_BASE);

    return 0;

}


static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)

{

    SliceThreadContext *c = avctx->internal->thread_ctx;

    if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)

        return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);

    if (job_count <= 0)

        return 0;

    pthread_mutex_lock(&c->current_job_lock);

    c->current_job = avctx->thread_count;

    c->job_count = job_count;

    c->job_size = job_size;

    c->args = arg;

    c->func = func;

    c->rets = ret;

    c->current_execute++;

    pthread_cond_broadcast(&c->current_job_cond);

    thread_park_workers(c, avctx->thread_count);

    return 0;

}


static void gain_compensate(COOKContext *q, cook_gains *gains_ptr,

                            float* previous_buffer)

{

    const float fc = q->pow2tab[gains_ptr->previous[0] + 63];

    float *buffer = q->mono_mdct_output;

    int i;

    /* Overlap with the previous block. */

    for(i=0 ; i<q->samples_per_channel ; i++) {

        buffer[i] *= fc;

        buffer[i] += previous_buffer[i];

    }

    /* Apply gain profile */

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

        if (gains_ptr->now[i] || gains_ptr->now[i + 1])

            interpolate(q, &buffer[q->gain_size_factor * i],

                        gains_ptr->now[i], gains_ptr->now[i + 1]);

    }

    /* Save away the current to be previous block. */

    memcpy(previous_buffer, buffer+q->samples_per_channel,

           sizeof(float)*q->samples_per_channel);

}


int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index)

{

    MOVMuxContext *mov  = s->priv_data;

    MOVTrack *track     = &mov->tracks[index];

    MOVTrack *src_track = &mov->tracks[src_index];

    AVStream *src_st    = s->streams[src_index];

    int ret = AVERROR(ENOMEM);

    AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);

    track->tag = MKTAG('r','t','p',' ');

    track->src_track = src_index;

    if (!rtp_format) {

        ret = AVERROR(ENOENT);

        goto fail;

    }

    track->enc = avcodec_alloc_context();

    if (!track->enc)

        goto fail;

    track->enc->codec_type = AVMEDIA_TYPE_DATA;

    track->enc->codec_tag  = track->tag;

    track->rtp_ctx = avformat_alloc_context();

    if (!track->rtp_ctx)

        goto fail;

    track->rtp_ctx->oformat = rtp_format;

    if (!av_new_stream(track->rtp_ctx, 0))

        goto fail;

    /* Copy stream parameters */

    track->rtp_ctx->streams[0]->sample_aspect_ratio =

                        src_st->sample_aspect_ratio;

    /* Remove the allocated codec context, link to the original one

     * instead, to give the rtp muxer access to codec parameters. */

    av_free(track->rtp_ctx->streams[0]->codec);

    track->rtp_ctx->streams[0]->codec = src_st->codec;

    if ((ret = url_open_dyn_packet_buf(&track->rtp_ctx->pb,

                                       RTP_MAX_PACKET_SIZE)) < 0)

        goto fail;

    ret = av_write_header(track->rtp_ctx);

    if (ret)

        goto fail;

    /* Copy the RTP AVStream timebase back to the hint AVStream */

    track->timescale = track->rtp_ctx->streams[0]->time_base.den;

    /* Mark the hinted track that packets written to it should be

     * sent to this track for hinting. */

    src_track->hint_track = index;

    return 0;

fail:

    av_log(s, AV_LOG_WARNING,

           "Unable to initialize hinting of stream %d\n", src_index);

    if (track->rtp_ctx && track->rtp_ctx->pb) {

        uint8_t *buf;

        url_close_dyn_buf(track->rtp_ctx->pb, &buf);

        av_free(buf);

    }

    if (track->rtp_ctx && track->rtp_ctx->streams[0]) {

        av_metadata_free(&track->rtp_ctx->streams[0]->metadata);

        av_free(track->rtp_ctx->streams[0]);

    }

    if (track->rtp_ctx) {

        av_metadata_free(&track->rtp_ctx->metadata);

        av_free(track->rtp_ctx->priv_data);

        av_freep(&track->rtp_ctx);

    }

    av_freep(&track->enc);

    /* Set a default timescale, to avoid crashes in dump_format */

    track->timescale = 90000;

    return ret;

}


static inline int l3_unscale(int value, int exponent)

{

    unsigned int m;

    int e;

    e  = table_4_3_exp  [4 * value + (exponent & 3)];

    m  = table_4_3_value[4 * value + (exponent & 3)];

    e -= exponent >> 2;

#ifdef DEBUG

    if(e < 1)

        av_log(NULL, AV_LOG_WARNING, "l3_unscale: e is %d\n", e);

#endif

    if (e > (SUINT)31)

        return 0;

    m = (m + (1 << (e - 1))) >> e;

    return m;

}


static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
{
    BDRVQcow2State *s = bs->opaque;
    uint64_t old_l2_offset;
    uint64_t *l2_table = NULL;
    int64_t l2_offset;
    int ret;
    old_l2_offset = s->l1_table[l1_index];
    trace_qcow2_l2_allocate(bs, l1_index);
    /* allocate a new l2 entry */
    l2_offset = qcow2_alloc_clusters(bs, s->l2_size * sizeof(uint64_t));
    if (l2_offset < 0) {
        ret = l2_offset;
    ret = qcow2_cache_flush(bs, s->refcount_block_cache);
    if (ret < 0) {
    /* allocate a new entry in the l2 cache */
    trace_qcow2_l2_allocate_get_empty(bs, l1_index);
    ret = qcow2_cache_get_empty(bs, s->l2_table_cache, l2_offset, (void**) table);
    if (ret < 0) {
    l2_table = *table;
    if ((old_l2_offset & L1E_OFFSET_MASK) == 0) {
        /* if there was no old l2 table, clear the new table */
        memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
    } else {
        uint64_t* old_table;
        /* if there was an old l2 table, read it from the disk */
        BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_COW_READ);
        ret = qcow2_cache_get(bs, s->l2_table_cache,
            old_l2_offset & L1E_OFFSET_MASK,
            (void**) &old_table);
        if (ret < 0) {
        memcpy(l2_table, old_table, s->cluster_size);
        qcow2_cache_put(bs, s->l2_table_cache, (void **) &old_table);
    /* write the l2 table to the file */
    BLKDBG_EVENT(bs->file, BLKDBG_L2_ALLOC_WRITE);
    trace_qcow2_l2_allocate_write_l2(bs, l1_index);
    qcow2_cache_entry_mark_dirty(bs, s->l2_table_cache, l2_table);
    ret = qcow2_cache_flush(bs, s->l2_table_cache);
    if (ret < 0) {
    /* update the L1 entry */
    trace_qcow2_l2_allocate_write_l1(bs, l1_index);
    s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
    ret = qcow2_write_l1_entry(bs, l1_index);
    if (ret < 0) {
    *table = l2_table;
    trace_qcow2_l2_allocate_done(bs, l1_index, 0);
    return 0;
fail:
    trace_qcow2_l2_allocate_done(bs, l1_index, ret);
    if (l2_table != NULL) {
        qcow2_cache_put(bs, s->l2_table_cache, (void**) table);
    s->l1_table[l1_index] = old_l2_offset;
    if (l2_offset > 0) {
        qcow2_free_clusters(bs, l2_offset, s->l2_size * sizeof(uint64_t),
                            QCOW2_DISCARD_ALWAYS);
    return ret;


void get_tmp_filename(char *filename, int size)

{

    char temp_dir[MAX_PATH];

    GetTempPath(MAX_PATH, temp_dir);

    GetTempFileName(temp_dir, "qem", 0, filename);

}


static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,

                               AVFrame *p)

{

    size_t x, y;

    uint8_t *buffer = av_malloc(s->image_linesize * s->height);

    if (!buffer)

        return AVERROR(ENOMEM);

    if (s->blend_op == APNG_BLEND_OP_OVER &&

        avctx->pix_fmt != AV_PIX_FMT_RGBA &&

        avctx->pix_fmt != AV_PIX_FMT_GRAY8A &&

        avctx->pix_fmt != AV_PIX_FMT_PAL8) {

        avpriv_request_sample(avctx, "Blending with pixel format %s",

                              av_get_pix_fmt_name(avctx->pix_fmt));

        return AVERROR_PATCHWELCOME;

    }

    // Do the disposal operation specified by the last frame on the frame

    if (s->last_dispose_op != APNG_DISPOSE_OP_PREVIOUS) {

        ff_thread_await_progress(&s->last_picture, INT_MAX, 0);

        memcpy(buffer, s->last_picture.f->data[0], s->image_linesize * s->height);

        if (s->last_dispose_op == APNG_DISPOSE_OP_BACKGROUND)

            for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; ++y)

                memset(buffer + s->image_linesize * y + s->bpp * s->last_x_offset, 0, s->bpp * s->last_w);

        memcpy(s->previous_picture.f->data[0], buffer, s->image_linesize * s->height);

        ff_thread_report_progress(&s->previous_picture, INT_MAX, 0);

    } else {

        ff_thread_await_progress(&s->previous_picture, INT_MAX, 0);

        memcpy(buffer, s->previous_picture.f->data[0], s->image_linesize * s->height);

    }

    // Perform blending

    if (s->blend_op == APNG_BLEND_OP_SOURCE) {

        for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) {

            size_t row_start = s->image_linesize * y + s->bpp * s->x_offset;

            memcpy(buffer + row_start, p->data[0] + row_start, s->bpp * s->cur_w);

        }

    } else { // APNG_BLEND_OP_OVER

        for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) {

            uint8_t *foreground = p->data[0] + s->image_linesize * y + s->bpp * s->x_offset;

            uint8_t *background = buffer + s->image_linesize * y + s->bpp * s->x_offset;

            for (x = s->x_offset; x < s->x_offset + s->cur_w; ++x, foreground += s->bpp, background += s->bpp) {

                size_t b;

                uint8_t foreground_alpha, background_alpha, output_alpha;

                uint8_t output[4];

                // Since we might be blending alpha onto alpha, we use the following equations:

                // output_alpha = foreground_alpha + (1 - foreground_alpha) * background_alpha

                // output = (foreground_alpha * foreground + (1 - foreground_alpha) * background_alpha * background) / output_alpha

                switch (avctx->pix_fmt) {

                case AV_PIX_FMT_RGBA:

                    foreground_alpha = foreground[3];

                    background_alpha = background[3];

                    break;

                case AV_PIX_FMT_GRAY8A:

                    foreground_alpha = foreground[1];

                    background_alpha = background[1];

                    break;

                case AV_PIX_FMT_PAL8:

                    foreground_alpha = s->palette[foreground[0]] >> 24;

                    background_alpha = s->palette[background[0]] >> 24;

                    break;

                }

                if (foreground_alpha == 0)

                    continue;

                if (foreground_alpha == 255) {

                    memcpy(background, foreground, s->bpp);

                    continue;

                }

                if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {

                    // TODO: Alpha blending with PAL8 will likely need the entire image converted over to RGBA first

                    avpriv_request_sample(avctx, "Alpha blending palette samples");

                    background[0] = foreground[0];

                    continue;

                }

                output_alpha = foreground_alpha + FAST_DIV255((255 - foreground_alpha) * background_alpha);

                for (b = 0; b < s->bpp - 1; ++b) {

                    if (output_alpha == 0) {

                        output[b] = 0;

                    } else if (background_alpha == 255) {

                        output[b] = FAST_DIV255(foreground_alpha * foreground[b] + (255 - foreground_alpha) * background[b]);

                    } else {

                        output[b] = (255 * foreground_alpha * foreground[b] + (255 - foreground_alpha) * background_alpha * background[b]) / (255 * output_alpha);

                    }

                }

                output[b] = output_alpha;

                memcpy(background, output, s->bpp);

            }

        }

    }

    // Copy blended buffer into the frame and free

    memcpy(p->data[0], buffer, s->image_linesize * s->height);

    av_free(buffer);

    return 0;

}


void microblaze_load_kernel(MicroBlazeCPU *cpu, target_phys_addr_t ddr_base,

                            uint32_t ramsize, const char *dtb_filename,

                            void (*machine_cpu_reset)(MicroBlazeCPU *))

{

    QemuOpts *machine_opts;

    const char *kernel_filename = NULL;

    const char *kernel_cmdline = NULL;

    machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);

    if (machine_opts) {

        const char *dtb_arg;

        kernel_filename = qemu_opt_get(machine_opts, "kernel");

        kernel_cmdline = qemu_opt_get(machine_opts, "append");

        dtb_arg = qemu_opt_get(machine_opts, "dtb");

        if (dtb_arg) { /* Preference a -dtb argument */

            dtb_filename = dtb_arg;

        } else { /* default to pcbios dtb as passed by machine_init */

            dtb_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename);

        }

    }

    boot_info.machine_cpu_reset = machine_cpu_reset;

    qemu_register_reset(main_cpu_reset, cpu);

    if (kernel_filename) {

        int kernel_size;

        uint64_t entry, low, high;

        uint32_t base32;

        int big_endian = 0;

#ifdef TARGET_WORDS_BIGENDIAN

        big_endian = 1;

#endif

        /* Boots a kernel elf binary.  */

        kernel_size = load_elf(kernel_filename, NULL, NULL,

                               &entry, &low, &high,

                               big_endian, ELF_MACHINE, 0);

        base32 = entry;

        if (base32 == 0xc0000000) {

            kernel_size = load_elf(kernel_filename, translate_kernel_address,

                                   NULL, &entry, NULL, NULL,

                                   big_endian, ELF_MACHINE, 0);

        }

        /* Always boot into physical ram.  */

        boot_info.bootstrap_pc = ddr_base + (entry & 0x0fffffff);

        /* If it wasn't an ELF image, try an u-boot image.  */

        if (kernel_size < 0) {

            target_phys_addr_t uentry, loadaddr;

            kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0);

            boot_info.bootstrap_pc = uentry;

            high = (loadaddr + kernel_size + 3) & ~3;

        }

        /* Not an ELF image nor an u-boot image, try a RAW image.  */

        if (kernel_size < 0) {

            kernel_size = load_image_targphys(kernel_filename, ddr_base,

                                              ram_size);

            boot_info.bootstrap_pc = ddr_base;

            high = (ddr_base + kernel_size + 3) & ~3;

        }

        boot_info.cmdline = high + 4096;

        if (kernel_cmdline && strlen(kernel_cmdline)) {

            pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline);

        }

        /* Provide a device-tree.  */

        boot_info.fdt = boot_info.cmdline + 4096;

        microblaze_load_dtb(boot_info.fdt, ram_size, kernel_cmdline,

                                                     dtb_filename);

    }

}


void qemu_clock_enable(QEMUClockType type, bool enabled)

{

    QEMUClock *clock = qemu_clock_ptr(type);

    QEMUTimerList *tl;

    bool old = clock->enabled;

    clock->enabled = enabled;

    if (enabled && !old) {

        qemu_clock_notify(type);

    } else if (!enabled && old) {

        QLIST_FOREACH(tl, &clock->timerlists, list) {

            qemu_event_wait(&tl->timers_done_ev);

        }

    }

}


static uint64_t grlib_gptimer_read(void *opaque, target_phys_addr_t addr,

                                   unsigned size)

{

    GPTimerUnit        *unit  = opaque;

    target_phys_addr_t  timer_addr;

    int                 id;

    uint32_t            value = 0;

    addr &= 0xff;

    /* Unit registers */

    switch (addr) {

    case SCALER_OFFSET:

        trace_grlib_gptimer_readl(-1, addr, unit->scaler);

        return unit->scaler;

    case SCALER_RELOAD_OFFSET:

        trace_grlib_gptimer_readl(-1, addr, unit->reload);

        return unit->reload;

    case CONFIG_OFFSET:

        trace_grlib_gptimer_readl(-1, addr, unit->config);

        return unit->config;

    default:

        break;

    }

    timer_addr = (addr % TIMER_BASE);

    id         = (addr - TIMER_BASE) / TIMER_BASE;

    if (id >= 0 && id < unit->nr_timers) {

        /* GPTimer registers */

        switch (timer_addr) {

        case COUNTER_OFFSET:

            value = ptimer_get_count(unit->timers[id].ptimer);

            trace_grlib_gptimer_readl(id, addr, value);

            return value;

        case COUNTER_RELOAD_OFFSET:

            value = unit->timers[id].reload;

            trace_grlib_gptimer_readl(id, addr, value);

            return value;

        case CONFIG_OFFSET:

            trace_grlib_gptimer_readl(id, addr, unit->timers[id].config);

            return unit->timers[id].config;

        default:

            break;

        }

    }

    trace_grlib_gptimer_readl(-1, addr, 0);

    return 0;

}


static int get_cpsr(QEMUFile *f, void *opaque, size_t size,

                    VMStateField *field)

{

    ARMCPU *cpu = opaque;

    CPUARMState *env = &cpu->env;

    uint32_t val = qemu_get_be32(f);

    if (arm_feature(env, ARM_FEATURE_M)) {

        if (val & XPSR_EXCP) {

            /* This is a CPSR format value from an older QEMU. (We can tell

             * because values transferred in XPSR format always have zero

             * for the EXCP field, and CPSR format will always have bit 4

             * set in CPSR_M.) Rearrange it into XPSR format. The significant

             * differences are that the T bit is not in the same place, the

             * primask/faultmask info may be in the CPSR I and F bits, and

             * we do not want the mode bits.

             */

            uint32_t newval = val;

            newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE);

            if (val & CPSR_T) {

                newval |= XPSR_T;

            }

            /* If the I or F bits are set then this is a migration from

             * an old QEMU which still stored the M profile FAULTMASK

             * and PRIMASK in env->daif. For a new QEMU, the data is

             * transferred using the vmstate_m_faultmask_primask subsection.

             */

            if (val & CPSR_F) {

                env->v7m.faultmask = 1;

            }

            if (val & CPSR_I) {

                env->v7m.primask = 1;

            }

            val = newval;

        }

        /* Ignore the low bits, they are handled by vmstate_m. */

        xpsr_write(env, val, ~XPSR_EXCP);

        return 0;

    }

    env->aarch64 = ((val & PSTATE_nRW) == 0);

    if (is_a64(env)) {

        pstate_write(env, val);

        return 0;

    }

    cpsr_write(env, val, 0xffffffff, CPSRWriteRaw);

    return 0;

}


static void pcnet_receive(void *opaque, const uint8_t *buf, int size)

{

    PCNetState *s = opaque;

    int is_padr = 0, is_bcast = 0, is_ladr = 0;

    uint8_t buf1[60];

    if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size)

        return;

#ifdef PCNET_DEBUG

    printf("pcnet_receive size=%d\n", size);

#endif

    /* if too small buffer, then expand it */

    if (size < MIN_BUF_SIZE) {

        memcpy(buf1, buf, size);

        memset(buf1 + size, 0, MIN_BUF_SIZE - size);

        buf = buf1;

        size = MIN_BUF_SIZE;

    }

    if (CSR_PROM(s)

        || (is_padr=padr_match(s, buf, size))

        || (is_bcast=padr_bcast(s, buf, size))

        || (is_ladr=ladr_match(s, buf, size))) {

        pcnet_rdte_poll(s);

        if (!(CSR_CRST(s) & 0x8000) && s->rdra) {

            struct pcnet_RMD rmd;

            int rcvrc = CSR_RCVRC(s)-1,i;

            target_phys_addr_t nrda;

            for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) {

                if (rcvrc <= 1)

                    rcvrc = CSR_RCVRL(s);

                nrda = s->rdra +

                    (CSR_RCVRL(s) - rcvrc) *

                    (BCR_SWSTYLE(s) ? 16 : 8 );

                RMDLOAD(&rmd, PHYSADDR(s,nrda));

                if (GET_FIELD(rmd.status, RMDS, OWN)) {

#ifdef PCNET_DEBUG_RMD

                    printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n",

                                rcvrc, CSR_RCVRC(s));

#endif

                    CSR_RCVRC(s) = rcvrc;

                    pcnet_rdte_poll(s);

                    break;

                }

            }

        }

        if (!(CSR_CRST(s) & 0x8000)) {

#ifdef PCNET_DEBUG_RMD

            printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s));

#endif

            s->csr[0] |= 0x1000; /* Set MISS flag */

            CSR_MISSC(s)++;

        } else {

            uint8_t *src = &s->buffer[8];

            target_phys_addr_t crda = CSR_CRDA(s);

            struct pcnet_RMD rmd;

            int pktcount = 0;

            memcpy(src, buf, size);

#if 1

            /* no need to compute the CRC */

            src[size] = 0;

            src[size + 1] = 0;

            src[size + 2] = 0;

            src[size + 3] = 0;

            size += 4;

#else

            /* XXX: avoid CRC generation */

            if (!CSR_ASTRP_RCV(s)) {

                uint32_t fcs = ~0;

                uint8_t *p = src;

                while (size < 46) {

                    src[size++] = 0;

                }

                while (p != &src[size]) {

                    CRC(fcs, *p++);

                }

                ((uint32_t *)&src[size])[0] = htonl(fcs);

                size += 4; /* FCS at end of packet */

            } else size += 4;

#endif

#ifdef PCNET_DEBUG_MATCH

            PRINT_PKTHDR(buf);

#endif

            RMDLOAD(&rmd, PHYSADDR(s,crda));

            /*if (!CSR_LAPPEN(s))*/

                SET_FIELD(&rmd.status, RMDS, STP, 1);

#define PCNET_RECV_STORE() do {                                 \

    int count = MIN(4096 - GET_FIELD(rmd.buf_length, RMDL, BCNT),size); \

    target_phys_addr_t rbadr = PHYSADDR(s, rmd.rbadr);          \

    s->phys_mem_write(s->dma_opaque, rbadr, src, count, CSR_BSWP(s)); \

    src += count; size -= count;                                \

    SET_FIELD(&rmd.msg_length, RMDM, MCNT, count);              \

    SET_FIELD(&rmd.status, RMDS, OWN, 0);                       \

    RMDSTORE(&rmd, PHYSADDR(s,crda));                           \

    pktcount++;                                                 \

} while (0)

            PCNET_RECV_STORE();

            if ((size > 0) && CSR_NRDA(s)) {

                target_phys_addr_t nrda = CSR_NRDA(s);

                RMDLOAD(&rmd, PHYSADDR(s,nrda));

                if (GET_FIELD(rmd.status, RMDS, OWN)) {

                    crda = nrda;

                    PCNET_RECV_STORE();

                    if ((size > 0) && (nrda=CSR_NNRD(s))) {

                        RMDLOAD(&rmd, PHYSADDR(s,nrda));

                        if (GET_FIELD(rmd.status, RMDS, OWN)) {

                            crda = nrda;

                            PCNET_RECV_STORE();

                        }

                    }

                }

            }

#undef PCNET_RECV_STORE

            RMDLOAD(&rmd, PHYSADDR(s,crda));

            if (size == 0) {

                SET_FIELD(&rmd.status, RMDS, ENP, 1);

                SET_FIELD(&rmd.status, RMDS, PAM, !CSR_PROM(s) && is_padr);

                SET_FIELD(&rmd.status, RMDS, LFAM, !CSR_PROM(s) && is_ladr);

                SET_FIELD(&rmd.status, RMDS, BAM, !CSR_PROM(s) && is_bcast);

            } else {

                SET_FIELD(&rmd.status, RMDS, OFLO, 1);

                SET_FIELD(&rmd.status, RMDS, BUFF, 1);

                SET_FIELD(&rmd.status, RMDS, ERR, 1);

            }

            RMDSTORE(&rmd, PHYSADDR(s,crda));

            s->csr[0] |= 0x0400;

#ifdef PCNET_DEBUG

            printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n",

                CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount);

#endif

#ifdef PCNET_DEBUG_RMD

            PRINT_RMD(&rmd);

#endif

            while (pktcount--) {

                if (CSR_RCVRC(s) <= 1)

                    CSR_RCVRC(s) = CSR_RCVRL(s);

                else

                    CSR_RCVRC(s)--;

            }

            pcnet_rdte_poll(s);

        }

    }

    pcnet_poll(s);

    pcnet_update_irq(s);

}


static uint32_t m5206_mbar_readl(void *opaque, target_phys_addr_t offset)

{

    m5206_mbar_state *s = (m5206_mbar_state *)opaque;

    int width;

    offset &= 0x3ff;

    if (offset >= 0x200) {

        hw_error("Bad MBAR read offset 0x%x", (int)offset);

    }

    width = m5206_mbar_width[offset >> 2];

    if (width < 4) {

        uint32_t val;

        val = m5206_mbar_readw(opaque, offset) << 16;

        val |= m5206_mbar_readw(opaque, offset + 2);

        return val;

    }

    return m5206_mbar_read(s, offset, 4);

}


uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,

                                               uint64_t offset,

                                               int compressed_size)

{

    BDRVQcowState *s = bs->opaque;

    int l2_index, ret;

    uint64_t *l2_table;

    int64_t cluster_offset;

    int nb_csectors;

    ret = get_cluster_table(bs, offset, &l2_table, &l2_index);

    if (ret < 0) {

        return 0;

    }

    /* Compression can't overwrite anything. Fail if the cluster was already

     * allocated. */

    cluster_offset = be64_to_cpu(l2_table[l2_index]);

    if (cluster_offset & L2E_OFFSET_MASK) {

        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

        return 0;

    }

    cluster_offset = qcow2_alloc_bytes(bs, compressed_size);

    if (cluster_offset < 0) {

        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

        return 0;

    }

    nb_csectors = ((cluster_offset + compressed_size - 1) >> 9) -

                  (cluster_offset >> 9);

    cluster_offset |= QCOW_OFLAG_COMPRESSED |

                      ((uint64_t)nb_csectors << s->csize_shift);

    /* update L2 table */

    /* compressed clusters never have the copied flag */

    BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);

    qcow2_cache_entry_mark_dirty(bs, s->l2_table_cache, l2_table);

    l2_table[l2_index] = cpu_to_be64(cluster_offset);

    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

    if (ret < 0) {

        return 0;

    }

    return cluster_offset;

}


void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,

                               Error **errp)

{

    int index;

    sPAPRDRConnector *drc;

    sPAPRDRConnectorClass *drck;

    Error *local_err = NULL;

    CPUCore *cc = CPU_CORE(dev);

    int smt = kvmppc_smt_threads();

    if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) {

        error_setg(errp, "Unable to find CPU core with core-id: %d",

                   cc->core_id);

        return;

    }

    if (index == 0) {

        error_setg(errp, "Boot CPU core may not be unplugged");

        return;

    }

    drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index * smt);

    g_assert(drc);

    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    drck->detach(drc, dev, spapr_core_release, NULL, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    spapr_hotplug_req_remove_by_index(drc);

}


void commit_active_start(BlockDriverState *bs, BlockDriverState *base,

                         int64_t speed,

                         BlockdevOnError on_error,

                         BlockDriverCompletionFunc *cb,

                         void *opaque, Error **errp)

{

    int64_t length, base_length;

    int orig_base_flags;

    int ret;

    Error *local_err = NULL;

    orig_base_flags = bdrv_get_flags(base);

    if (bdrv_reopen(base, bs->open_flags, errp)) {

        return;

    }

    length = bdrv_getlength(bs);

    if (length < 0) {

        error_setg_errno(errp, -length,

                         "Unable to determine length of %s", bs->filename);

        goto error_restore_flags;

    }

    base_length = bdrv_getlength(base);

    if (base_length < 0) {

        error_setg_errno(errp, -base_length,

                         "Unable to determine length of %s", base->filename);

        goto error_restore_flags;

    }

    if (length > base_length) {

        ret = bdrv_truncate(base, length);

        if (ret < 0) {

            error_setg_errno(errp, -ret,

                            "Top image %s is larger than base image %s, and "

                             "resize of base image failed",

                             bs->filename, base->filename);

            goto error_restore_flags;

        }

    }

    bdrv_ref(base);

    mirror_start_job(bs, base, speed, 0, 0,

                     on_error, on_error, cb, opaque, &local_err,

                     &commit_active_job_driver, false, base);

    if (error_is_set(&local_err)) {

        error_propagate(errp, local_err);

        goto error_restore_flags;

    }

    return;

error_restore_flags:

    /* ignore error and errp for bdrv_reopen, because we want to propagate

     * the original error */

    bdrv_reopen(base, orig_base_flags, NULL);

    return;

}


static void term_up_char(void)

{

    int idx;

    if (term_hist_entry == 0)

	return;

    if (term_hist_entry == -1) {

	/* Find latest entry */

	for (idx = 0; idx < TERM_MAX_CMDS; idx++) {

	    if (term_history[idx] == NULL)

		break;

	}

	term_hist_entry = idx;

    }

    term_hist_entry--;

    if (term_hist_entry >= 0) {

	pstrcpy(term_cmd_buf, sizeof(term_cmd_buf),

                term_history[term_hist_entry]);

	term_cmd_buf_index = term_cmd_buf_size = strlen(term_cmd_buf);

    }

}


static int kalman_smoothen(WMAVoiceContext *s, int pitch,

                           const float *in, float *out, int size)

{

    int n;

    float optimal_gain = 0, dot;

    const float *ptr = &in[-FFMAX(s->min_pitch_val, pitch - 3)],

                *end = &in[-FFMIN(s->max_pitch_val, pitch + 3)],

                *best_hist_ptr;

    /* find best fitting point in history */

    do {

        dot = ff_scalarproduct_float_c(in, ptr, size);

        if (dot > optimal_gain) {

            optimal_gain  = dot;

            best_hist_ptr = ptr;

        }

    } while (--ptr >= end);

    if (optimal_gain <= 0)

        return -1;

    dot = ff_scalarproduct_float_c(best_hist_ptr, best_hist_ptr, size);

    if (dot <= 0) // would be 1.0

        return -1;

    if (optimal_gain <= dot) {

        dot = dot / (dot + 0.6 * optimal_gain); // 0.625-1.000

    } else

        dot = 0.625;

    /* actual smoothing */

    for (n = 0; n < size; n++)

        out[n] = best_hist_ptr[n] + dot * (in[n] - best_hist_ptr[n]);

    return 0;

}