int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl, H264Context *h0)

{

    unsigned int first_mb_in_slice;

    unsigned int pps_id;

    int ret;

    unsigned int slice_type, tmp, i, j;

    int default_ref_list_done = 0;

    int last_pic_structure, last_pic_droppable;

    int needs_reinit = 0;

    int field_pic_flag, bottom_field_flag;

    h->qpel_put = h->h264qpel.put_h264_qpel_pixels_tab;

    h->qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab;

    first_mb_in_slice = get_ue_golomb(&h->gb);

    if (first_mb_in_slice == 0) { // FIXME better field boundary detection

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

            ff_h264_field_end(h, sl, 1);

        }

        h0->current_slice = 0;

        if (!h0->first_field) {

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

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

                                          h->picture_structure == PICT_BOTTOM_FIELD);

            }

            h->cur_pic_ptr = NULL;

        }

    }

    slice_type = get_ue_golomb_31(&h->gb);

    if (slice_type > 9) {

        av_log(h->avctx, AV_LOG_ERROR,

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

               slice_type, h->mb_x, h->mb_y);

        return AVERROR_INVALIDDATA;

    }

    if (slice_type > 4) {

        slice_type -= 5;

        sl->slice_type_fixed = 1;

    } else

        sl->slice_type_fixed = 0;

    slice_type = golomb_to_pict_type[slice_type];

    if (slice_type == AV_PICTURE_TYPE_I ||

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

        default_ref_list_done = 1;

    }

    sl->slice_type     = slice_type;

    sl->slice_type_nos = slice_type & 3;

    if (h->nal_unit_type  == NAL_IDR_SLICE &&

        sl->slice_type_nos != AV_PICTURE_TYPE_I) {

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

        return AVERROR_INVALIDDATA;

    }

    // to make a few old functions happy, it's wrong though

    h->pict_type = sl->slice_type;

    pps_id = get_ue_golomb(&h->gb);

    if (pps_id >= MAX_PPS_COUNT) {

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

        return AVERROR_INVALIDDATA;

    }

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

        av_log(h->avctx, AV_LOG_ERROR,

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

               pps_id);

        return AVERROR_INVALIDDATA;

    }

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

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

        av_log(h->avctx, AV_LOG_ERROR,

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

               h->pps.sps_id);

        return AVERROR_INVALIDDATA;

    }

    if (h->pps.sps_id != h->sps.sps_id ||

        h0->sps_buffers[h->pps.sps_id]->new) {

        h0->sps_buffers[h->pps.sps_id]->new = 0;

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

        if (h->bit_depth_luma    != h->sps.bit_depth_luma ||

            h->chroma_format_idc != h->sps.chroma_format_idc) {

            h->bit_depth_luma    = h->sps.bit_depth_luma;

            h->chroma_format_idc = h->sps.chroma_format_idc;

            needs_reinit         = 1;

        }

        if ((ret = ff_h264_set_parameter_from_sps(h)) < 0)

            return ret;

    }

    h->avctx->profile = ff_h264_get_profile(&h->sps);

    h->avctx->level   = h->sps.level_idc;

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

    if (h->mb_width  != h->sps.mb_width ||

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

        needs_reinit = 1;

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

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

    h->mb_num    = h->mb_width * h->mb_height;

    h->mb_stride = h->mb_width + 1;

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

    h->chroma_y_shift = h->sps.chroma_format_idc <= 1; // 400 uses yuv420p

    h->width  = 16 * h->mb_width;

    h->height = 16 * h->mb_height;

    ret = init_dimensions(h);

    if (ret < 0)

        return ret;

    if (h->sps.video_signal_type_present_flag) {

        h->avctx->color_range = h->sps.full_range ? AVCOL_RANGE_JPEG

                                                  : AVCOL_RANGE_MPEG;

        if (h->sps.colour_description_present_flag) {

            if (h->avctx->colorspace != h->sps.colorspace)

                needs_reinit = 1;

            h->avctx->color_primaries = h->sps.color_primaries;

            h->avctx->color_trc       = h->sps.color_trc;

            h->avctx->colorspace      = h->sps.colorspace;

        }

    }

    if (h->context_initialized && needs_reinit) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "changing width %d -> %d / height %d -> %d on "

                   "slice %d\n",

                   h->width, h->avctx->coded_width,

                   h->height, h->avctx->coded_height,

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

        ff_h264_flush_change(h);

        if ((ret = get_pixel_format(h)) < 0)

            return ret;

        h->avctx->pix_fmt = ret;

        av_log(h->avctx, AV_LOG_INFO, "Reinit context to %dx%d, "

               "pix_fmt: %d\n", h->width, h->height, h->avctx->pix_fmt);

        if ((ret = h264_slice_header_init(h, 1)) < 0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

    if (!h->context_initialized) {

        if (h != h0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "Cannot (re-)initialize context during parallel decoding.\n");

            return AVERROR_PATCHWELCOME;

        }

        if ((ret = get_pixel_format(h)) < 0)

            return ret;

        h->avctx->pix_fmt = ret;

        if ((ret = h264_slice_header_init(h, 0)) < 0) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "h264_slice_header_init() failed\n");

            return ret;

        }

    }

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

        h->dequant_coeff_pps = pps_id;

        h264_init_dequant_tables(h);

    }

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

    h->mb_mbaff        = 0;

    h->mb_aff_frame    = 0;

    last_pic_structure = h0->picture_structure;

    last_pic_droppable = h0->droppable;

    h->droppable       = h->nal_ref_idc == 0;

    if (h->sps.frame_mbs_only_flag) {

        h->picture_structure = PICT_FRAME;

    } else {

        field_pic_flag = get_bits1(&h->gb);

        if (field_pic_flag) {

            bottom_field_flag = get_bits1(&h->gb);

            h->picture_structure = PICT_TOP_FIELD + bottom_field_flag;

        } else {

            h->picture_structure = PICT_FRAME;

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

        }

    }

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

    if (h0->current_slice != 0) {

        if (last_pic_structure != h->picture_structure ||

            last_pic_droppable != h->droppable) {

            av_log(h->avctx, AV_LOG_ERROR,

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

                   last_pic_structure, h->picture_structure);

            h->picture_structure = last_pic_structure;

            h->droppable         = last_pic_droppable;

            return AVERROR_INVALIDDATA;

        } else if (!h0->cur_pic_ptr) {

            av_log(h->avctx, AV_LOG_ERROR,

                   "unset cur_pic_ptr on slice %d\n",

                   h0->current_slice + 1);

            return AVERROR_INVALIDDATA;

        }

    } else {

        /* Shorten frame num gaps so we don't have to allocate reference

         * frames just to throw them away */

        if (h->frame_num != h->prev_frame_num) {

            int unwrap_prev_frame_num = h->prev_frame_num;

            int max_frame_num         = 1 << h->sps.log2_max_frame_num;

            if (unwrap_prev_frame_num > h->frame_num)

                unwrap_prev_frame_num -= max_frame_num;

            if ((h->frame_num - unwrap_prev_frame_num) > h->sps.ref_frame_count) {

                unwrap_prev_frame_num = (h->frame_num - h->sps.ref_frame_count) - 1;

                if (unwrap_prev_frame_num < 0)

                    unwrap_prev_frame_num += max_frame_num;

                h->prev_frame_num = unwrap_prev_frame_num;

            }

        }

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

         * Here, we're using that to see if we should mark previously

         * decode frames as "finished".

         * We have to do that before the "dummy" in-between frame allocation,

         * since that can modify s->current_picture_ptr. */

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

            assert(h0->cur_pic_ptr->f.buf[0]);

            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);

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

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

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

                 * remain for reference if marked as such. */

                if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {

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

                                              last_pic_structure == PICT_TOP_FIELD);

                }

            } else {

                if (h0->cur_pic_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. */

                    if (!last_pic_droppable && last_pic_structure != PICT_FRAME) {

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

                                                  last_pic_structure == PICT_TOP_FIELD);

                    }

                } else {

                    /* Second field in complementary pair */

                    if (!((last_pic_structure   == PICT_TOP_FIELD &&

                           h->picture_structure == PICT_BOTTOM_FIELD) ||

                          (last_pic_structure   == PICT_BOTTOM_FIELD &&

                           h->picture_structure == PICT_TOP_FIELD))) {

                        av_log(h->avctx, AV_LOG_ERROR,

                               "Invalid field mode combination %d/%d\n",

                               last_pic_structure, h->picture_structure);

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_INVALIDDATA;

                    } else if (last_pic_droppable != h->droppable) {

                        avpriv_request_sample(h->avctx,

                                              "Found reference and non-reference fields in the same frame, which");

                        h->picture_structure = last_pic_structure;

                        h->droppable         = last_pic_droppable;

                        return AVERROR_PATCHWELCOME;

                    }

                }

            }

        }

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

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

            H264Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL;

            av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n",

                   h->frame_num, h->prev_frame_num);

            ret = h264_frame_start(h);

            if (ret < 0) {

                h0->first_field = 0;

                return ret;

            }

            h->prev_frame_num++;

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

            h->cur_pic_ptr->frame_num = h->prev_frame_num;

            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);

            ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);

            ret = ff_generate_sliding_window_mmcos(h, 1);

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

                return ret;

            ret = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);

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

                return ret;

            /* Error concealment: If a ref is missing, copy the previous ref

             * in its place.

             * FIXME: Avoiding a memcpy would be nice, but ref handling makes

             * many assumptions about there being no actual duplicates.

             * FIXME: This does not copy padding for out-of-frame motion

             * vectors.  Given we are concealing a lost frame, this probably

             * is not noticeable by comparison, but it should be fixed. */

            if (h->short_ref_count) {

                if (prev) {

                    av_image_copy(h->short_ref[0]->f.data,

                                  h->short_ref[0]->f.linesize,

                                  (const uint8_t **)prev->f.data,

                                  prev->f.linesize,

                                  h->avctx->pix_fmt,

                                  h->mb_width  * 16,

                                  h->mb_height * 16);

                    h->short_ref[0]->poc = prev->poc + 2;

                }

                h->short_ref[0]->frame_num = h->prev_frame_num;

            }

        }

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

         * We're using that to see whether to continue decoding in that

         * frame, or to allocate a new one. */

        if (h0->first_field) {

            assert(h0->cur_pic_ptr);

            assert(h0->cur_pic_ptr->f.buf[0]);

            assert(h0->cur_pic_ptr->reference != DELAYED_PIC_REF);

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

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

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

                 * remain for reference if marked as such. */

                h0->cur_pic_ptr = NULL;

                h0->first_field = FIELD_PICTURE(h);

            } else {

                if (h0->cur_pic_ptr->frame_num != h->frame_num) {

                    /* This and the previous field had different frame_nums.

                     * Consider this field first in pair. Throw away previous

                     * one except for reference purposes. */

                    h0->first_field = 1;

                    h0->cur_pic_ptr = NULL;

                } else {

                    /* Second field in complementary pair */

                    h0->first_field = 0;

                }

            }

        } else {

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

            h0->first_field = FIELD_PICTURE(h);

        }

        if (!FIELD_PICTURE(h) || h0->first_field) {

            if (h264_frame_start(h) < 0) {

                h0->first_field = 0;

                return AVERROR_INVALIDDATA;

            }

        } else {

            release_unused_pictures(h, 0);

        }

    }

    if (h != h0 && (ret = clone_slice(h, h0)) < 0)

        return ret;

    h->cur_pic_ptr->frame_num = h->frame_num; // FIXME frame_num cleanup

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

    if (first_mb_in_slice << FIELD_OR_MBAFF_PICTURE(h) >= h->mb_num ||

        first_mb_in_slice >= h->mb_num) {

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

        return AVERROR_INVALIDDATA;

    }

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

    h->resync_mb_y = h->mb_y = (first_mb_in_slice / h->mb_width) <<

                               FIELD_OR_MBAFF_PICTURE(h);

    if (h->picture_structure == PICT_BOTTOM_FIELD)

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

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

    if (h->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(&h->gb); /* idr_pic_id */

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

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

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

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

    }

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

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

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

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

    }

    ff_init_poc(h, h->cur_pic_ptr->field_poc, &h->cur_pic_ptr->poc);

    if (h->pps.redundant_pic_cnt_present)

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

    ret = ff_set_ref_count(h, sl);

    if (ret < 0)

        return ret;

    else if (ret == 1)

        default_ref_list_done = 0;

    if (!default_ref_list_done)

        ff_h264_fill_default_ref_list(h, sl);

    if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {

       ret = ff_h264_decode_ref_pic_list_reordering(h, sl);

       if (ret < 0) {

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

           return ret;

       }

    }

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

        (h->pps.weighted_bipred_idc == 1 &&

         sl->slice_type_nos == AV_PICTURE_TYPE_B))

        ff_pred_weight_table(h, sl);

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

             sl->slice_type_nos == AV_PICTURE_TYPE_B) {

        implicit_weight_table(h, sl, -1);

    } else {

        sl->use_weight = 0;

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

            sl->luma_weight_flag[i]   = 0;

            sl->chroma_weight_flag[i] = 0;

        }

    }

    // If frame-mt is enabled, only update mmco tables for the first slice

    // in a field. Subsequent slices can temporarily clobber h->mmco_index

    // or h->mmco, which will cause ref list mix-ups and decoding errors

    // further down the line. This may break decoding if the first slice is

    // corrupt, thus we only do this if frame-mt is enabled.

    if (h->nal_ref_idc) {

        ret = ff_h264_decode_ref_pic_marking(h0, &h->gb,

                                             !(h->avctx->active_thread_type & FF_THREAD_FRAME) ||

                                             h0->current_slice == 0);

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

            return AVERROR_INVALIDDATA;

    }

    if (FRAME_MBAFF(h)) {

        ff_h264_fill_mbaff_ref_list(h, sl);

        if (h->pps.weighted_bipred_idc == 2 && sl->slice_type_nos == AV_PICTURE_TYPE_B) {

            implicit_weight_table(h, sl, 0);

            implicit_weight_table(h, sl, 1);

        }

    }

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B && !sl->direct_spatial_mv_pred)

        ff_h264_direct_dist_scale_factor(h, sl);

    ff_h264_direct_ref_list_init(h, sl);

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

        tmp = get_ue_golomb_31(&h->gb);

        if (tmp > 2) {

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

            return AVERROR_INVALIDDATA;

        }

        h->cabac_init_idc = tmp;

    }

    sl->last_qscale_diff = 0;

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

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

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

        return AVERROR_INVALIDDATA;

    }

    sl->qscale       = tmp;

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

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

    // FIXME qscale / qp ... stuff

    if (sl->slice_type == AV_PICTURE_TYPE_SP)

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

    if (sl->slice_type == AV_PICTURE_TYPE_SP ||

        sl->slice_type == AV_PICTURE_TYPE_SI)

        get_se_golomb(&h->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(&h->gb);

        if (tmp > 2) {

            av_log(h->avctx, AV_LOG_ERROR,

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

            return AVERROR_INVALIDDATA;

        }

        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(&h->gb) * 2;

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

            if (h->slice_alpha_c0_offset >  12 ||

                h->slice_alpha_c0_offset < -12 ||

                h->slice_beta_offset >  12     ||

                h->slice_beta_offset < -12) {

                av_log(h->avctx, AV_LOG_ERROR,

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

                       h->slice_alpha_c0_offset, h->slice_beta_offset);

                return AVERROR_INVALIDDATA;

            }

        }

    }

    if (h->avctx->skip_loop_filter >= AVDISCARD_ALL ||

        (h->avctx->skip_loop_filter >= AVDISCARD_NONKEY &&

         sl->slice_type_nos != AV_PICTURE_TYPE_I) ||

        (h->avctx->skip_loop_filter >= AVDISCARD_BIDIR  &&

         sl->slice_type_nos == AV_PICTURE_TYPE_B) ||

        (h->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 (h->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(h->avctx, AV_LOG_INFO,

                       "Cannot parallelize deblocking type 1, decoding such frames in sequential order\n");

                h0->single_decode_warning = 1;

            }

            if (h != h0) {

                av_log(h->avctx, AV_LOG_ERROR,

                       "Deblocking switched inside frame.\n");

                return 1;

            }

        }

    }

    sl->qp_thresh = 15 -

                   FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) -

                   FFMAX3(0,

                          h->pps.chroma_qp_index_offset[0],

                          h->pps.chroma_qp_index_offset[1]) +

                   6 * (h->sps.bit_depth_luma - 8);

    h0->last_slice_type = slice_type;

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

    if (sl->slice_num >= MAX_SLICES) {

        av_log(h->avctx, AV_LOG_ERROR,

               "Too many slices, increase MAX_SLICES and recompile\n");

    }

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

        int id_list[16];

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

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

            id_list[i] = 60;

            if (j < sl->list_count && i < sl->ref_count[j] &&

                sl->ref_list[j][i].f.buf[0]) {

                int k;

                AVBuffer *buf = sl->ref_list[j][i].f.buf[0]->buffer;

                for (k = 0; k < h->short_ref_count; k++)

                    if (h->short_ref[k]->f.buf[0]->buffer == buf) {

                        id_list[i] = k;

                        break;

                    }

                for (k = 0; k < h->long_ref_count; k++)

                    if (h->long_ref[k] && h->long_ref[k]->f.buf[0]->buffer == buf) {

                        id_list[i] = h->short_ref_count + k;

                        break;

                    }

            }

        }

        ref2frm[0] =

        ref2frm[1] = -1;

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

            ref2frm[i + 2] = 4 * id_list[i] + (sl->ref_list[j][i].reference & 3);

        ref2frm[18 + 0] =

        ref2frm[18 + 1] = -1;

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

            ref2frm[i + 4] = 4 * id_list[(i - 16) >> 1] +

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

    }

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

        av_log(h->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",

               sl->slice_num,

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

               first_mb_in_slice,

               av_get_picture_type_char(sl->slice_type),

               sl->slice_type_fixed ? " fix" : "",

               h->nal_unit_type == NAL_IDR_SLICE ? " IDR" : "",

               pps_id, h->frame_num,

               h->cur_pic_ptr->field_poc[0],

               h->cur_pic_ptr->field_poc[1],

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

               sl->qscale,

               h->deblocking_filter,

               h->slice_alpha_c0_offset, h->slice_beta_offset,

               sl->use_weight,

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

               sl->slice_type == AV_PICTURE_TYPE_B ? (sl->direct_spatial_mv_pred ? "SPAT" : "TEMP") : "");

    }

    return 0;

}


Object *qio_task_get_source(QIOTask *task)

{

    object_ref(task->source);

    return task->source;

}


static void gen_ldx(DisasContext *dc, uint32_t code, uint32_t flags)

{

    I_TYPE(instr, code);

    TCGv addr = tcg_temp_new();

    TCGv data;

    /*

     * WARNING: Loads into R_ZERO are ignored, but we must generate the

     *          memory access itself to emulate the CPU precisely. Load

     *          from a protected page to R_ZERO will cause SIGSEGV on

     *          the Nios2 CPU.

     */

    if (likely(instr.b != R_ZERO)) {

        data = dc->cpu_R[instr.b];

    } else {

        data = tcg_temp_new();

    }

    tcg_gen_addi_tl(addr, load_gpr(dc, instr.a), instr.imm16s);

    tcg_gen_qemu_ld_tl(data, addr, dc->mem_idx, flags);

    if (unlikely(instr.b == R_ZERO)) {

        tcg_temp_free(data);

    }

    tcg_temp_free(addr);

}


static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index,

                              int64_t *ppos, int64_t pos_limit)

{

    MpegTSContext *ts = s->priv_data;

    int64_t pos;

    int pos47 = ts->pos47_full % ts->raw_packet_size;

    pos = ((*ppos  + ts->raw_packet_size - 1 - pos47) / ts->raw_packet_size) * ts->raw_packet_size + pos47;

    ff_read_frame_flush(s);

    if (avio_seek(s->pb, pos, SEEK_SET) < 0)

        return AV_NOPTS_VALUE;

    while(pos < pos_limit) {

        int ret;

        AVPacket pkt;

        av_init_packet(&pkt);

        ret= av_read_frame(s, &pkt);

        if(ret < 0)

            return AV_NOPTS_VALUE;

        av_free_packet(&pkt);

        if(pkt.dts != AV_NOPTS_VALUE && pkt.pos >= 0){

            ff_reduce_index(s, pkt.stream_index);

            av_add_index_entry(s->streams[pkt.stream_index], pkt.pos, pkt.dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);

            if(pkt.stream_index == stream_index){

                *ppos= pkt.pos;

                return pkt.dts;

            }

        }

        pos = pkt.pos;

    }

    return AV_NOPTS_VALUE;

}


static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
    uint64_t *host_offset, uint64_t *bytes, QCowL2Meta **m)
{
    BDRVQcowState *s = bs->opaque;
    int l2_index;
    uint64_t *l2_table;
    uint64_t entry;
    unsigned int nb_clusters;
    int ret;
    uint64_t alloc_cluster_offset;
    trace_qcow2_handle_alloc(qemu_coroutine_self(), guest_offset, *host_offset,
                             *bytes);
    assert(*bytes > 0);
    /*
     * Calculate the number of clusters to look for. We stop at L2 table
     * boundaries to keep things simple.
     */
    nb_clusters =
        size_to_clusters(s, offset_into_cluster(s, guest_offset) + *bytes);
    l2_index = offset_to_l2_index(s, guest_offset);
    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);
    /* Find L2 entry for the first involved cluster */
    ret = get_cluster_table(bs, guest_offset, &l2_table, &l2_index);
    if (ret < 0) {
        return ret;
    entry = be64_to_cpu(l2_table[l2_index]);
    /* For the moment, overwrite compressed clusters one by one */
    if (entry & QCOW_OFLAG_COMPRESSED) {
        nb_clusters = 1;
    } else {
        nb_clusters = count_cow_clusters(s, nb_clusters, l2_table, l2_index);
    /* This function is only called when there were no non-COW clusters, so if
     * we can't find any unallocated or COW clusters either, something is
     * wrong with our code. */
    assert(nb_clusters > 0);
    ret = qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
    if (ret < 0) {
        return ret;
    /* Allocate, if necessary at a given offset in the image file */
    alloc_cluster_offset = start_of_cluster(s, *host_offset);
    ret = do_alloc_cluster_offset(bs, guest_offset, &alloc_cluster_offset,
                                  &nb_clusters);
    if (ret < 0) {
    /* Can't extend contiguous allocation */
    if (nb_clusters == 0) {
        *bytes = 0;
        return 0;
    /*
     * Save info needed for meta data update.
     *
     * requested_sectors: Number of sectors from the start of the first
     * newly allocated cluster to the end of the (possibly shortened
     * before) write request.
     *
     * avail_sectors: Number of sectors from the start of the first
     * newly allocated to the end of the last newly allocated cluster.
     *
     * nb_sectors: The number of sectors from the start of the first
     * newly allocated cluster to the end of the area that the write
     * request actually writes to (excluding COW at the end)
     */
    int requested_sectors =
        (*bytes + offset_into_cluster(s, guest_offset))
        >> BDRV_SECTOR_BITS;
    int avail_sectors = nb_clusters
                        << (s->cluster_bits - BDRV_SECTOR_BITS);
    int alloc_n_start = offset_into_cluster(s, guest_offset)
                        >> BDRV_SECTOR_BITS;
    int nb_sectors = MIN(requested_sectors, avail_sectors);
    QCowL2Meta *old_m = *m;
    *m = g_malloc0(sizeof(**m));
    **m = (QCowL2Meta) {
        .next           = old_m,
        .alloc_offset   = alloc_cluster_offset,
        .offset         = start_of_cluster(s, guest_offset),
        .nb_clusters    = nb_clusters,
        .nb_available   = nb_sectors,
        .cow_start = {
            .offset     = 0,
            .nb_sectors = alloc_n_start,
        },
        .cow_end = {
            .offset     = nb_sectors * BDRV_SECTOR_SIZE,
            .nb_sectors = avail_sectors - nb_sectors,
        },
    };
    qemu_co_queue_init(&(*m)->dependent_requests);
    QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight);
    *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset);
    *bytes = MIN(*bytes, (nb_sectors * BDRV_SECTOR_SIZE)
                         - offset_into_cluster(s, guest_offset));
    assert(*bytes != 0);
    return 1;
fail:
    if (*m && (*m)->nb_clusters > 0) {
        QLIST_REMOVE(*m, next_in_flight);
    return ret;


static int rv10_decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             UINT8 *buf, int buf_size)

{

    MpegEncContext *s = avctx->priv_data;

    int i, mb_count, mb_pos, left;

    DCTELEM block[6][64];

    AVPicture *pict = data;

#ifdef DEBUG

    printf("*****frame %d size=%d\n", avctx->frame_number, buf_size);

#endif

    /* no supplementary picture */

    if (buf_size == 0) {

        *data_size = 0;

        return 0;

    }

    init_get_bits(&s->gb, buf, buf_size);

    mb_count = rv10_decode_picture_header(s);

    if (mb_count < 0) {

#ifdef DEBUG

        printf("HEADER ERROR\n");

#endif

        return -1;

    }

    if (s->mb_x >= s->mb_width ||

        s->mb_y >= s->mb_height) {

#ifdef DEBUG

        printf("POS ERROR %d %d\n", s->mb_x, s->mb_y);

#endif

        return -1;

    }

    mb_pos = s->mb_y * s->mb_width + s->mb_x;

    left = s->mb_width * s->mb_height - mb_pos;

    if (mb_count > left) {

#ifdef DEBUG

        printf("COUNT ERROR\n");

#endif

        return -1;

    }

    if (s->mb_x == 0 && s->mb_y == 0) {

        MPV_frame_start(s, avctx);

    }

#ifdef DEBUG

    printf("qscale=%d\n", s->qscale);

#endif

    /* default quantization values */

    s->y_dc_scale = 8;

    s->c_dc_scale = 8;

    s->rv10_first_dc_coded[0] = 0;

    s->rv10_first_dc_coded[1] = 0;

    s->rv10_first_dc_coded[2] = 0;

    s->block_wrap[0]=

    s->block_wrap[1]=

    s->block_wrap[2]=

    s->block_wrap[3]= s->mb_width*2 + 2;

    s->block_wrap[4]=

    s->block_wrap[5]= s->mb_width + 2;

    s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1 + s->mb_x*2;

    s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1)     + s->mb_x*2;

    s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1 + s->mb_x*2;

    s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2)     + s->mb_x*2;

    s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1)                    + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;

    s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;

    /* decode each macroblock */

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

        s->block_index[0]+=2;

        s->block_index[1]+=2;

        s->block_index[2]+=2;

        s->block_index[3]+=2;

        s->block_index[4]++;

        s->block_index[5]++;

#ifdef DEBUG

        printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);

#endif

        memset(block, 0, sizeof(block));

        s->mv_dir = MV_DIR_FORWARD;

        s->mv_type = MV_TYPE_16X16;

        if (h263_decode_mb(s, block) < 0) {

#ifdef DEBUG

            printf("ERROR\n");

#endif

            return -1;

        }

        MPV_decode_mb(s, block);

        if (++s->mb_x == s->mb_width) {

            s->mb_x = 0;

            s->mb_y++;

            s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1;

            s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1);

            s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1;

            s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2);

            s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1)                    + s->block_wrap[0]*(s->mb_height*2 + 2);

            s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2);

        }

    }

    if (s->mb_x == 0 &&

        s->mb_y == s->mb_height) {

        MPV_frame_end(s);

        pict->data[0] = s->current_picture[0];

        pict->data[1] = s->current_picture[1];

        pict->data[2] = s->current_picture[2];

        pict->linesize[0] = s->linesize;

        pict->linesize[1] = s->uvlinesize;

        pict->linesize[2] = s->uvlinesize;

        avctx->quality = s->qscale;

        *data_size = sizeof(AVPicture);

    } else {

        *data_size = 0;

    }

    return buf_size;

}


static int http_open(URLContext *h, const char *uri, int flags)

{

    HTTPContext *s = h->priv_data;

    h->is_streamed = 1;

    s->filesize = -1;

    av_strlcpy(s->location, uri, sizeof(s->location));

    if (s->headers) {

        int len = strlen(s->headers);

        if (len < 2 || strcmp("\r\n", s->headers + len - 2))

            av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n");

    }

    return http_open_cnx(h);

}


static inline void softusb_read_pmem(MilkymistSoftUsbState *s,

        uint32_t offset, uint8_t *buf, uint32_t len)

{

    if (offset + len >= s->pmem_size) {

        error_report("milkymist_softusb: read pmem out of bounds "

                "at offset 0x%x, len %d", offset, len);

        return;

    }

    memcpy(buf, s->pmem_ptr + offset, len);

}


int attribute_align_arg sws_scale(struct SwsContext *c,

                                  const uint8_t * const srcSlice[],

                                  const int srcStride[], int srcSliceY,

                                  int srcSliceH, uint8_t *const dst[],

                                  const int dstStride[])

{

    int i, ret;

    const uint8_t *src2[4] = { srcSlice[0], srcSlice[1], srcSlice[2], srcSlice[3] };

    uint8_t *dst2[4] = { dst[0], dst[1], dst[2], dst[3] };

    uint8_t *rgb0_tmp = NULL;

    // do not mess up sliceDir if we have a "trailing" 0-size slice

    if (srcSliceH == 0)

        return 0;

    if (!check_image_pointers(srcSlice, c->srcFormat, srcStride)) {

        av_log(c, AV_LOG_ERROR, "bad src image pointers\n");

        return 0;

    }

    if (!check_image_pointers((const uint8_t* const*)dst, c->dstFormat, dstStride)) {

        av_log(c, AV_LOG_ERROR, "bad dst image pointers\n");

        return 0;

    }

    if (c->sliceDir == 0 && srcSliceY != 0 && srcSliceY + srcSliceH != c->srcH) {

        av_log(c, AV_LOG_ERROR, "Slices start in the middle!\n");

        return 0;

    }

    if (c->sliceDir == 0) {

        if (srcSliceY == 0) c->sliceDir = 1; else c->sliceDir = -1;

    }

    if (usePal(c->srcFormat)) {

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

            int p, r, g, b, y, u, v, a = 0xff;

            if (c->srcFormat == AV_PIX_FMT_PAL8) {

                p = ((const uint32_t *)(srcSlice[1]))[i];

                a = (p >> 24) & 0xFF;

                r = (p >> 16) & 0xFF;

                g = (p >>  8) & 0xFF;

                b =  p        & 0xFF;

            } else if (c->srcFormat == AV_PIX_FMT_RGB8) {

                r = ( i >> 5     ) * 36;

                g = ((i >> 2) & 7) * 36;

                b = ( i       & 3) * 85;

            } else if (c->srcFormat == AV_PIX_FMT_BGR8) {

                b = ( i >> 6     ) * 85;

                g = ((i >> 3) & 7) * 36;

                r = ( i       & 7) * 36;

            } else if (c->srcFormat == AV_PIX_FMT_RGB4_BYTE) {

                r = ( i >> 3     ) * 255;

                g = ((i >> 1) & 3) * 85;

                b = ( i       & 1) * 255;

            } else if (c->srcFormat == AV_PIX_FMT_GRAY8 || c->srcFormat == AV_PIX_FMT_GRAY8A) {

                r = g = b = i;

            } else {

                av_assert1(c->srcFormat == AV_PIX_FMT_BGR4_BYTE);

                b = ( i >> 3     ) * 255;

                g = ((i >> 1) & 3) * 85;

                r = ( i       & 1) * 255;

            }

#define RGB2YUV_SHIFT 15

#define BY ( (int) (0.114 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define BV (-(int) (0.081 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define BU ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define GY ( (int) (0.587 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define GV (-(int) (0.419 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define GU (-(int) (0.331 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define RY ( (int) (0.299 * 219 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define RV ( (int) (0.500 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

#define RU (-(int) (0.169 * 224 / 255 * (1 << RGB2YUV_SHIFT) + 0.5))

            y = av_clip_uint8((RY * r + GY * g + BY * b + ( 33 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);

            u = av_clip_uint8((RU * r + GU * g + BU * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);

            v = av_clip_uint8((RV * r + GV * g + BV * b + (257 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT);

            c->pal_yuv[i]= y + (u<<8) + (v<<16) + (a<<24);

            switch (c->dstFormat) {

            case AV_PIX_FMT_BGR32:

#if !HAVE_BIGENDIAN

            case AV_PIX_FMT_RGB24:

#endif

                c->pal_rgb[i]=  r + (g<<8) + (b<<16) + (a<<24);

                break;

            case AV_PIX_FMT_BGR32_1:

#if HAVE_BIGENDIAN

            case AV_PIX_FMT_BGR24:

#endif

                c->pal_rgb[i]= a + (r<<8) + (g<<16) + (b<<24);

                break;

            case AV_PIX_FMT_RGB32_1:

#if HAVE_BIGENDIAN

            case AV_PIX_FMT_RGB24:

#endif

                c->pal_rgb[i]= a + (b<<8) + (g<<16) + (r<<24);

                break;

            case AV_PIX_FMT_RGB32:

#if !HAVE_BIGENDIAN

            case AV_PIX_FMT_BGR24:

#endif

            default:

                c->pal_rgb[i]=  b + (g<<8) + (r<<16) + (a<<24);

            }

        }

    }

    if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) {

        uint8_t *base;

        int x,y;

        rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);

        base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;

        for (y=0; y<srcSliceH; y++){

            memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);

            for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) {

                base[ srcStride[0]*y + x] = 0xFF;

            }

        }

        src2[0] = base;

    }

    // copy strides, so they can safely be modified

    if (c->sliceDir == 1) {

        // slices go from top to bottom

        int srcStride2[4] = { srcStride[0], srcStride[1], srcStride[2],

                              srcStride[3] };

        int dstStride2[4] = { dstStride[0], dstStride[1], dstStride[2],

                              dstStride[3] };

        reset_ptr(src2, c->srcFormat);

        reset_ptr((void*)dst2, c->dstFormat);

        /* reset slice direction at end of frame */

        if (srcSliceY + srcSliceH == c->srcH)

            c->sliceDir = 0;

        ret = c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2,

                          dstStride2);

    } else {

        // slices go from bottom to top => we flip the image internally

        int srcStride2[4] = { -srcStride[0], -srcStride[1], -srcStride[2],

                              -srcStride[3] };

        int dstStride2[4] = { -dstStride[0], -dstStride[1], -dstStride[2],

                              -dstStride[3] };

        src2[0] += (srcSliceH - 1) * srcStride[0];

        if (!usePal(c->srcFormat))

            src2[1] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[1];

        src2[2] += ((srcSliceH >> c->chrSrcVSubSample) - 1) * srcStride[2];

        src2[3] += (srcSliceH - 1) * srcStride[3];

        dst2[0] += ( c->dstH                         - 1) * dstStride[0];

        dst2[1] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[1];

        dst2[2] += ((c->dstH >> c->chrDstVSubSample) - 1) * dstStride[2];

        dst2[3] += ( c->dstH                         - 1) * dstStride[3];

        reset_ptr(src2, c->srcFormat);

        reset_ptr((void*)dst2, c->dstFormat);

        /* reset slice direction at end of frame */

        if (!srcSliceY)

            c->sliceDir = 0;

        ret = c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH,

                          srcSliceH, dst2, dstStride2);

    }

    av_free(rgb0_tmp);

    return ret;

}


static av_cold int MPA_encode_init(AVCodecContext *avctx)

{

    MpegAudioContext *s = avctx->priv_data;

    int freq = avctx->sample_rate;

    int bitrate = avctx->bit_rate;

    int channels = avctx->channels;

    int i, v, table;

    float a;

    if (channels <= 0 || channels > 2){

        av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels);

        return AVERROR(EINVAL);

    }

    bitrate = bitrate / 1000;

    s->nb_channels = channels;

    avctx->frame_size = MPA_FRAME_SIZE;

    avctx->delay      = 512 - 32 + 1;

    /* encoding freq */

    s->lsf = 0;

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

        if (avpriv_mpa_freq_tab[i] == freq)

            break;

        if ((avpriv_mpa_freq_tab[i] / 2) == freq) {

            s->lsf = 1;

            break;

        }

    }

    if (i == 3){

        av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq);

        return AVERROR(EINVAL);

    }

    s->freq_index = i;

    /* encoding bitrate & frequency */

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

        if (avpriv_mpa_bitrate_tab[s->lsf][1][i] == bitrate)

            break;

    }

    if (i == 15){

        av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate);

        return AVERROR(EINVAL);

    }

    s->bitrate_index = i;

    /* compute total header size & pad bit */

    a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0);

    s->frame_size = ((int)a) * 8;

    /* frame fractional size to compute padding */

    s->frame_frac = 0;

    s->frame_frac_incr = (int)((a - floor(a)) * 65536.0);

    /* select the right allocation table */

    table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf);

    /* number of used subbands */

    s->sblimit = ff_mpa_sblimit_table[table];

    s->alloc_table = ff_mpa_alloc_tables[table];

    av_dlog(avctx, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n",

            bitrate, freq, s->frame_size, table, s->frame_frac_incr);

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

        s->samples_offset[i] = 0;

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

        int v;

        v = ff_mpa_enwindow[i];

#if WFRAC_BITS != 16

        v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);

#endif

        s->filter_bank[i] = v;

        if ((i & 63) != 0)

            v = -v;

        if (i != 0)

            s->filter_bank[512 - i] = v;

    }

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

        v = (int)(exp2((3 - i) / 3.0) * (1 << 20));

        if (v <= 0)

            v = 1;

        s->scale_factor_table[i] = v;

#if USE_FLOATS

        s->scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);

#else

#define P 15

        s->scale_factor_shift[i] = 21 - P - (i / 3);

        s->scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);

#endif

    }

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

        v = i - 64;

        if (v <= -3)

            v = 0;

        else if (v < 0)

            v = 1;

        else if (v == 0)

            v = 2;

        else if (v < 3)

            v = 3;

        else

            v = 4;

        s->scale_diff_table[i] = v;

    }

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

        v = ff_mpa_quant_bits[i];

        if (v < 0)

            v = -v;

        else

            v = v * 3;

        s->total_quant_bits[i] = 12 * v;

    }

    return 0;

}


static av_cold int vc1_decode_init(AVCodecContext *avctx)
{
    VC1Context *v = avctx->priv_data;
    MpegEncContext *s = &v->s;
    GetBitContext gb;
    int ret;
    /* save the container output size for WMImage */
    v->output_width  = avctx->width;
    v->output_height = avctx->height;
    if (!avctx->extradata_size || !avctx->extradata)
        return -1;
    if (!(avctx->flags & CODEC_FLAG_GRAY))
        avctx->pix_fmt = ff_get_format(avctx, avctx->codec->pix_fmts);
    else
        avctx->pix_fmt = AV_PIX_FMT_GRAY8;
    v->s.avctx = avctx;
    if ((ret = ff_vc1_init_common(v)) < 0)
        return ret;
    // ensure static VLC tables are initialized
    if ((ret = ff_msmpeg4_decode_init(avctx)) < 0)
        return ret;
    if ((ret = ff_vc1_decode_init_alloc_tables(v)) < 0)
        return ret;
    // Hack to ensure the above functions will be called
    // again once we know all necessary settings.
    // That this is necessary might indicate a bug.
    ff_vc1_decode_end(avctx);
    ff_blockdsp_init(&s->bdsp, avctx);
    ff_h264chroma_init(&v->h264chroma, 8);
    ff_qpeldsp_init(&s->qdsp);
    if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) {
        int count = 0;
        // looks like WMV3 has a sequence header stored in the extradata
        // advanced sequence header may be before the first frame
        // the last byte of the extradata is a version number, 1 for the
        // samples we can decode
        init_get_bits(&gb, avctx->extradata, avctx->extradata_size*8);
        if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0)
          return ret;
        count = avctx->extradata_size*8 - get_bits_count(&gb);
        if (count > 0) {
            av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n",
                   count, get_bits(&gb, count));
        } else if (count < 0) {
            av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count);
        }
    } else { // VC1/WVC1/WVP2
        const uint8_t *start = avctx->extradata;
        uint8_t *end = avctx->extradata + avctx->extradata_size;
        const uint8_t *next;
        int size, buf2_size;
        uint8_t *buf2 = NULL;
        int seq_initialized = 0, ep_initialized = 0;
        if (avctx->extradata_size < 16) {
            av_log(avctx, AV_LOG_ERROR, "Extradata size too small: %i\n", avctx->extradata_size);
            return -1;
        }
        buf2  = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
        start = find_next_marker(start, end); // in WVC1 extradata first byte is its size, but can be 0 in mkv
        next  = start;
        for (; next < end; start = next) {
            next = find_next_marker(start + 4, end);
            size = next - start - 4;
            if (size <= 0)
                continue;
            buf2_size = vc1_unescape_buffer(start + 4, size, buf2);
            init_get_bits(&gb, buf2, buf2_size * 8);
            switch (AV_RB32(start)) {
            case VC1_CODE_SEQHDR:
                if ((ret = ff_vc1_decode_sequence_header(avctx, v, &gb)) < 0) {
                    av_free(buf2);
                    return ret;
                }
                seq_initialized = 1;
                break;
            case VC1_CODE_ENTRYPOINT:
                if ((ret = ff_vc1_decode_entry_point(avctx, v, &gb)) < 0) {
                    av_free(buf2);
                    return ret;
                }
                ep_initialized = 1;
                break;
            }
        }
        av_free(buf2);
        if (!seq_initialized || !ep_initialized) {
            av_log(avctx, AV_LOG_ERROR, "Incomplete extradata\n");
            return -1;
        }
        v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE);
    }
    v->sprite_output_frame = av_frame_alloc();
    if (!v->sprite_output_frame)
    avctx->profile = v->profile;
    if (v->profile == PROFILE_ADVANCED)
        avctx->level = v->level;
    avctx->has_b_frames = !!avctx->max_b_frames;
    if (v->color_prim == 1 || v->color_prim == 5 || v->color_prim == 6)
        avctx->color_primaries = v->color_prim;
    if (v->transfer_char == 1 || v->transfer_char == 7)
        avctx->color_trc = v->transfer_char;
    if (v->matrix_coef == 1 || v->matrix_coef == 6 || v->matrix_coef == 7)
        avctx->colorspace = v->matrix_coef;
    s->mb_width  = (avctx->coded_width  + 15) >> 4;
    s->mb_height = (avctx->coded_height + 15) >> 4;
    if (v->profile == PROFILE_ADVANCED || v->res_fasttx) {
        ff_vc1_init_transposed_scantables(v);
    } else {
        memcpy(v->zz_8x8, ff_wmv1_scantable, 4*64);
        v->left_blk_sh = 3;
        v->top_blk_sh  = 0;
    }
    if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {
        v->sprite_width  = avctx->coded_width;
        v->sprite_height = avctx->coded_height;
        avctx->coded_width  = avctx->width  = v->output_width;
        avctx->coded_height = avctx->height = v->output_height;
        // prevent 16.16 overflows
        if (v->sprite_width  > 1 << 14 ||
            v->sprite_height > 1 << 14 ||
            v->output_width  > 1 << 14 ||
            v->output_height > 1 << 14) return -1;
        if ((v->sprite_width&1) || (v->sprite_height&1)) {
            avpriv_request_sample(avctx, "odd sprites support");
            return AVERROR_PATCHWELCOME;
        }
    }
    return 0;
}


int ff_h264_fill_default_ref_list(H264Context *h)

{

    int i, len;

    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {

        Picture *sorted[32];

        int cur_poc, list;

        int lens[2];

        if (FIELD_PICTURE(h))

            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];

        else

            cur_poc = h->cur_pic_ptr->poc;

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

            len  = add_sorted(sorted,       h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);

            len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);

            assert(len <= 32);

            len  = build_def_list(h->default_ref_list[list],       sorted,      len, 0, h->picture_structure);

            len += build_def_list(h->default_ref_list[list] + len, h->long_ref, 16,  1, h->picture_structure);

            assert(len <= 32);

            if (len < h->ref_count[list])

                memset(&h->default_ref_list[list][len], 0, sizeof(Picture) * (h->ref_count[list] - len));

            lens[list] = len;

        }

        if (lens[0] == lens[1] && lens[1] > 1) {

            for (i = 0; i < lens[0] &&

                        h->default_ref_list[0][i].f.buf[0]->buffer ==

                        h->default_ref_list[1][i].f.buf[0]->buffer; i++);

            if (i == lens[0]) {

                Picture tmp;

                COPY_PICTURE(&tmp, &h->default_ref_list[1][0]);

                COPY_PICTURE(&h->default_ref_list[1][0], &h->default_ref_list[1][1]);

                COPY_PICTURE(&h->default_ref_list[1][1], &tmp);

            }

        }

    } else {

        len  = build_def_list(h->default_ref_list[0],       h->short_ref, h->short_ref_count, 0, h->picture_structure);

        len += build_def_list(h->default_ref_list[0] + len, h-> long_ref, 16,                 1, h->picture_structure);

        assert(len <= 32);

        if (len < h->ref_count[0])

            memset(&h->default_ref_list[0][len], 0, sizeof(Picture) * (h->ref_count[0] - len));

    }

#ifdef TRACE

    for (i = 0; i < h->ref_count[0]; i++) {

        tprintf(h->avctx, "List0: %s fn:%d 0x%p\n",

                (h->default_ref_list[0][i].long_ref ? "LT" : "ST"),

                h->default_ref_list[0][i].pic_id,

                h->default_ref_list[0][i].f.data[0]);

    }

    if (h->slice_type_nos == AV_PICTURE_TYPE_B) {

        for (i = 0; i < h->ref_count[1]; i++) {

            tprintf(h->avctx, "List1: %s fn:%d 0x%p\n",

                    (h->default_ref_list[1][i].long_ref ? "LT" : "ST"),

                    h->default_ref_list[1][i].pic_id,

                    h->default_ref_list[1][i].f.data[0]);

        }

    }

#endif

    return 0;

}


static void start_frame(AVFilterLink *link, AVFilterBufferRef *picref)

{

    AVFilterContext *ctx = link->dst;

    CropContext *crop = ctx->priv;

    AVFilterBufferRef *ref2;

    int i;

    picref->video->w = crop->w;

    picref->video->h = crop->h;

    ref2 = avfilter_ref_buffer(picref, ~0);

    crop->var_values[VAR_T] = picref->pts == AV_NOPTS_VALUE ?

        NAN : picref->pts * av_q2d(link->time_base);

    crop->var_values[VAR_POS] = picref->pos == -1 ? NAN : picref->pos;

    crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);

    crop->var_values[VAR_Y] = av_expr_eval(crop->y_pexpr, crop->var_values, NULL);

    crop->var_values[VAR_X] = av_expr_eval(crop->x_pexpr, crop->var_values, NULL);

    normalize_double(&crop->x, crop->var_values[VAR_X]);

    normalize_double(&crop->y, crop->var_values[VAR_Y]);

    if (crop->x < 0) crop->x = 0;

    if (crop->y < 0) crop->y = 0;

    if ((unsigned)crop->x + (unsigned)crop->w > link->w) crop->x = link->w - crop->w;

    if ((unsigned)crop->y + (unsigned)crop->h > link->h) crop->y = link->h - crop->h;

    crop->x &= ~((1 << crop->hsub) - 1);

    crop->y &= ~((1 << crop->vsub) - 1);

    av_log(ctx, AV_LOG_DEBUG,

           "n:%d t:%f x:%d y:%d x+w:%d y+h:%d\n",

           (int)crop->var_values[VAR_N], crop->var_values[VAR_T], crop->x, crop->y, crop->x+crop->w, crop->y+crop->h);

    ref2->data[0] += crop->y * ref2->linesize[0];

    ref2->data[0] += crop->x * crop->max_step[0];

    if (!(av_pix_fmt_descriptors[link->format].flags & PIX_FMT_PAL)) {

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

            if (ref2->data[i]) {

                ref2->data[i] += (crop->y >> crop->vsub) * ref2->linesize[i];

                ref2->data[i] += (crop->x * crop->max_step[i]) >> crop->hsub;

            }

        }

    }

    /* alpha plane */

    if (ref2->data[3]) {

        ref2->data[3] += crop->y * ref2->linesize[3];

        ref2->data[3] += crop->x * crop->max_step[3];

    }

    avfilter_start_frame(link->dst->outputs[0], ref2);

}


static void gen_tlbsx_440(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    TCGv t0;

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    t0 = tcg_temp_new();

    gen_addr_reg_index(ctx, t0);

    gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);

    tcg_temp_free(t0);

    if (Rc(ctx->opcode)) {

        TCGLabel *l1 = gen_new_label();

        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);

        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);

        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);

        gen_set_label(l1);

    }

#endif

}


static void blockdev_backup_prepare(BlkActionState *common, Error **errp)

{

    BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common);

    BlockdevBackup *backup;

    BlockDriverState *bs, *target;

    Error *local_err = NULL;

    assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);

    backup = common->action->u.blockdev_backup.data;

    bs = qmp_get_root_bs(backup->device, errp);

    if (!bs) {

        return;

    }

    target = bdrv_lookup_bs(backup->target, backup->target, errp);

    if (!target) {

        return;

    }

    /* AioContext is released in .clean() */

    state->aio_context = bdrv_get_aio_context(bs);

    if (state->aio_context != bdrv_get_aio_context(target)) {

        state->aio_context = NULL;

        error_setg(errp, "Backup between two IO threads is not implemented");

        return;

    }

    aio_context_acquire(state->aio_context);

    state->bs = bs;

    bdrv_drained_begin(state->bs);

    do_blockdev_backup(backup, common->block_job_txn, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    state->job = state->bs->job;

}


static int guest_get_network_stats(const char *name,

                       GuestNetworkInterfaceStat *stats)

{

    DWORD if_index = 0;

    MIB_IFROW a_mid_ifrow;

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

    if_index = get_interface_index(name);

    a_mid_ifrow.dwIndex = if_index;

    if (NO_ERROR == GetIfEntry(&a_mid_ifrow)) {

        stats->rx_bytes = a_mid_ifrow.dwInOctets;

        stats->rx_packets = a_mid_ifrow.dwInUcastPkts;

        stats->rx_errs = a_mid_ifrow.dwInErrors;

        stats->rx_dropped = a_mid_ifrow.dwInDiscards;

        stats->tx_bytes = a_mid_ifrow.dwOutOctets;

        stats->tx_packets = a_mid_ifrow.dwOutUcastPkts;

        stats->tx_errs = a_mid_ifrow.dwOutErrors;

        stats->tx_dropped = a_mid_ifrow.dwOutDiscards;

        return 0;

    }

    return -1;

}


void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)

{

    CPUARMState *env = &cpu->env;

    int kernel_size;

    int initrd_size;

    int n;

    int is_linux = 0;

    uint64_t elf_entry;

    target_phys_addr_t entry;

    int big_endian;

    QemuOpts *machine_opts;

    /* Load the kernel.  */

    if (!info->kernel_filename) {

        fprintf(stderr, "Kernel image must be specified\n");

        exit(1);

    }

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

    if (machine_opts) {

        info->dtb_filename = qemu_opt_get(machine_opts, "dtb");

    } else {

        info->dtb_filename = NULL;

    }

    if (!info->secondary_cpu_reset_hook) {

        info->secondary_cpu_reset_hook = default_reset_secondary;

    }

    if (!info->write_secondary_boot) {

        info->write_secondary_boot = default_write_secondary;

    }

    if (info->nb_cpus == 0)

        info->nb_cpus = 1;

#ifdef TARGET_WORDS_BIGENDIAN

    big_endian = 1;

#else

    big_endian = 0;

#endif

    /* Assume that raw images are linux kernels, and ELF images are not.  */

    kernel_size = load_elf(info->kernel_filename, NULL, NULL, &elf_entry,

                           NULL, NULL, big_endian, ELF_MACHINE, 1);

    entry = elf_entry;

    if (kernel_size < 0) {

        kernel_size = load_uimage(info->kernel_filename, &entry, NULL,

                                  &is_linux);

    }

    if (kernel_size < 0) {

        entry = info->loader_start + KERNEL_LOAD_ADDR;

        kernel_size = load_image_targphys(info->kernel_filename, entry,

                                          info->ram_size - KERNEL_LOAD_ADDR);

        is_linux = 1;

    }

    if (kernel_size < 0) {

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

                info->kernel_filename);

        exit(1);

    }

    info->entry = entry;

    if (is_linux) {

        if (info->initrd_filename) {

            initrd_size = load_image_targphys(info->initrd_filename,

                                              info->loader_start

                                              + INITRD_LOAD_ADDR,

                                              info->ram_size

                                              - INITRD_LOAD_ADDR);

            if (initrd_size < 0) {

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

                        info->initrd_filename);

                exit(1);

            }

        } else {

            initrd_size = 0;

        }

        info->initrd_size = initrd_size;

        bootloader[4] = info->board_id;

        /* for device tree boot, we pass the DTB directly in r2. Otherwise

         * we point to the kernel args.

         */

        if (info->dtb_filename) {

            /* Place the DTB after the initrd in memory */

            target_phys_addr_t dtb_start = TARGET_PAGE_ALIGN(info->loader_start

                                                             + INITRD_LOAD_ADDR

                                                             + initrd_size);

            if (load_dtb(dtb_start, info)) {

                exit(1);

            }

            bootloader[5] = dtb_start;

        } else {

            bootloader[5] = info->loader_start + KERNEL_ARGS_ADDR;

            if (info->ram_size >= (1ULL << 32)) {

                fprintf(stderr, "qemu: RAM size must be less than 4GB to boot"

                        " Linux kernel using ATAGS (try passing a device tree"

                        " using -dtb)\n");

                exit(1);

            }

        }

        bootloader[6] = entry;

        for (n = 0; n < sizeof(bootloader) / 4; n++) {

            bootloader[n] = tswap32(bootloader[n]);

        }

        rom_add_blob_fixed("bootloader", bootloader, sizeof(bootloader),

                           info->loader_start);

        if (info->nb_cpus > 1) {

            info->write_secondary_boot(cpu, info);

        }

    }

    info->is_linux = is_linux;

    for (; env; env = env->next_cpu) {

        cpu = arm_env_get_cpu(env);

        env->boot_info = info;

        qemu_register_reset(do_cpu_reset, cpu);

    }

}


static CharDriverState *qemu_chr_open_null(void)

{

    CharDriverState *chr;

    chr = g_malloc0(sizeof(CharDriverState));

    chr->chr_write = null_chr_write;

    chr->explicit_be_open = true;

    return chr;

}


static bool nvic_rettobase(NVICState *s)

{

    int irq, nhand = 0;

    for (irq = ARMV7M_EXCP_RESET; irq < s->num_irq; irq++) {

        if (s->vectors[irq].active) {

            nhand++;

            if (nhand == 2) {

                return 0;

            }

        }

    }

    return 1;

}


void ioinst_handle_xsch(S390CPU *cpu, uint64_t reg1)

{

    int cssid, ssid, schid, m;

    SubchDev *sch;

    int ret = -ENODEV;

    int cc;

    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {

        program_interrupt(&cpu->env, PGM_OPERAND, 2);

        return;

    }

    trace_ioinst_sch_id("xsch", cssid, ssid, schid);

    sch = css_find_subch(m, cssid, ssid, schid);

    if (sch && css_subch_visible(sch)) {

        ret = css_do_xsch(sch);

    }

    switch (ret) {

    case -ENODEV:

        cc = 3;

        break;

    case -EBUSY:

        cc = 2;

        break;

    case 0:

        cc = 0;

        break;

    default:

        cc = 1;

        break;

    }

    setcc(cpu, cc);

}


static int vtd_dev_to_context_entry(IntelIOMMUState *s, uint8_t bus_num,

                                    uint8_t devfn, VTDContextEntry *ce)

{

    VTDRootEntry re;

    int ret_fr;

    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);

    ret_fr = vtd_get_root_entry(s, bus_num, &re);

    if (ret_fr) {

        return ret_fr;

    }

    if (!vtd_root_entry_present(&re)) {

        /* Not error - it's okay we don't have root entry. */

        trace_vtd_re_not_present(bus_num);

        return -VTD_FR_ROOT_ENTRY_P;

    }

    if (re.rsvd || (re.val & VTD_ROOT_ENTRY_RSVD(VTD_HOST_ADDRESS_WIDTH))) {

        trace_vtd_re_invalid(re.rsvd, re.val);

        return -VTD_FR_ROOT_ENTRY_RSVD;

    }

    ret_fr = vtd_get_context_entry_from_root(&re, devfn, ce);

    if (ret_fr) {

        return ret_fr;

    }

    if (!vtd_ce_present(ce)) {

        /* Not error - it's okay we don't have context entry. */

        trace_vtd_ce_not_present(bus_num, devfn);

        return -VTD_FR_CONTEXT_ENTRY_P;

    }

    if ((ce->hi & VTD_CONTEXT_ENTRY_RSVD_HI) ||

               (ce->lo & VTD_CONTEXT_ENTRY_RSVD_LO(VTD_HOST_ADDRESS_WIDTH))) {

        trace_vtd_ce_invalid(ce->hi, ce->lo);

        return -VTD_FR_CONTEXT_ENTRY_RSVD;

    }

    /* Check if the programming of context-entry is valid */

    if (!vtd_is_level_supported(s, vtd_ce_get_level(ce))) {

        trace_vtd_ce_invalid(ce->hi, ce->lo);

        return -VTD_FR_CONTEXT_ENTRY_INV;

    }

    /* Do translation type check */

    if (!vtd_ce_type_check(x86_iommu, ce)) {

        trace_vtd_ce_invalid(ce->hi, ce->lo);

        return -VTD_FR_CONTEXT_ENTRY_INV;

    }

    return 0;

}


static void do_interrupt_real(int intno, int is_int, int error_code,

                                 unsigned int next_eip)

{

    SegmentCache *dt;

    uint8_t *ptr, *ssp;

    int selector;

    uint32_t offset, esp;

    uint32_t old_cs, old_eip;

    /* real mode (simpler !) */

    dt = &env->idt;

    if (intno * 4 + 3 > dt->limit)

        raise_exception_err(EXCP0D_GPF, intno * 8 + 2);

    ptr = dt->base + intno * 4;

    offset = lduw(ptr);

    selector = lduw(ptr + 2);

    esp = env->regs[R_ESP];

    ssp = env->segs[R_SS].base;

    if (is_int)

        old_eip = next_eip;

    else

        old_eip = env->eip;

    old_cs = env->segs[R_CS].selector;

    esp -= 2;

    stw(ssp + (esp & 0xffff), compute_eflags());

    esp -= 2;

    stw(ssp + (esp & 0xffff), old_cs);

    esp -= 2;

    stw(ssp + (esp & 0xffff), old_eip);

    /* update processor state */

    env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | (esp & 0xffff);

    env->eip = offset;

    env->segs[R_CS].selector = selector;

    env->segs[R_CS].base = (uint8_t *)(selector << 4);

    env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);

}


void ff_ass_init(AVSubtitle *sub)

{

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

}


uint64_t helper_stl_c_raw(uint64_t t0, uint64_t t1)

{

    uint64_t ret;

    if (t1 == env->lock) {

        stl_raw(t1, t0);

        ret = 0;

    } else

        ret = 1;

    env->lock = 1;

    return ret;

}


int AUD_read (SWVoiceIn *sw, void *buf, int size)

{

    int bytes;

    if (!sw) {

        /* XXX: Consider options */

        return size;

    }

    if (!sw->hw->enabled) {

        dolog ("Reading from disabled voice %s\n", SW_NAME (sw));

        return 0;

    }

    bytes = sw->hw->pcm_ops->read (sw, buf, size);

    return bytes;

}


QEMUFile *qemu_fopen_ops_buffered(void *opaque,

                                  size_t bytes_per_sec,

                                  BufferedPutFunc *put_buffer,

                                  BufferedPutReadyFunc *put_ready,

                                  BufferedWaitForUnfreezeFunc *wait_for_unfreeze,

                                  BufferedCloseFunc *close)

{

    QEMUFileBuffered *s;

    s = qemu_mallocz(sizeof(*s));

    s->opaque = opaque;

    s->xfer_limit = bytes_per_sec / 10;

    s->put_buffer = put_buffer;

    s->put_ready = put_ready;

    s->wait_for_unfreeze = wait_for_unfreeze;

    s->close = close;

    s->file = qemu_fopen_ops(s, buffered_put_buffer, NULL,

                             buffered_close, buffered_rate_limit,

                             buffered_set_rate_limit,

			     buffered_get_rate_limit);

    s->timer = qemu_new_timer(rt_clock, buffered_rate_tick, s);

    qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100);

    return s->file;

}


int keysym2scancode(void *kbd_layout, int keysym)

{

    kbd_layout_t *k = kbd_layout;

    if (keysym < MAX_NORMAL_KEYCODE) {

        if (k->keysym2keycode[keysym] == 0) {

            trace_keymap_unmapped(keysym);

            fprintf(stderr, "Warning: no scancode found for keysym %d\n",

                    keysym);

        }

        return k->keysym2keycode[keysym];

    } else {

        int i;

#ifdef XK_ISO_Left_Tab

        if (keysym == XK_ISO_Left_Tab) {

            keysym = XK_Tab;

        }

#endif

        for (i = 0; i < k->extra_count; i++) {

            if (k->keysym2keycode_extra[i].keysym == keysym) {

                return k->keysym2keycode_extra[i].keycode;

            }

        }

    }

    return 0;

}


gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb,

                               bool search_pc)

{

    CPUState *cs = CPU(cpu);

    CPUM68KState *env = &cpu->env;

    DisasContext dc1, *dc = &dc1;

    uint16_t *gen_opc_end;

    CPUBreakpoint *bp;

    int j, lj;

    target_ulong pc_start;

    int pc_offset;

    int num_insns;

    int max_insns;

    /* generate intermediate code */

    pc_start = tb->pc;

    dc->tb = tb;

    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;

    dc->env = env;

    dc->is_jmp = DISAS_NEXT;

    dc->pc = pc_start;

    dc->cc_op = CC_OP_DYNAMIC;

    dc->singlestep_enabled = cs->singlestep_enabled;

    dc->fpcr = env->fpcr;

    dc->user = (env->sr & SR_S) == 0;

    dc->is_mem = 0;

    dc->done_mac = 0;

    lj = -1;

    num_insns = 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0)

        max_insns = CF_COUNT_MASK;

    gen_tb_start();

    do {

        pc_offset = dc->pc - pc_start;

        gen_throws_exception = NULL;

        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {

            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {

                if (bp->pc == dc->pc) {

                    gen_exception(dc, dc->pc, EXCP_DEBUG);

                    dc->is_jmp = DISAS_JUMP;

                    break;

                }

            }

            if (dc->is_jmp)

                break;

        }

        if (search_pc) {

            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

            if (lj < j) {

                lj++;

                while (lj < j)

                    tcg_ctx.gen_opc_instr_start[lj++] = 0;

            }

            tcg_ctx.gen_opc_pc[lj] = dc->pc;

            tcg_ctx.gen_opc_instr_start[lj] = 1;

            tcg_ctx.gen_opc_icount[lj] = num_insns;

        }

        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))

            gen_io_start();

        dc->insn_pc = dc->pc;

	disas_m68k_insn(env, dc);

        num_insns++;

    } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&

             !cs->singlestep_enabled &&

             !singlestep &&

             (pc_offset) < (TARGET_PAGE_SIZE - 32) &&

             num_insns < max_insns);

    if (tb->cflags & CF_LAST_IO)

        gen_io_end();

    if (unlikely(cs->singlestep_enabled)) {

        /* Make sure the pc is updated, and raise a debug exception.  */

        if (!dc->is_jmp) {

            gen_flush_cc_op(dc);

            tcg_gen_movi_i32(QREG_PC, dc->pc);

        }

        gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));

    } else {

        switch(dc->is_jmp) {

        case DISAS_NEXT:

            gen_flush_cc_op(dc);

            gen_jmp_tb(dc, 0, dc->pc);

            break;

        default:

        case DISAS_JUMP:

        case DISAS_UPDATE:

            gen_flush_cc_op(dc);

            /* indicate that the hash table must be used to find the next TB */

            tcg_gen_exit_tb(0);

            break;

        case DISAS_TB_JUMP:

            /* nothing more to generate */

            break;

        }

    }

    gen_tb_end(tb, num_insns);

    *tcg_ctx.gen_opc_ptr = INDEX_op_end;

#ifdef DEBUG_DISAS

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {

        qemu_log("----------------\n");

        qemu_log("IN: %s\n", lookup_symbol(pc_start));

        log_target_disas(env, pc_start, dc->pc - pc_start, 0);

        qemu_log("\n");

    }

#endif

    if (search_pc) {

        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;

        lj++;

        while (lj <= j)

            tcg_ctx.gen_opc_instr_start[lj++] = 0;

    } else {

        tb->size = dc->pc - pc_start;

        tb->icount = num_insns;

    }

    //optimize_flags();

    //expand_target_qops();

}


static CCPrepare gen_prepare_eflags_c(DisasContext *s, TCGv reg)

{

    TCGv t0, t1;

    int size, shift;

    switch (s->cc_op) {

    case CC_OP_SUBB ... CC_OP_SUBQ:

        /* (DATA_TYPE)(CC_DST + CC_SRC) < (DATA_TYPE)CC_SRC */

        size = s->cc_op - CC_OP_SUBB;

        t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);

        /* If no temporary was used, be careful not to alias t1 and t0.  */

        t0 = TCGV_EQUAL(t1, cpu_cc_src) ? cpu_tmp0 : reg;

        tcg_gen_add_tl(t0, cpu_cc_dst, cpu_cc_src);

        gen_extu(size, t0);

        goto add_sub;

    case CC_OP_ADDB ... CC_OP_ADDQ:

        /* (DATA_TYPE)CC_DST < (DATA_TYPE)CC_SRC */

        size = s->cc_op - CC_OP_ADDB;

        t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);

        t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);

    add_sub:

        return (CCPrepare) { .cond = TCG_COND_LTU, .reg = t0,

                             .reg2 = t1, .mask = -1, .use_reg2 = true };

    case CC_OP_SBBB ... CC_OP_SBBQ:

        /* (DATA_TYPE)(CC_DST + CC_SRC + 1) <= (DATA_TYPE)CC_SRC */

        size = s->cc_op - CC_OP_SBBB;

        t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);

        if (TCGV_EQUAL(t1, reg) && TCGV_EQUAL(reg, cpu_cc_src)) {

            tcg_gen_mov_tl(cpu_tmp0, cpu_cc_src);

            t1 = cpu_tmp0;

        }

        tcg_gen_add_tl(reg, cpu_cc_dst, cpu_cc_src);

        tcg_gen_addi_tl(reg, reg, 1);

        gen_extu(size, reg);

        t0 = reg;

        goto adc_sbb;

    case CC_OP_ADCB ... CC_OP_ADCQ:

        /* (DATA_TYPE)CC_DST <= (DATA_TYPE)CC_SRC */

        size = s->cc_op - CC_OP_ADCB;

        t1 = gen_ext_tl(cpu_tmp0, cpu_cc_src, size, false);

        t0 = gen_ext_tl(reg, cpu_cc_dst, size, false);

    adc_sbb:

        return (CCPrepare) { .cond = TCG_COND_LEU, .reg = t0,

                             .reg2 = t1, .mask = -1, .use_reg2 = true };

    case CC_OP_LOGICB ... CC_OP_LOGICQ:

        return (CCPrepare) { .cond = TCG_COND_NEVER, .mask = -1 };

    case CC_OP_INCB ... CC_OP_INCQ:

    case CC_OP_DECB ... CC_OP_DECQ:

        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,

                             .mask = -1, .no_setcond = true };

    case CC_OP_SHLB ... CC_OP_SHLQ:

        /* (CC_SRC >> (DATA_BITS - 1)) & 1 */

        size = s->cc_op - CC_OP_SHLB;

        shift = (8 << size) - 1;

        return (CCPrepare) { .cond = TCG_COND_NE, .reg = cpu_cc_src,

                             .mask = (target_ulong)1 << shift };

    case CC_OP_MULB ... CC_OP_MULQ:

        return (CCPrepare) { .cond = TCG_COND_NE,

                             .reg = cpu_cc_src, .mask = -1 };

    case CC_OP_EFLAGS:

    case CC_OP_SARB ... CC_OP_SARQ:

        /* CC_SRC & 1 */

        return (CCPrepare) { .cond = TCG_COND_NE,

                             .reg = cpu_cc_src, .mask = CC_C };

    default:

       /* The need to compute only C from CC_OP_DYNAMIC is important

          in efficiently implementing e.g. INC at the start of a TB.  */

       gen_update_cc_op(s);

       gen_helper_cc_compute_c(cpu_tmp2_i32, cpu_env, cpu_cc_op);

       tcg_gen_extu_i32_tl(reg, cpu_tmp2_i32);

       return (CCPrepare) { .cond = TCG_COND_NE, .reg = reg,

                            .mask = -1, .no_setcond = true };

    }

}


static void pflash_cfi01_realize(DeviceState *dev, Error **errp)

{

    pflash_t *pfl = CFI_PFLASH01(dev);

    uint64_t total_len;

    int ret;

    uint64_t blocks_per_device, device_len;

    int num_devices;

    Error *local_err = NULL;

    total_len = pfl->sector_len * pfl->nb_blocs;

    /* These are only used to expose the parameters of each device

     * in the cfi_table[].

     */

    num_devices = pfl->device_width ? (pfl->bank_width / pfl->device_width) : 1;

    blocks_per_device = pfl->nb_blocs / num_devices;

    device_len = pfl->sector_len * blocks_per_device;

    /* XXX: to be fixed */

#if 0

    if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&

        total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))

        return NULL;

#endif

    memory_region_init_rom_device(

        &pfl->mem, OBJECT(dev),

        pfl->be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl,

        pfl->name, total_len, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    vmstate_register_ram(&pfl->mem, DEVICE(pfl));

    pfl->storage = memory_region_get_ram_ptr(&pfl->mem);

    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);

    if (pfl->bs) {

        /* read the initial flash content */

        ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);

        if (ret < 0) {

            vmstate_unregister_ram(&pfl->mem, DEVICE(pfl));

            error_setg(errp, "failed to read the initial flash content");

            return;

        }

    }

    if (pfl->bs) {

        pfl->ro = bdrv_is_read_only(pfl->bs);

    } else {

        pfl->ro = 0;

    }

    /* Default to devices being used at their maximum device width. This was

     * assumed before the device_width support was added.

     */

    if (!pfl->max_device_width) {

        pfl->max_device_width = pfl->device_width;

    }

    pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);

    pfl->wcycle = 0;

    pfl->cmd = 0;

    pfl->status = 0;

    /* Hardcoded CFI table */

    pfl->cfi_len = 0x52;

    /* Standard "QRY" string */

    pfl->cfi_table[0x10] = 'Q';

    pfl->cfi_table[0x11] = 'R';

    pfl->cfi_table[0x12] = 'Y';

    /* Command set (Intel) */

    pfl->cfi_table[0x13] = 0x01;

    pfl->cfi_table[0x14] = 0x00;

    /* Primary extended table address (none) */

    pfl->cfi_table[0x15] = 0x31;

    pfl->cfi_table[0x16] = 0x00;

    /* Alternate command set (none) */

    pfl->cfi_table[0x17] = 0x00;

    pfl->cfi_table[0x18] = 0x00;

    /* Alternate extended table (none) */

    pfl->cfi_table[0x19] = 0x00;

    pfl->cfi_table[0x1A] = 0x00;

    /* Vcc min */

    pfl->cfi_table[0x1B] = 0x45;

    /* Vcc max */

    pfl->cfi_table[0x1C] = 0x55;

    /* Vpp min (no Vpp pin) */

    pfl->cfi_table[0x1D] = 0x00;

    /* Vpp max (no Vpp pin) */

    pfl->cfi_table[0x1E] = 0x00;

    /* Reserved */

    pfl->cfi_table[0x1F] = 0x07;

    /* Timeout for min size buffer write */

    pfl->cfi_table[0x20] = 0x07;

    /* Typical timeout for block erase */

    pfl->cfi_table[0x21] = 0x0a;

    /* Typical timeout for full chip erase (4096 ms) */

    pfl->cfi_table[0x22] = 0x00;

    /* Reserved */

    pfl->cfi_table[0x23] = 0x04;

    /* Max timeout for buffer write */

    pfl->cfi_table[0x24] = 0x04;

    /* Max timeout for block erase */

    pfl->cfi_table[0x25] = 0x04;

    /* Max timeout for chip erase */

    pfl->cfi_table[0x26] = 0x00;

    /* Device size */

    pfl->cfi_table[0x27] = ctz32(device_len); /* + 1; */

    /* Flash device interface (8 & 16 bits) */

    pfl->cfi_table[0x28] = 0x02;

    pfl->cfi_table[0x29] = 0x00;

    /* Max number of bytes in multi-bytes write */

    if (pfl->bank_width == 1) {

        pfl->cfi_table[0x2A] = 0x08;

    } else {

        pfl->cfi_table[0x2A] = 0x0B;

    }

    pfl->writeblock_size = 1 << pfl->cfi_table[0x2A];

    pfl->cfi_table[0x2B] = 0x00;

    /* Number of erase block regions (uniform) */

    pfl->cfi_table[0x2C] = 0x01;

    /* Erase block region 1 */

    pfl->cfi_table[0x2D] = blocks_per_device - 1;

    pfl->cfi_table[0x2E] = (blocks_per_device - 1) >> 8;

    pfl->cfi_table[0x2F] = pfl->sector_len >> 8;

    pfl->cfi_table[0x30] = pfl->sector_len >> 16;

    /* Extended */

    pfl->cfi_table[0x31] = 'P';

    pfl->cfi_table[0x32] = 'R';

    pfl->cfi_table[0x33] = 'I';

    pfl->cfi_table[0x34] = '1';

    pfl->cfi_table[0x35] = '0';

    pfl->cfi_table[0x36] = 0x00;

    pfl->cfi_table[0x37] = 0x00;

    pfl->cfi_table[0x38] = 0x00;

    pfl->cfi_table[0x39] = 0x00;

    pfl->cfi_table[0x3a] = 0x00;

    pfl->cfi_table[0x3b] = 0x00;

    pfl->cfi_table[0x3c] = 0x00;

    pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */

}


static long do_rt_sigreturn_v2(CPUARMState *env)

{

    abi_ulong frame_addr;

    struct rt_sigframe_v2 *frame = NULL;

    /*

     * Since we stacked the signal on a 64-bit boundary,

     * then 'sp' should be word aligned here.  If it's

     * not, then the user is trying to mess with us.

     */

    frame_addr = env->regs[13];

    trace_user_do_rt_sigreturn(env, frame_addr);

    if (frame_addr & 7) {

        goto badframe;

    }

    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {

        goto badframe;

    }

    if (do_sigframe_return_v2(env, frame_addr, &frame->uc)) {

        goto badframe;

    }

    unlock_user_struct(frame, frame_addr, 0);

    return env->regs[0];

badframe:

    unlock_user_struct(frame, frame_addr, 0);

    force_sig(TARGET_SIGSEGV /* , current */);

    return 0;

}


void bdrv_drain_all_begin(void)

{

    /* Always run first iteration so any pending completion BHs run */

    bool waited = true;

    BlockDriverState *bs;

    BdrvNextIterator it;

    GSList *aio_ctxs = NULL, *ctx;

    block_job_pause_all();

    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {

        AioContext *aio_context = bdrv_get_aio_context(bs);

        aio_context_acquire(aio_context);

        bdrv_parent_drained_begin(bs);

        aio_disable_external(aio_context);

        aio_context_release(aio_context);

        if (!g_slist_find(aio_ctxs, aio_context)) {

            aio_ctxs = g_slist_prepend(aio_ctxs, aio_context);

        }

    }

    /* Note that completion of an asynchronous I/O operation can trigger any

     * number of other I/O operations on other devices---for example a

     * coroutine can submit an I/O request to another device in response to

     * request completion.  Therefore we must keep looping until there was no

     * more activity rather than simply draining each device independently.

     */

    while (waited) {

        waited = false;

        for (ctx = aio_ctxs; ctx != NULL; ctx = ctx->next) {

            AioContext *aio_context = ctx->data;

            aio_context_acquire(aio_context);

            for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {

                if (aio_context == bdrv_get_aio_context(bs)) {

                    /* FIXME Calling this multiple times is wrong */

                    bdrv_drain_invoke(bs, true);

                    waited |= bdrv_drain_recurse(bs, true);

                }

            }

            aio_context_release(aio_context);

        }

    }

    g_slist_free(aio_ctxs);

}


static size_t qemu_rdma_save_page(QEMUFile *f, void *opaque,

                                  ram_addr_t block_offset, ram_addr_t offset,

                                  size_t size, int *bytes_sent)

{

    QEMUFileRDMA *rfile = opaque;

    RDMAContext *rdma = rfile->rdma;

    int ret;

    CHECK_ERROR_STATE();

    qemu_fflush(f);

    if (size > 0) {

        /*

         * Add this page to the current 'chunk'. If the chunk

         * is full, or the page doen't belong to the current chunk,

         * an actual RDMA write will occur and a new chunk will be formed.

         */

        ret = qemu_rdma_write(f, rdma, block_offset, offset, size);

        if (ret < 0) {

            fprintf(stderr, "rdma migration: write error! %d\n", ret);

            goto err;

        }

        /*

         * We always return 1 bytes because the RDMA

         * protocol is completely asynchronous. We do not yet know

         * whether an  identified chunk is zero or not because we're

         * waiting for other pages to potentially be merged with

         * the current chunk. So, we have to call qemu_update_position()

         * later on when the actual write occurs.

         */

        if (bytes_sent) {

            *bytes_sent = 1;

        }

    } else {

        uint64_t index, chunk;

        /* TODO: Change QEMUFileOps prototype to be signed: size_t => long

        if (size < 0) {

            ret = qemu_rdma_drain_cq(f, rdma);

            if (ret < 0) {

                fprintf(stderr, "rdma: failed to synchronously drain"

                                " completion queue before unregistration.\n");

                goto err;

            }

        }

        */

        ret = qemu_rdma_search_ram_block(rdma, block_offset,

                                         offset, size, &index, &chunk);

        if (ret) {

            fprintf(stderr, "ram block search failed\n");

            goto err;

        }

        qemu_rdma_signal_unregister(rdma, index, chunk, 0);

        /*

         * TODO: Synchronous, guaranteed unregistration (should not occur during

         * fast-path). Otherwise, unregisters will process on the next call to

         * qemu_rdma_drain_cq()

        if (size < 0) {

            qemu_rdma_unregister_waiting(rdma);

        }

        */

    }

    /*

     * Drain the Completion Queue if possible, but do not block,

     * just poll.

     *

     * If nothing to poll, the end of the iteration will do this

     * again to make sure we don't overflow the request queue.

     */

    while (1) {

        uint64_t wr_id, wr_id_in;

        int ret = qemu_rdma_poll(rdma, &wr_id_in, NULL);

        if (ret < 0) {

            fprintf(stderr, "rdma migration: polling error! %d\n", ret);

            goto err;

        }

        wr_id = wr_id_in & RDMA_WRID_TYPE_MASK;

        if (wr_id == RDMA_WRID_NONE) {

            break;

        }

    }

    return RAM_SAVE_CONTROL_DELAYED;

err:

    rdma->error_state = ret;

    return ret;

}


int xen_be_init(void)

{

    xenstore = xs_daemon_open();

    if (!xenstore) {

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

        return -1;

    }

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

        goto err;

    }

    if (xen_xc == XC_HANDLER_INITIAL_VALUE) {

        /* Check if xen_init() have been called */

        goto err;

    }

    return 0;

err:

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

    xs_daemon_close(xenstore);

    xenstore = NULL;

    return -1;

}


static void guess_palette(DVDSubContext* ctx,

                          uint32_t *rgba_palette,

                          uint32_t subtitle_color)

{

    static const uint8_t level_map[4][4] = {

        // this configuration (full range, lowest to highest) in tests

        // seemed most common, so assume this

        {0xff},

        {0x00, 0xff},

        {0x00, 0x80, 0xff},

        {0x00, 0x55, 0xaa, 0xff},

    };

    uint8_t color_used[16] = { 0 };

    int nb_opaque_colors, i, level, j, r, g, b;

    uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;

    if(ctx->has_palette) {

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

            rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff)

                              | ((alpha[i] * 17U) << 24);

        return;

    }

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

        rgba_palette[i] = 0;

    nb_opaque_colors = 0;

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

        if (alpha[i] != 0 && !color_used[colormap[i]]) {

            color_used[colormap[i]] = 1;

            nb_opaque_colors++;

        }

    }

    if (nb_opaque_colors == 0)

        return;

    j = 0;

    memset(color_used, 0, 16);

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

        if (alpha[i] != 0) {

            if (!color_used[colormap[i]])  {

                level = level_map[nb_opaque_colors - 1][j];

                r = (((subtitle_color >> 16) & 0xff) * level) >> 8;

                g = (((subtitle_color >> 8) & 0xff) * level) >> 8;

                b = (((subtitle_color >> 0) & 0xff) * level) >> 8;

                rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24);

                color_used[colormap[i]] = (i + 1);

                j++;

            } else {

                rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |

                                    ((alpha[i] * 17) << 24);

            }

        }

    }

}


int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice)

{

    MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = first_slice ? h->mmco : mmco_temp;

    int mmco_index = 0, i;

    assert(h->long_ref_count + h->short_ref_count <= h->sps.ref_frame_count);

    if (h->short_ref_count &&

        h->long_ref_count + h->short_ref_count == h->sps.ref_frame_count &&

        !(FIELD_PICTURE(h) && !h->first_field && h->cur_pic_ptr->reference)) {

        mmco[0].opcode        = MMCO_SHORT2UNUSED;

        mmco[0].short_pic_num = h->short_ref[h->short_ref_count - 1]->frame_num;

        mmco_index            = 1;

        if (FIELD_PICTURE(h)) {

            mmco[0].short_pic_num *= 2;

            mmco[1].opcode         = MMCO_SHORT2UNUSED;

            mmco[1].short_pic_num  = mmco[0].short_pic_num + 1;

            mmco_index             = 2;

        }

    }

    if (first_slice) {

        h->mmco_index = mmco_index;

    } else if (!first_slice && mmco_index >= 0 &&

               (mmco_index != h->mmco_index ||

                (i = check_opcodes(h->mmco, mmco_temp, mmco_index)))) {

        av_log(h->avctx, AV_LOG_ERROR,

               "Inconsistent MMCO state between slices [%d, %d, %d]\n",

               mmco_index, h->mmco_index, i);

        return AVERROR_INVALIDDATA;

    }

    return 0;

}


ImgReSampleContext *img_resample_full_init(int owidth, int oheight,

                                      int iwidth, int iheight,

                                      int topBand, int bottomBand,

        int leftBand, int rightBand,

        int padtop, int padbottom,

        int padleft, int padright)

{

    ImgReSampleContext *s;

    s = av_mallocz(sizeof(ImgReSampleContext));

    if (!s)

    s->line_buf = av_mallocz(owidth * (LINE_BUF_HEIGHT + NB_TAPS));

    if (!s->line_buf)

        goto fail;

    s->owidth = owidth;

    s->oheight = oheight;

    s->iwidth = iwidth;

    s->iheight = iheight;

    s->topBand = topBand;

    s->bottomBand = bottomBand;

    s->leftBand = leftBand;

    s->rightBand = rightBand;

    s->padtop = padtop;

    s->padbottom = padbottom;

    s->padleft = padleft;

    s->padright = padright;

    s->pad_owidth = owidth - (padleft + padright);

    s->pad_oheight = oheight - (padtop + padbottom);

    s->h_incr = ((iwidth - leftBand - rightBand) * POS_FRAC) / s->pad_owidth;

    s->v_incr = ((iheight - topBand - bottomBand) * POS_FRAC) / s->pad_oheight;

    av_build_filter(&s->h_filters[0][0], (float) s->pad_owidth  /

            (float) (iwidth - leftBand - rightBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);

    av_build_filter(&s->v_filters[0][0], (float) s->pad_oheight /

            (float) (iheight - topBand - bottomBand), NB_TAPS, NB_PHASES, 1<<FILTER_BITS, 0);

    return s;

fail:

    av_free(s);

}


static abi_long do_socketcall(int num, abi_ulong vptr)

{

    static const unsigned ac[] = { /* number of arguments per call */

        [SOCKOP_socket] = 3,      /* domain, type, protocol */

        [SOCKOP_bind] = 3,        /* sockfd, addr, addrlen */

        [SOCKOP_connect] = 3,     /* sockfd, addr, addrlen */

        [SOCKOP_listen] = 2,      /* sockfd, backlog */

        [SOCKOP_accept] = 3,      /* sockfd, addr, addrlen */

        [SOCKOP_accept4] = 4,     /* sockfd, addr, addrlen, flags */

        [SOCKOP_getsockname] = 3, /* sockfd, addr, addrlen */

        [SOCKOP_getpeername] = 3, /* sockfd, addr, addrlen */

        [SOCKOP_socketpair] = 4,  /* domain, type, protocol, tab */

        [SOCKOP_send] = 4,        /* sockfd, msg, len, flags */

        [SOCKOP_recv] = 4,        /* sockfd, msg, len, flags */

        [SOCKOP_sendto] = 6,      /* sockfd, msg, len, flags, addr, addrlen */

        [SOCKOP_recvfrom] = 6,    /* sockfd, msg, len, flags, addr, addrlen */

        [SOCKOP_shutdown] = 2,    /* sockfd, how */

        [SOCKOP_sendmsg] = 3,     /* sockfd, msg, flags */

        [SOCKOP_recvmsg] = 3,     /* sockfd, msg, flags */

        [SOCKOP_sendmmsg] = 4,    /* sockfd, msgvec, vlen, flags */

        [SOCKOP_recvmmsg] = 4,    /* sockfd, msgvec, vlen, flags */

        [SOCKOP_setsockopt] = 5,  /* sockfd, level, optname, optval, optlen */

        [SOCKOP_getsockopt] = 5,  /* sockfd, level, optname, optval, optlen */

    };

    abi_long a[6]; /* max 6 args */

    /* first, collect the arguments in a[] according to ac[] */

    if (num >= 0 && num < ARRAY_SIZE(ac)) {

        unsigned i;

        assert(ARRAY_SIZE(a) >= ac[num]); /* ensure we have space for args */

        for (i = 0; i < ac[num]; ++i) {

            if (get_user_ual(a[i], vptr + i * sizeof(abi_long)) != 0) {

                return -TARGET_EFAULT;

            }

        }

    }

    /* now when we have the args, actually handle the call */

    switch (num) {

    case SOCKOP_socket: /* domain, type, protocol */

        return do_socket(a[0], a[1], a[2]);

    case SOCKOP_bind: /* sockfd, addr, addrlen */

        return do_bind(a[0], a[1], a[2]);

    case SOCKOP_connect: /* sockfd, addr, addrlen */

        return do_connect(a[0], a[1], a[2]);

    case SOCKOP_listen: /* sockfd, backlog */

        return get_errno(listen(a[0], a[1]));

    case SOCKOP_accept: /* sockfd, addr, addrlen */

        return do_accept4(a[0], a[1], a[2], 0);

    case SOCKOP_accept4: /* sockfd, addr, addrlen, flags */

        return do_accept4(a[0], a[1], a[2], a[3]);

    case SOCKOP_getsockname: /* sockfd, addr, addrlen */

        return do_getsockname(a[0], a[1], a[2]);

    case SOCKOP_getpeername: /* sockfd, addr, addrlen */

        return do_getpeername(a[0], a[1], a[2]);

    case SOCKOP_socketpair: /* domain, type, protocol, tab */

        return do_socketpair(a[0], a[1], a[2], a[3]);

    case SOCKOP_send: /* sockfd, msg, len, flags */

        return do_sendto(a[0], a[1], a[2], a[3], 0, 0);

    case SOCKOP_recv: /* sockfd, msg, len, flags */

        return do_recvfrom(a[0], a[1], a[2], a[3], 0, 0);

    case SOCKOP_sendto: /* sockfd, msg, len, flags, addr, addrlen */

        return do_sendto(a[0], a[1], a[2], a[3], a[4], a[5]);

    case SOCKOP_recvfrom: /* sockfd, msg, len, flags, addr, addrlen */

        return do_recvfrom(a[0], a[1], a[2], a[3], a[4], a[5]);

    case SOCKOP_shutdown: /* sockfd, how */

        return get_errno(shutdown(a[0], a[1]));

    case SOCKOP_sendmsg: /* sockfd, msg, flags */

        return do_sendrecvmsg(a[0], a[1], a[2], 1);

    case SOCKOP_recvmsg: /* sockfd, msg, flags */

        return do_sendrecvmsg(a[0], a[1], a[2], 0);

    case SOCKOP_sendmmsg: /* sockfd, msgvec, vlen, flags */

        return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 1);

    case SOCKOP_recvmmsg: /* sockfd, msgvec, vlen, flags */

        return do_sendrecvmmsg(a[0], a[1], a[2], a[3], 0);

    case SOCKOP_setsockopt: /* sockfd, level, optname, optval, optlen */

        return do_setsockopt(a[0], a[1], a[2], a[3], a[4]);

    case SOCKOP_getsockopt: /* sockfd, level, optname, optval, optlen */

        return do_getsockopt(a[0], a[1], a[2], a[3], a[4]);

    default:

        gemu_log("Unsupported socketcall: %d\n", num);

        return -TARGET_ENOSYS;

    }

}


static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,

                                                MemTxAttrs attrs,

                                                const uint8_t *buf,

                                                int len, hwaddr addr1,

                                                hwaddr l, MemoryRegion *mr)

{

    uint8_t *ptr;

    uint64_t val;

    MemTxResult result = MEMTX_OK;

    bool release_lock = false;

    for (;;) {

        if (!memory_access_is_direct(mr, true)) {

            release_lock |= prepare_mmio_access(mr);

            l = memory_access_size(mr, l, addr1);

            /* XXX: could force current_cpu to NULL to avoid

               potential bugs */

            switch (l) {

            case 8:

                /* 64 bit write access */

                val = ldq_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 8,

                                                       attrs);

                break;

            case 4:

                /* 32 bit write access */

                val = ldl_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 4,

                                                       attrs);

                break;

            case 2:

                /* 16 bit write access */

                val = lduw_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 2,

                                                       attrs);

                break;

            case 1:

                /* 8 bit write access */

                val = ldub_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 1,

                                                       attrs);

                break;

            default:

                abort();

            }

        } else {

            /* RAM case */

            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);

            memcpy(ptr, buf, l);

            invalidate_and_set_dirty(mr, addr1, l);

        }

        if (release_lock) {

            qemu_mutex_unlock_iothread();

            release_lock = false;

        }

        len -= l;

        buf += l;

        addr += l;

        if (!len) {

            break;

        }

        l = len;

        mr = address_space_translate(as, addr, &addr1, &l, true);

    }

    return result;

}