av_cold int ff_rate_control_init(MpegEncContext *s)

{

    RateControlContext *rcc = &s->rc_context;

    int i, res;

    static const char * const const_names[] = {

        "PI",

        "E",

        "iTex",

        "pTex",

        "tex",

        "mv",

        "fCode",

        "iCount",

        "mcVar",

        "var",

        "isI",

        "isP",

        "isB",

        "avgQP",

        "qComp",

#if 0

        "lastIQP",

        "lastPQP",

        "lastBQP",

        "nextNonBQP",

#endif

        "avgIITex",

        "avgPITex",

        "avgPPTex",

        "avgBPTex",

        "avgTex",

        NULL

    };

    static double (* const func1[])(void *, double) = {

        (void *)bits2qp,

        (void *)qp2bits,

        NULL

    };

    static const char * const func1_names[] = {

        "bits2qp",

        "qp2bits",

        NULL

    };

    emms_c();

    if (!s->avctx->rc_max_available_vbv_use && s->avctx->rc_buffer_size) {

        if (s->avctx->rc_max_rate) {

            s->avctx->rc_max_available_vbv_use = av_clipf(s->avctx->rc_max_rate/(s->avctx->rc_buffer_size*get_fps(s->avctx)), 1.0/3, 1.0);

        } else

            s->avctx->rc_max_available_vbv_use = 1.0;

    }

    res = av_expr_parse(&rcc->rc_eq_eval,

                        s->rc_eq ? s->rc_eq : "tex^qComp",

                        const_names, func1_names, func1,

                        NULL, NULL, 0, s->avctx);

    if (res < 0) {

        av_log(s->avctx, AV_LOG_ERROR, "Error parsing rc_eq \"%s\"\n", s->rc_eq);

        return res;

    }

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

        rcc->pred[i].coeff = FF_QP2LAMBDA * 7.0;

        rcc->pred[i].count = 1.0;

        rcc->pred[i].decay = 0.4;

        rcc->i_cplx_sum [i] =

        rcc->p_cplx_sum [i] =

        rcc->mv_bits_sum[i] =

        rcc->qscale_sum [i] =

        rcc->frame_count[i] = 1; // 1 is better because of 1/0 and such

        rcc->last_qscale_for[i] = FF_QP2LAMBDA * 5;

    }

    rcc->buffer_index = s->avctx->rc_initial_buffer_occupancy;

    if (!rcc->buffer_index)

        rcc->buffer_index = s->avctx->rc_buffer_size * 3 / 4;

    if (s->flags & CODEC_FLAG_PASS2) {

        int i;

        char *p;

        /* find number of pics */

        p = s->avctx->stats_in;

        for (i = -1; p; i++)

            p = strchr(p + 1, ';');

        i += s->max_b_frames;

        if (i <= 0 || i >= INT_MAX / sizeof(RateControlEntry))

            return -1;

        rcc->entry       = av_mallocz(i * sizeof(RateControlEntry));

        rcc->num_entries = i;

        /* init all to skipped p frames

         * (with b frames we might have a not encoded frame at the end FIXME) */

        for (i = 0; i < rcc->num_entries; i++) {

            RateControlEntry *rce = &rcc->entry[i];

            rce->pict_type  = rce->new_pict_type = AV_PICTURE_TYPE_P;

            rce->qscale     = rce->new_qscale    = FF_QP2LAMBDA * 2;

            rce->misc_bits  = s->mb_num + 10;

            rce->mb_var_sum = s->mb_num * 100;

        }

        /* read stats */

        p = s->avctx->stats_in;

        for (i = 0; i < rcc->num_entries - s->max_b_frames; i++) {

            RateControlEntry *rce;

            int picture_number;

            int e;

            char *next;

            next = strchr(p, ';');

            if (next) {

                (*next) = 0; // sscanf in unbelievably slow on looong strings // FIXME copy / do not write

                next++;

            }

            e = sscanf(p, " in:%d ", &picture_number);

            assert(picture_number >= 0);

            assert(picture_number < rcc->num_entries);

            rce = &rcc->entry[picture_number];

            e += sscanf(p, " in:%*d out:%*d type:%d q:%f itex:%d ptex:%d mv:%d misc:%d fcode:%d bcode:%d mc-var:%"SCNd64" var:%"SCNd64" icount:%d skipcount:%d hbits:%d",

                        &rce->pict_type, &rce->qscale, &rce->i_tex_bits, &rce->p_tex_bits,

                        &rce->mv_bits, &rce->misc_bits,

                        &rce->f_code, &rce->b_code,

                        &rce->mc_mb_var_sum, &rce->mb_var_sum,

                        &rce->i_count, &rce->skip_count, &rce->header_bits);

            if (e != 14) {

                av_log(s->avctx, AV_LOG_ERROR,

                       "statistics are damaged at line %d, parser out=%d\n",

                       i, e);

                return -1;

            }

            p = next;

        }

        if (init_pass2(s) < 0)

            return -1;

        // FIXME maybe move to end

        if ((s->flags & CODEC_FLAG_PASS2) && s->avctx->rc_strategy == FF_RC_STRATEGY_XVID) {

#if CONFIG_LIBXVID

            return ff_xvid_rate_control_init(s);

#else

            av_log(s->avctx, AV_LOG_ERROR,

                   "Xvid ratecontrol requires libavcodec compiled with Xvid support.\n");

            return -1;

#endif

        }

    }

    if (!(s->flags & CODEC_FLAG_PASS2)) {

        rcc->short_term_qsum   = 0.001;

        rcc->short_term_qcount = 0.001;

        rcc->pass1_rc_eq_output_sum = 0.001;

        rcc->pass1_wanted_bits      = 0.001;

        if (s->avctx->qblur > 1.0) {

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

            return -1;

        }

        /* init stuff with the user specified complexity */

        if (s->rc_initial_cplx) {

            for (i = 0; i < 60 * 30; i++) {

                double bits = s->rc_initial_cplx * (i / 10000.0 + 1.0) * s->mb_num;

                RateControlEntry rce;

                if (i % ((s->gop_size + 3) / 4) == 0)

                    rce.pict_type = AV_PICTURE_TYPE_I;

                else if (i % (s->max_b_frames + 1))

                    rce.pict_type = AV_PICTURE_TYPE_B;

                else

                    rce.pict_type = AV_PICTURE_TYPE_P;

                rce.new_pict_type = rce.pict_type;

                rce.mc_mb_var_sum = bits * s->mb_num / 100000;

                rce.mb_var_sum    = s->mb_num;

                rce.qscale    = FF_QP2LAMBDA * 2;

                rce.f_code    = 2;

                rce.b_code    = 1;

                rce.misc_bits = 1;

                if (s->pict_type == AV_PICTURE_TYPE_I) {

                    rce.i_count    = s->mb_num;

                    rce.i_tex_bits = bits;

                    rce.p_tex_bits = 0;

                    rce.mv_bits    = 0;

                } else {

                    rce.i_count    = 0; // FIXME we do know this approx

                    rce.i_tex_bits = 0;

                    rce.p_tex_bits = bits * 0.9;

                    rce.mv_bits    = bits * 0.1;

                }

                rcc->i_cplx_sum[rce.pict_type]  += rce.i_tex_bits * rce.qscale;

                rcc->p_cplx_sum[rce.pict_type]  += rce.p_tex_bits * rce.qscale;

                rcc->mv_bits_sum[rce.pict_type] += rce.mv_bits;

                rcc->frame_count[rce.pict_type]++;

                get_qscale(s, &rce, rcc->pass1_wanted_bits / rcc->pass1_rc_eq_output_sum, i);

                // FIXME misbehaves a little for variable fps

                rcc->pass1_wanted_bits += s->bit_rate / get_fps(s->avctx);

            }

        }

    }

    return 0;

}


void trace_event_set_vcpu_state_dynamic(CPUState *vcpu,

                                        TraceEvent *ev, bool state)

{

    TraceEventVCPUID vcpu_id;

    bool state_pre;

    assert(trace_event_get_state_static(ev));

    assert(trace_event_is_vcpu(ev));

    vcpu_id = trace_event_get_vcpu_id(ev);

    state_pre = test_bit(vcpu_id, vcpu->trace_dstate);

    if (state_pre != state) {

        if (state) {

            trace_events_enabled_count++;

            set_bit(vcpu_id, vcpu->trace_dstate);

            (*ev->dstate)++;

        } else {

            trace_events_enabled_count--;

            clear_bit(vcpu_id, vcpu->trace_dstate);

            (*ev->dstate)--;

        }

    }

}


static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)

{

    struct vmsvga_state_s *s = opaque;

    if (s->index >= SVGA_SCRATCH_BASE) {

        trace_vmware_scratch_write(s->index, value);

    } else if (s->index >= SVGA_PALETTE_BASE) {

        trace_vmware_palette_write(s->index, value);

    } else {

        trace_vmware_value_write(s->index, value);

    }

    switch (s->index) {

    case SVGA_REG_ID:

        if (value == SVGA_ID_2 || value == SVGA_ID_1 || value == SVGA_ID_0) {

            s->svgaid = value;

        }

        break;

    case SVGA_REG_ENABLE:

        s->enable = !!value;

        s->invalidated = 1;

        s->vga.hw_ops->invalidate(&s->vga);

        if (s->enable && s->config) {

            vga_dirty_log_stop(&s->vga);

        } else {

            vga_dirty_log_start(&s->vga);

        }

        break;

    case SVGA_REG_WIDTH:

        if (value <= SVGA_MAX_WIDTH) {

            s->new_width = value;

            s->invalidated = 1;

        } else {

            printf("%s: Bad width: %i\n", __func__, value);

        }

        break;

    case SVGA_REG_HEIGHT:

        if (value <= SVGA_MAX_HEIGHT) {

            s->new_height = value;

            s->invalidated = 1;

        } else {

            printf("%s: Bad height: %i\n", __func__, value);

        }

        break;

    case SVGA_REG_BITS_PER_PIXEL:

        if (value != 32) {

            printf("%s: Bad bits per pixel: %i bits\n", __func__, value);

            s->config = 0;

            s->invalidated = 1;

        }

        break;

    case SVGA_REG_CONFIG_DONE:

        if (value) {

            s->fifo = (uint32_t *) s->fifo_ptr;

            /* Check range and alignment.  */

            if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) {

                break;

            }

            if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) {

                break;

            }

            if (CMD(max) > SVGA_FIFO_SIZE) {

                break;

            }

            if (CMD(max) < CMD(min) + 10 * 1024) {

                break;

            }

            vga_dirty_log_stop(&s->vga);

        }

        s->config = !!value;

        break;

    case SVGA_REG_SYNC:

        s->syncing = 1;

        vmsvga_fifo_run(s); /* Or should we just wait for update_display? */

        break;

    case SVGA_REG_GUEST_ID:

        s->guest = value;

#ifdef VERBOSE

        if (value >= GUEST_OS_BASE && value < GUEST_OS_BASE +

            ARRAY_SIZE(vmsvga_guest_id)) {

            printf("%s: guest runs %s.\n", __func__,

                   vmsvga_guest_id[value - GUEST_OS_BASE]);

        }

#endif

        break;

    case SVGA_REG_CURSOR_ID:

        s->cursor.id = value;

        break;

    case SVGA_REG_CURSOR_X:

        s->cursor.x = value;

        break;

    case SVGA_REG_CURSOR_Y:

        s->cursor.y = value;

        break;

    case SVGA_REG_CURSOR_ON:

        s->cursor.on |= (value == SVGA_CURSOR_ON_SHOW);

        s->cursor.on &= (value != SVGA_CURSOR_ON_HIDE);

#ifdef HW_MOUSE_ACCEL

        if (value <= SVGA_CURSOR_ON_SHOW) {

            dpy_mouse_set(s->vga.con, s->cursor.x, s->cursor.y, s->cursor.on);

        }

#endif

        break;

    case SVGA_REG_DEPTH:

    case SVGA_REG_MEM_REGS:

    case SVGA_REG_NUM_DISPLAYS:

    case SVGA_REG_PITCHLOCK:

    case SVGA_PALETTE_BASE ... SVGA_PALETTE_END:

        break;

    default:

        if (s->index >= SVGA_SCRATCH_BASE &&

                s->index < SVGA_SCRATCH_BASE + s->scratch_size) {

            s->scratch[s->index - SVGA_SCRATCH_BASE] = value;

            break;

        }

        printf("%s: Bad register %02x\n", __func__, s->index);

    }

}


int main (int argc, char **argv)

{

    int ret = 0, got_frame;

    if (argc != 4) {

        fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"

                "API example program to show how to read frames from an input file.\n"

                "This program reads frames from a file, decodes them, and writes decoded\n"

                "video frames to a rawvideo file named video_output_file, and decoded\n"

                "audio frames to a rawaudio file named audio_output_file.\n"

                "\n", argv[0]);

        exit(1);

    }

    src_filename = argv[1];

    video_dst_filename = argv[2];

    audio_dst_filename = argv[3];

    /* register all formats and codecs */

    av_register_all();

    /* open input file, and allocate format context */

    if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {

        fprintf(stderr, "Could not open source file %s\n", src_filename);

        exit(1);

    }

    /* retrieve stream information */

    if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {

        fprintf(stderr, "Could not find stream information\n");

        exit(1);

    }

    if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {

        video_stream = fmt_ctx->streams[video_stream_idx];

        video_dec_ctx = video_stream->codec;

        video_dst_file = fopen(video_dst_filename, "wb");

        if (!video_dst_file) {

            fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);

            ret = 1;

            goto end;

        }

        /* allocate image where the decoded image will be put */

        ret = av_image_alloc(video_dst_data, video_dst_linesize,

                             video_dec_ctx->width, video_dec_ctx->height,

                             video_dec_ctx->pix_fmt, 1);

        if (ret < 0) {

            fprintf(stderr, "Could not allocate raw video buffer\n");

            goto end;

        }

        video_dst_bufsize = ret;

    }

    if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {

        int nb_planes;

        audio_stream = fmt_ctx->streams[audio_stream_idx];

        audio_dec_ctx = audio_stream->codec;

        audio_dst_file = fopen(audio_dst_filename, "wb");

        if (!audio_dst_file) {

            fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);

            ret = 1;

            goto end;

        }

        nb_planes = av_sample_fmt_is_planar(audio_dec_ctx->sample_fmt) ?

            audio_dec_ctx->channels : 1;

        audio_dst_data = av_mallocz(sizeof(uint8_t *) * nb_planes);

        if (!audio_dst_data) {

            fprintf(stderr, "Could not allocate audio data buffers\n");

            ret = AVERROR(ENOMEM);

            goto end;

        }

    }

    /* dump input information to stderr */

    av_dump_format(fmt_ctx, 0, src_filename, 0);

    if (!audio_stream && !video_stream) {

        fprintf(stderr, "Could not find audio or video stream in the input, aborting\n");

        ret = 1;

        goto end;

    }

    frame = avcodec_alloc_frame();

    if (!frame) {

        fprintf(stderr, "Could not allocate frame\n");

        ret = AVERROR(ENOMEM);

        goto end;

    }

    /* initialize packet, set data to NULL, let the demuxer fill it */

    av_init_packet(&pkt);

    pkt.data = NULL;

    pkt.size = 0;

    if (video_stream)

        printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);

    if (audio_stream)

        printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);

    /* read frames from the file */

    while (av_read_frame(fmt_ctx, &pkt) >= 0)

        decode_packet(&got_frame, 0);

    /* flush cached frames */

    pkt.data = NULL;

    pkt.size = 0;

    do {

        decode_packet(&got_frame, 1);

    } while (got_frame);

    printf("Demuxing succeeded.\n");

    if (video_stream) {

        printf("Play the output video file with the command:\n"

               "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",

               av_get_pix_fmt_name(video_dec_ctx->pix_fmt), video_dec_ctx->width, video_dec_ctx->height,

               video_dst_filename);

    }

    if (audio_stream) {

        const char *fmt;

        if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt)) < 0)

            goto end;

        printf("Play the output audio file with the command:\n"

               "ffplay -f %s -ac %d -ar %d %s\n",

               fmt, audio_dec_ctx->channels, audio_dec_ctx->sample_rate,

               audio_dst_filename);

    }

end:

    if (video_dec_ctx)

        avcodec_close(video_dec_ctx);

    if (audio_dec_ctx)

        avcodec_close(audio_dec_ctx);

    avformat_close_input(&fmt_ctx);

    if (video_dst_file)

        fclose(video_dst_file);

    if (audio_dst_file)

        fclose(audio_dst_file);

    av_free(frame);

    av_free(video_dst_data[0]);

    av_free(audio_dst_data);

    return ret < 0;

}


static av_cold int truemotion1_decode_init(AVCodecContext *avctx)

{

    TrueMotion1Context *s = avctx->priv_data;

    s->avctx = avctx;

    // FIXME: it may change ?

//    if (avctx->bits_per_sample == 24)

//        avctx->pix_fmt = AV_PIX_FMT_RGB24;

//    else

//        avctx->pix_fmt = AV_PIX_FMT_RGB555;

    s->frame.data[0] = NULL;

    /* there is a vertical predictor for each pixel in a line; each vertical

     * predictor is 0 to start with */

    av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));

    return 0;

}


static int h264_export_frame_props(H264Context *h)

{

    const SPS *sps = h->ps.sps;

    H264Picture *cur = h->cur_pic_ptr;

    cur->f->interlaced_frame = 0;

    cur->f->repeat_pict      = 0;

    /* Signal interlacing information externally. */

    /* Prioritize picture timing SEI information over used

     * decoding process if it exists. */

    if (sps->pic_struct_present_flag) {

        H264SEIPictureTiming *pt = &h->sei.picture_timing;

        switch (pt->pic_struct) {

        case SEI_PIC_STRUCT_FRAME:

            break;

        case SEI_PIC_STRUCT_TOP_FIELD:

        case SEI_PIC_STRUCT_BOTTOM_FIELD:

            cur->f->interlaced_frame = 1;

            break;

        case SEI_PIC_STRUCT_TOP_BOTTOM:

        case SEI_PIC_STRUCT_BOTTOM_TOP:

            if (FIELD_OR_MBAFF_PICTURE(h))

                cur->f->interlaced_frame = 1;

            else

                // try to flag soft telecine progressive

                cur->f->interlaced_frame = h->prev_interlaced_frame;

            break;

        case SEI_PIC_STRUCT_TOP_BOTTOM_TOP:

        case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:

            /* Signal the possibility of telecined film externally

             * (pic_struct 5,6). From these hints, let the applications

             * decide if they apply deinterlacing. */

            cur->f->repeat_pict = 1;

            break;

        case SEI_PIC_STRUCT_FRAME_DOUBLING:

            cur->f->repeat_pict = 2;

            break;

        case SEI_PIC_STRUCT_FRAME_TRIPLING:

            cur->f->repeat_pict = 4;

            break;

        }

        if ((pt->ct_type & 3) &&

            pt->pic_struct <= SEI_PIC_STRUCT_BOTTOM_TOP)

            cur->f->interlaced_frame = (pt->ct_type & (1 << 1)) != 0;

    } else {

        /* Derive interlacing flag from used decoding process. */

        cur->f->interlaced_frame = FIELD_OR_MBAFF_PICTURE(h);

    }

    h->prev_interlaced_frame = cur->f->interlaced_frame;

    if (cur->field_poc[0] != cur->field_poc[1]) {

        /* Derive top_field_first from field pocs. */

        cur->f->top_field_first = cur->field_poc[0] < cur->field_poc[1];

    } else {

        if (cur->f->interlaced_frame || sps->pic_struct_present_flag) {

            /* Use picture timing SEI information. Even if it is a

             * information of a past frame, better than nothing. */

            if (h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM ||

                h->sei.picture_timing.pic_struct == SEI_PIC_STRUCT_TOP_BOTTOM_TOP)

                cur->f->top_field_first = 1;

            else

                cur->f->top_field_first = 0;

        } else {

            /* Most likely progressive */

            cur->f->top_field_first = 0;

        }

    }

    if (h->sei.frame_packing.present &&

        h->sei.frame_packing.arrangement_type >= 0 &&

        h->sei.frame_packing.arrangement_type <= 6 &&

        h->sei.frame_packing.content_interpretation_type > 0 &&

        h->sei.frame_packing.content_interpretation_type < 3) {

        H264SEIFramePacking *fp = &h->sei.frame_packing;

        AVStereo3D *stereo = av_stereo3d_create_side_data(cur->f);

        if (!stereo)

            return AVERROR(ENOMEM);

        switch (fp->arrangement_type) {

        case 0:

            stereo->type = AV_STEREO3D_CHECKERBOARD;

            break;

        case 1:

            stereo->type = AV_STEREO3D_COLUMNS;

            break;

        case 2:

            stereo->type = AV_STEREO3D_LINES;

            break;

        case 3:

            if (fp->quincunx_subsampling)

                stereo->type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;

            else

                stereo->type = AV_STEREO3D_SIDEBYSIDE;

            break;

        case 4:

            stereo->type = AV_STEREO3D_TOPBOTTOM;

            break;

        case 5:

            stereo->type = AV_STEREO3D_FRAMESEQUENCE;

            break;

        case 6:

            stereo->type = AV_STEREO3D_2D;

            break;

        }

        if (fp->content_interpretation_type == 2)

            stereo->flags = AV_STEREO3D_FLAG_INVERT;

    }

    if (h->sei.display_orientation.present &&

        (h->sei.display_orientation.anticlockwise_rotation ||

         h->sei.display_orientation.hflip ||

         h->sei.display_orientation.vflip)) {

        H264SEIDisplayOrientation *o = &h->sei.display_orientation;

        double angle = o->anticlockwise_rotation * 360 / (double) (1 << 16);

        AVFrameSideData *rotation = av_frame_new_side_data(cur->f,

                                                           AV_FRAME_DATA_DISPLAYMATRIX,

                                                           sizeof(int32_t) * 9);

        if (!rotation)

            return AVERROR(ENOMEM);

        av_display_rotation_set((int32_t *)rotation->data, angle);

        av_display_matrix_flip((int32_t *)rotation->data,

                               o->hflip, o->vflip);

    }

    if (h->sei.afd.present) {

        AVFrameSideData *sd = av_frame_new_side_data(cur->f, AV_FRAME_DATA_AFD,

                                                     sizeof(uint8_t));

        if (!sd)

            return AVERROR(ENOMEM);

        *sd->data = h->sei.afd.active_format_description;

        h->sei.afd.present = 0;

    }

    if (h->sei.a53_caption.a53_caption) {

        H264SEIA53Caption *a53 = &h->sei.a53_caption;

        AVFrameSideData *sd = av_frame_new_side_data(cur->f,

                                                     AV_FRAME_DATA_A53_CC,

                                                     a53->a53_caption_size);

        if (!sd)

            return AVERROR(ENOMEM);

        memcpy(sd->data, a53->a53_caption, a53->a53_caption_size);

        av_freep(&a53->a53_caption);

        a53->a53_caption_size = 0;

    }

    return 0;

}


static int colo_packet_compare_icmp(Packet *spkt, Packet *ppkt)

{

    int network_header_length = ppkt->ip->ip_hl * 4;

    trace_colo_compare_main("compare icmp");

    /*

     * Because of ppkt and spkt are both in the same connection,

     * The ppkt's src ip, dst ip, src port, dst port, ip_proto all are

     * same with spkt. In addition, IP header's Identification is a random

     * field, we can handle it in IP fragmentation function later.

     * COLO just concern the response net packet payload from primary guest

     * and secondary guest are same or not, So we ignored all IP header include

     * other field like TOS,TTL,IP Checksum. we only need to compare

     * the ip payload here.

     */

    if (colo_packet_compare_common(ppkt, spkt,

                                   network_header_length + ETH_HLEN)) {

        trace_colo_compare_icmp_miscompare("primary pkt size",

                                           ppkt->size);

        trace_colo_compare_icmp_miscompare("Secondary pkt size",

                                           spkt->size);

        if (trace_event_get_state(TRACE_COLO_COMPARE_MISCOMPARE)) {

            qemu_hexdump((char *)ppkt->data, stderr, "colo-compare pri pkt",

                         ppkt->size);

            qemu_hexdump((char *)spkt->data, stderr, "colo-compare sec pkt",

                         spkt->size);

        }

        return -1;

    } else {

        return 0;

    }

}


static int caca_write_header(AVFormatContext *s)

{

    CACAContext *c = s->priv_data;

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

    AVCodecContext *encctx = st->codec;

    int ret, bpp;

    c->ctx = s;

    if (c->list_drivers) {

        list_drivers(c);

        return AVERROR_EXIT;

    }

    if (c->list_dither) {

        if (!strcmp(c->list_dither, "colors")) {

            list_dither_color(c);

        } else if (!strcmp(c->list_dither, "charsets")) {

            list_dither_charset(c);

        } else if (!strcmp(c->list_dither, "algorithms")) {

            list_dither_algorithm(c);

        } else if (!strcmp(c->list_dither, "antialiases")) {

            list_dither_antialias(c);

        } else {

            av_log(s, AV_LOG_ERROR,

                   "Invalid argument '%s', for 'list_dither' option\n"

                   "Argument must be one of 'algorithms, 'antialiases', 'charsets', 'colors'\n",

                   c->list_dither);

            return AVERROR(EINVAL);

        }

        return AVERROR_EXIT;

    }

    if (   s->nb_streams > 1

        || encctx->codec_type != AVMEDIA_TYPE_VIDEO

        || encctx->codec_id   != CODEC_ID_RAWVIDEO) {

        av_log(s, AV_LOG_ERROR, "Only supports one rawvideo stream\n");

        return AVERROR(EINVAL);

    }

    if (encctx->pix_fmt != PIX_FMT_RGB24) {

        av_log(s, AV_LOG_ERROR,

               "Unsupported pixel format '%s', choose rgb24\n",

               av_get_pix_fmt_name(encctx->pix_fmt));

        return AVERROR(EINVAL);

    }

    c->canvas = caca_create_canvas(c->window_width, c->window_height);

    if (!c->canvas) {

        av_log(s, AV_LOG_ERROR, "Failed to create canvas\n");

        return AVERROR(errno);

    }

    c->display = caca_create_display_with_driver(c->canvas, c->driver);

    if (!c->display) {

        av_log(s, AV_LOG_ERROR, "Failed to create display\n");

        list_drivers(c);

        caca_free_canvas(c->canvas);

        return AVERROR(errno);

    }

    if (!c->window_width || !c->window_height) {

        c->window_width  = caca_get_canvas_width(c->canvas);

        c->window_height = caca_get_canvas_height(c->canvas);

    }

    bpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[encctx->pix_fmt]);

    c->dither = caca_create_dither(bpp, encctx->width, encctx->height,

                                   bpp / 8 * encctx->width,

                                   0x0000ff, 0x00ff00, 0xff0000, 0);

    if (!c->dither) {

        av_log(s, AV_LOG_ERROR, "Failed to create dither\n");

        ret =  AVERROR(errno);

        goto fail;

    }

#define CHECK_DITHER_OPT(opt)                                           \

    if (caca_set_dither_##opt(c->dither, c->opt) < 0)  {                \

        ret = AVERROR(errno);                                           \

        av_log(s, AV_LOG_ERROR, "Failed to set value '%s' for option '%s'\n", \

               c->opt, #opt);                                           \

        goto fail;                                                      \

    }

    CHECK_DITHER_OPT(algorithm);

    CHECK_DITHER_OPT(antialias);

    CHECK_DITHER_OPT(charset);

    CHECK_DITHER_OPT(color);

    if (!c->window_title)

        c->window_title = av_strdup(s->filename);

    caca_set_display_title(c->display, c->window_title);

    caca_set_display_time(c->display, av_rescale_q(1, st->codec->time_base, AV_TIME_BASE_Q));

    return 0;

fail:

    caca_write_trailer(s);

    return ret;

}


static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment)

{

    int i, length;

    segment->nb_index_entries = avio_rb32(pb);

    length = avio_rb32(pb);

    if (!(segment->temporal_offset_entries=av_calloc(segment->nb_index_entries, sizeof(*segment->temporal_offset_entries))) ||

        !(segment->flag_entries          = av_calloc(segment->nb_index_entries, sizeof(*segment->flag_entries))) ||

        !(segment->stream_offset_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->stream_offset_entries)))) {

        av_freep(&segment->temporal_offset_entries);

        av_freep(&segment->flag_entries);

        return AVERROR(ENOMEM);

    }

    for (i = 0; i < segment->nb_index_entries; i++) {

        if(avio_feof(pb))

        segment->temporal_offset_entries[i] = avio_r8(pb);

        avio_r8(pb);                                        /* KeyFrameOffset */

        segment->flag_entries[i] = avio_r8(pb);

        segment->stream_offset_entries[i] = avio_rb64(pb);

        avio_skip(pb, length - 11);

    }

    return 0;

}


uint64_t hbitmap_serialization_granularity(const HBitmap *hb)

{

    /* Must hold true so that the shift below is defined

     * (ld(64) == 6, i.e. 1 << 6 == 64) */

    assert(hb->granularity < 64 - 6);

    /* Require at least 64 bit granularity to be safe on both 64 bit and 32 bit

     * hosts. */

    return UINT64_C(64) << hb->granularity;

}


void helper_store_sdr1(CPUPPCState *env, target_ulong val)

{

    ppc_store_sdr1(env, val);

}


static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)

{

    VP56RangeCoder *c = &s->c;

    int part1_size, hscale, vscale, i, j, ret;

    int width  = s->avctx->width;

    int height = s->avctx->height;

    s->profile = (buf[0] >> 1) & 7;

    if (s->profile > 1) {

        avpriv_request_sample(s->avctx, "Unknown profile %d", s->profile);

        return AVERROR_INVALIDDATA;

    }

    s->keyframe  = !(buf[0] & 1);

    s->invisible = 0;

    part1_size   = AV_RL24(buf) >> 4;

    buf      += 4 - s->profile;

    buf_size -= 4 - s->profile;

    memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));

    ff_vp56_init_range_decoder(c, buf, part1_size);

    buf      += part1_size;

    buf_size -= part1_size;

    /* A. Dimension information (keyframes only) */

    if (s->keyframe) {

        width  = vp8_rac_get_uint(c, 12);

        height = vp8_rac_get_uint(c, 12);

        hscale = vp8_rac_get_uint(c, 2);

        vscale = vp8_rac_get_uint(c, 2);

        if (hscale || vscale)

            avpriv_request_sample(s->avctx, "Upscaling");

        s->update_golden = s->update_altref = VP56_FRAME_CURRENT;

        vp78_reset_probability_tables(s);

        memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,

               sizeof(s->prob->pred16x16));

        memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,

               sizeof(s->prob->pred8x8c));

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

            memcpy(s->prob->mvc[i], vp7_mv_default_prob[i],

                   sizeof(vp7_mv_default_prob[i]));

        memset(&s->segmentation, 0, sizeof(s->segmentation));

        memset(&s->lf_delta, 0, sizeof(s->lf_delta));

        memcpy(s->prob[0].scan, zigzag_scan, sizeof(s->prob[0].scan));

    }

    if (s->keyframe || s->profile > 0)

        memset(s->inter_dc_pred, 0 , sizeof(s->inter_dc_pred));

    /* B. Decoding information for all four macroblock-level features */

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

        s->feature_enabled[i] = vp8_rac_get(c);

        if (s->feature_enabled[i]) {

             s->feature_present_prob[i] = vp8_rac_get_uint(c, 8);

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

                 s->feature_index_prob[i][j] =

                     vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;

             if (vp7_feature_value_size[i])

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

                     s->feature_value[i][j] =

                         vp8_rac_get(c) ? vp8_rac_get_uint(c, vp7_feature_value_size[s->profile][i]) : 0;

        }

    }

    s->segmentation.enabled    = 0;

    s->segmentation.update_map = 0;

    s->lf_delta.enabled        = 0;

    s->num_coeff_partitions = 1;

    ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size);

    if (!s->macroblocks_base || /* first frame */

        width != s->avctx->width || height != s->avctx->height ||

        (width + 15) / 16 != s->mb_width || (height + 15) / 16 != s->mb_height) {

        if ((ret = vp7_update_dimensions(s, width, height)) < 0)

            return ret;

    }

    /* C. Dequantization indices */

    vp7_get_quants(s);

    /* D. Golden frame update flag (a Flag) for interframes only */

    if (!s->keyframe) {

        s->update_golden = vp8_rac_get(c) ? VP56_FRAME_CURRENT : VP56_FRAME_NONE;

        s->sign_bias[VP56_FRAME_GOLDEN] = 0;

    }

    s->update_last          = 1;

    s->update_probabilities = 1;

    s->fade_present         = 1;

    if (s->profile > 0) {

        s->update_probabilities = vp8_rac_get(c);

        if (!s->update_probabilities)

            s->prob[1] = s->prob[0];

        if (!s->keyframe)

            s->fade_present = vp8_rac_get(c);

    }

    /* E. Fading information for previous frame */

    if (s->fade_present && vp8_rac_get(c)) {

        if ((ret = vp7_fade_frame(s ,c)) < 0)

            return ret;

    }

    /* F. Loop filter type */

    if (!s->profile)

        s->filter.simple = vp8_rac_get(c);

    /* G. DCT coefficient ordering specification */

    if (vp8_rac_get(c))

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

            s->prob[0].scan[i] = zigzag_scan[vp8_rac_get_uint(c, 4)];

    /* H. Loop filter levels  */

    if (s->profile > 0)

        s->filter.simple = vp8_rac_get(c);

    s->filter.level     = vp8_rac_get_uint(c, 6);

    s->filter.sharpness = vp8_rac_get_uint(c, 3);

    /* I. DCT coefficient probability update; 13.3 Token Probability Updates */

    vp78_update_probability_tables(s);

    s->mbskip_enabled = 0;

    /* J. The remaining frame header data occurs ONLY FOR INTERFRAMES */

    if (!s->keyframe) {

        s->prob->intra  = vp8_rac_get_uint(c, 8);

        s->prob->last   = vp8_rac_get_uint(c, 8);

        vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP7_MVC_SIZE);

    }

    return 0;

}


static inline void mc_dir_part(H264Context *h, Picture *pic, int n, int square, int chroma_height, int delta, int list,

                           uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,

                           int src_x_offset, int src_y_offset,

                           qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op){

    MpegEncContext * const s = &h->s;

    const int mx= h->mv_cache[list][ scan8[n] ][0] + src_x_offset*8;

    const int my= h->mv_cache[list][ scan8[n] ][1] + src_y_offset*8;

    const int luma_xy= (mx&3) + ((my&3)<<2);

    uint8_t * src_y = pic->data[0] + (mx>>2) + (my>>2)*s->linesize;

    uint8_t * src_cb= pic->data[1] + (mx>>3) + (my>>3)*s->uvlinesize;

    uint8_t * src_cr= pic->data[2] + (mx>>3) + (my>>3)*s->uvlinesize;

    int extra_width= (s->flags&CODEC_FLAG_EMU_EDGE) ? 0 : 16; //FIXME increase edge?, IMHO not worth it

    int extra_height= extra_width;

    int emu=0;

    const int full_mx= mx>>2;

    const int full_my= my>>2;

    const int pic_width  = 16*s->mb_width;

    const int pic_height = 16*s->mb_height;

    assert(pic->data[0]);

    if(mx&7) extra_width -= 3;

    if(my&7) extra_height -= 3;

    if(   full_mx < 0-extra_width

       || full_my < 0-extra_height

       || full_mx + 16/*FIXME*/ > pic_width + extra_width

       || full_my + 16/*FIXME*/ > pic_height + extra_height){

        ff_emulated_edge_mc(s->edge_emu_buffer, src_y - 2 - 2*s->linesize, s->linesize, 16+5, 16+5/*FIXME*/, full_mx-2, full_my-2, pic_width, pic_height);

            src_y= s->edge_emu_buffer + 2 + 2*s->linesize;

        emu=1;

    }

    qpix_op[luma_xy](dest_y, src_y, s->linesize); //FIXME try variable height perhaps?

    if(!square){

        qpix_op[luma_xy](dest_y + delta, src_y + delta, s->linesize);

    }

    if(s->flags&CODEC_FLAG_GRAY) return;

    if(emu){

        ff_emulated_edge_mc(s->edge_emu_buffer, src_cb, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);

            src_cb= s->edge_emu_buffer;

    }

    chroma_op(dest_cb, src_cb, s->uvlinesize, chroma_height, mx&7, my&7);

    if(emu){

        ff_emulated_edge_mc(s->edge_emu_buffer, src_cr, s->uvlinesize, 9, 9/*FIXME*/, (mx>>3), (my>>3), pic_width>>1, pic_height>>1);

            src_cr= s->edge_emu_buffer;

    }

    chroma_op(dest_cr, src_cr, s->uvlinesize, chroma_height, mx&7, my&7);

}


static int encode_frame(AVCodecContext *avctx, uint8_t *buf,

                        int buf_size, void *data)

{

    AVFrame *pic = data;

    int i, j;

    int aligned_width = FFALIGN(avctx->width, 64);

    uint8_t *src_line;

    uint8_t *dst = buf;

    if (buf_size < 4 * aligned_width * avctx->height) {

        av_log(avctx, AV_LOG_ERROR, "output buffer too small\n");

        return AVERROR(ENOMEM);

    }

    avctx->coded_frame->reference = 0;

    avctx->coded_frame->key_frame = 1;

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    src_line = pic->data[0];

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

        uint16_t *src = (uint16_t *)src_line;

        for (j = 0; j < avctx->width; j++) {

            uint32_t pixel;

            uint16_t r = *src++ >> 6;

            uint16_t g = *src++ >> 6;

            uint16_t b = *src++ >> 4;

            if (avctx->codec_id == CODEC_ID_R210)

                pixel = (r << 20) | (g << 10) | b >> 2;

            else

                pixel = (r << 22) | (g << 12) | b;

            if (avctx->codec_id == CODEC_ID_AVRP)

                bytestream_put_le32(&dst, pixel);

            else

                bytestream_put_be32(&dst, pixel);

        }

        dst += (aligned_width - avctx->width) * 4;

        src_line += pic->linesize[0];

    }

    return 4 * aligned_width * avctx->height;

}


static inline void gen_st32(TCGv val, TCGv addr, int index)

{

    tcg_gen_qemu_st32(val, addr, index);

    dead_tmp(val);

}


int uuid_is_null(const uuid_t uu)

{

    uuid_t null_uuid = { 0 };

    return memcmp(uu, null_uuid, sizeof(uuid_t)) == 0;

}


static int e1000_post_load(void *opaque, int version_id)

{

    E1000State *s = opaque;

    NetClientState *nc = qemu_get_queue(s->nic);

    if (!(s->compat_flags & E1000_FLAG_MIT)) {

        s->mac_reg[ITR] = s->mac_reg[RDTR] = s->mac_reg[RADV] =

            s->mac_reg[TADV] = 0;

        s->mit_irq_level = false;

    }

    s->mit_ide = 0;

    s->mit_timer_on = false;

    /* nc.link_down can't be migrated, so infer link_down according

     * to link status bit in mac_reg[STATUS].

     * Alternatively, restart link negotiation if it was in progress. */

    nc->link_down = (s->mac_reg[STATUS] & E1000_STATUS_LU) == 0;

    if (s->compat_flags & E1000_FLAG_AUTONEG &&

        s->phy_reg[PHY_CTRL] & MII_CR_AUTO_NEG_EN &&

        s->phy_reg[PHY_CTRL] & MII_CR_RESTART_AUTO_NEG &&

        !(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {

        nc->link_down = false;

        timer_mod(s->autoneg_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);

    }

    return 0;

}


int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname)

{

    Error *err = NULL;

    opts_do_parse(opts, params, firstname, false, &err);

    if (err) {

        qerror_report_err(err);

        error_free(err);

        return -1;

    }

    return 0;

}


static int cris_mmu_enabled(uint32_t rw_gc_cfg)

{

	return (rw_gc_cfg & 12) != 0;

}


static int nut_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    NUTContext *nut = s->priv_data;

    StreamContext *stream;

    ByteIOContext *bc = &s->pb;

    int size, frame_code, flags, size_mul, size_lsb, stream_id;

    int key_frame = 0;

    int frame_type= 0;

    int64_t pts = 0;

    const int64_t frame_start= url_ftell(bc);

    if (url_feof(bc))

	return -1;

    frame_code = get_byte(bc);

    if(frame_code == 'N'){

        uint64_t tmp= frame_code;

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

	tmp<<=16; tmp |= get_be16(bc);

	tmp<<=32; tmp |= get_be32(bc);

	if (tmp == KEYFRAME_STARTCODE)

	{

	    frame_code = get_byte(bc);

            frame_type = 2;

	}

	else

	    av_log(s, AV_LOG_ERROR, "error in zero bit / startcode %LX\n", tmp);

    }

    flags= nut->frame_code[frame_code].flags;

    size_mul= nut->frame_code[frame_code].size_mul;

    size_lsb= nut->frame_code[frame_code].size_lsb;

    stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1;

    if(flags & FLAG_FRAME_TYPE){

        reset(s);

        if(frame_type==2){

            get_packetheader(nut, bc, 8+1, 0);

        }else{

            get_packetheader(nut, bc, 1, 0);

            frame_type= 1;

        }

    }

    if(stream_id==-1)

        stream_id= get_v(bc);

    if(stream_id >= s->nb_streams){

        av_log(s, AV_LOG_ERROR, "illegal stream_id\n");

        return -1;

    }

    stream= &nut->stream[stream_id];

    if(flags & FLAG_PRED_KEY_FRAME){

        if(flags & FLAG_KEY_FRAME)

            key_frame= !stream->last_key_frame;

        else

            key_frame= stream->last_key_frame;

    }else{

        key_frame= !!(flags & FLAG_KEY_FRAME);

    }

    if(flags & FLAG_PTS){

        if(flags & FLAG_FULL_PTS){

            pts= get_v(bc);

        }else{

            int64_t mask = (1<<stream->msb_timestamp_shift)-1;

            int64_t delta= stream->last_pts - mask/2;

            pts= ((get_v(bc) - delta)&mask) + delta;

        }

    }else{

        pts= stream->last_pts + stream->lru_pts_delta[(flags&12)>>2];

    }

    if(size_mul <= size_lsb){

        size= stream->lru_size[size_lsb - size_mul];

    }else{

        if(flags & FLAG_DATA_SIZE)

            size= size_mul*get_v(bc) + size_lsb;

        else

            size= size_lsb;

    }

//av_log(s, AV_LOG_DEBUG, "fs:%lld fc:%d ft:%d kf:%d pts:%lld\n", frame_start, frame_code, frame_type, key_frame, pts);

    av_new_packet(pkt, size);

    get_buffer(bc, pkt->data, size);

    pkt->stream_index = stream_id;

    if (key_frame)

	pkt->flags |= PKT_FLAG_KEY;

    pkt->pts = pts * AV_TIME_BASE * stream->rate_den / stream->rate_num;

    update(nut, stream_id, frame_start, frame_type, frame_code, key_frame, size, pts);

    return 0;

}


void block_job_user_resume(BlockJob *job)

{

    if (job && job->user_paused && job->pause_count > 0) {

        job->user_paused = false;

        block_job_iostatus_reset(job);

        block_job_resume(job);

    }

}


static void pc_cpu_reset(void *opaque)

{

    X86CPU *cpu = opaque;

    CPUX86State *env = &cpu->env;

    cpu_reset(CPU(cpu));

    env->halted = !cpu_is_bsp(env);

}


static pflash_t *ve_pflash_cfi01_register(hwaddr base, const char *name,

                                          DriveInfo *di)

{

    DeviceState *dev = qdev_create(NULL, "cfi.pflash01");

    if (di && qdev_prop_set_drive(dev, "drive",

                                  blk_bs(blk_by_legacy_dinfo(di)))) {

        abort();

    }

    qdev_prop_set_uint32(dev, "num-blocks",

                         VEXPRESS_FLASH_SIZE / VEXPRESS_FLASH_SECT_SIZE);

    qdev_prop_set_uint64(dev, "sector-length", VEXPRESS_FLASH_SECT_SIZE);

    qdev_prop_set_uint8(dev, "width", 4);

    qdev_prop_set_uint8(dev, "device-width", 2);

    qdev_prop_set_uint8(dev, "big-endian", 0);

    qdev_prop_set_uint16(dev, "id0", 0x89);

    qdev_prop_set_uint16(dev, "id1", 0x18);

    qdev_prop_set_uint16(dev, "id2", 0x00);

    qdev_prop_set_uint16(dev, "id3", 0x00);

    qdev_prop_set_string(dev, "name", name);

    qdev_init_nofail(dev);

    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);

    return OBJECT_CHECK(pflash_t, (dev), "cfi.pflash01");

}


static bool virtio_queue_host_notifier_aio_poll(void *opaque)

{

    EventNotifier *n = opaque;

    VirtQueue *vq = container_of(n, VirtQueue, host_notifier);

    bool progress;

    if (virtio_queue_empty(vq)) {

        return false;

    }

    progress = virtio_queue_notify_aio_vq(vq);

    /* In case the handler function re-enabled notifications */

    virtio_queue_set_notification(vq, 0);

    return progress;

}


static void qvirtio_9p_stop(void)

{

    qtest_end();

    rmdir(test_share);

    g_free(test_share);

}


do_kernel_trap(CPUARMState *env)

{

    uint32_t addr;

    uint32_t cpsr;

    uint32_t val;

    switch (env->regs[15]) {

    case 0xffff0fa0: /* __kernel_memory_barrier */

        /* ??? No-op. Will need to do better for SMP.  */

        break;

    case 0xffff0fc0: /* __kernel_cmpxchg */

         /* XXX: This only works between threads, not between processes.

            It's probably possible to implement this with native host

            operations. However things like ldrex/strex are much harder so

            there's not much point trying.  */

        start_exclusive();

        cpsr = cpsr_read(env);

        addr = env->regs[2];

        /* FIXME: This should SEGV if the access fails.  */

        if (get_user_u32(val, addr))

            val = ~env->regs[0];

        if (val == env->regs[0]) {

            val = env->regs[1];

            /* FIXME: Check for segfaults.  */

            put_user_u32(val, addr);

            env->regs[0] = 0;

            cpsr |= CPSR_C;

        } else {

            env->regs[0] = -1;

            cpsr &= ~CPSR_C;

        }

        cpsr_write(env, cpsr, CPSR_C);

        end_exclusive();

        break;

    case 0xffff0fe0: /* __kernel_get_tls */

        env->regs[0] = env->cp15.tpidrro_el0;

        break;

    case 0xffff0f60: /* __kernel_cmpxchg64 */

        arm_kernel_cmpxchg64_helper(env);

        break;

    default:

        return 1;

    }

    /* Jump back to the caller.  */

    addr = env->regs[14];

    if (addr & 1) {

        env->thumb = 1;

        addr &= ~1;

    }

    env->regs[15] = addr;

    return 0;

}


static void event_notifier_dummy_cb(EventNotifier *e)

{

}


uint16_t cpu_inw(CPUState *env, pio_addr_t addr)

{

    uint16_t val;

    val = ioport_read(1, addr);

    LOG_IOPORT("inw : %04"FMT_pioaddr" %04"PRIx16"\n", addr, val);

#ifdef CONFIG_KQEMU

    if (env)

        env->last_io_time = cpu_get_time_fast();

#endif

    return val;

}


static NVDIMMDevice *nvdimm_get_device_by_handle(uint32_t handle)

{

    NVDIMMDevice *nvdimm = NULL;

    GSList *list, *device_list = nvdimm_get_plugged_device_list();

    for (list = device_list; list; list = list->next) {

        NVDIMMDevice *nvd = list->data;

        int slot = object_property_get_int(OBJECT(nvd), PC_DIMM_SLOT_PROP,

                                           NULL);

        if (nvdimm_slot_to_handle(slot) == handle) {

            nvdimm = nvd;

            break;

        }

    }

    g_slist_free(device_list);

    return nvdimm;

}


int avio_check(const char *url, int flags)

{

    URLContext *h;

    int ret = ffurl_alloc(&h, url, flags, NULL);

    if (ret)

        return ret;

    if (h->prot->url_check) {

        ret = h->prot->url_check(h, flags);

    } else {

        ret = ffurl_connect(h, NULL);

        if (ret >= 0)

            ret = flags;

    }

    ffurl_close(h);

    return ret;

}


int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,

                             int is_write1, int mmu_idx)

{

    X86CPU *cpu = X86_CPU(cs);

    CPUX86State *env = &cpu->env;

    uint64_t ptep, pte;

    target_ulong pde_addr, pte_addr;

    int error_code = 0;

    int is_dirty, prot, page_size, is_write, is_user;

    hwaddr paddr;

    uint64_t rsvd_mask = PG_HI_RSVD_MASK;

    uint32_t page_offset;

    target_ulong vaddr;

    is_user = mmu_idx == MMU_USER_IDX;

#if defined(DEBUG_MMU)

    printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",

           addr, is_write1, is_user, env->eip);

#endif

    is_write = is_write1 & 1;

    if (!(env->cr[0] & CR0_PG_MASK)) {

        pte = addr;

#ifdef TARGET_X86_64

        if (!(env->hflags & HF_LMA_MASK)) {

            /* Without long mode we can only address 32bits in real mode */

            pte = (uint32_t)pte;

        }

#endif

        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;

        page_size = 4096;

        goto do_mapping;

    }

    if (env->cr[4] & CR4_PAE_MASK) {

        uint64_t pde, pdpe;

        target_ulong pdpe_addr;

#ifdef TARGET_X86_64

        if (env->hflags & HF_LMA_MASK) {

            uint64_t pml4e_addr, pml4e;

            int32_t sext;

            /* test virtual address sign extension */

            sext = (int64_t)addr >> 47;

            if (sext != 0 && sext != -1) {

                env->error_code = 0;

                cs->exception_index = EXCP0D_GPF;

                return 1;

            }

            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &

                env->a20_mask;

            pml4e = ldq_phys(cs->as, pml4e_addr);

            if (!(pml4e & PG_PRESENT_MASK)) {

                goto do_fault;

            }

            if (pml4e & (rsvd_mask | PG_PSE_MASK)) {

                goto do_fault_rsvd;

            }

            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {

                goto do_fault_rsvd;

            }

            if (!(pml4e & PG_ACCESSED_MASK)) {

                pml4e |= PG_ACCESSED_MASK;

                stl_phys_notdirty(cs->as, pml4e_addr, pml4e);

            }

            ptep = pml4e ^ PG_NX_MASK;

            pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3)) &

                env->a20_mask;

            pdpe = ldq_phys(cs->as, pdpe_addr);

            if (!(pdpe & PG_PRESENT_MASK)) {

                goto do_fault;

            }

            if (pdpe & rsvd_mask) {

                goto do_fault_rsvd;

            }

            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {

                goto do_fault_rsvd;

            }

            ptep &= pdpe ^ PG_NX_MASK;

            if (!(pdpe & PG_ACCESSED_MASK)) {

                pdpe |= PG_ACCESSED_MASK;

                stl_phys_notdirty(cs->as, pdpe_addr, pdpe);

            }

            if (pdpe & PG_PSE_MASK) {

                /* 1 GB page */

                page_size = 1024 * 1024 * 1024;

                pte_addr = pdpe_addr;

                pte = pdpe;

                goto do_check_protect;

            }

        } else

#endif

        {

            /* XXX: load them when cr3 is loaded ? */

            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &

                env->a20_mask;

            pdpe = ldq_phys(cs->as, pdpe_addr);

            if (!(pdpe & PG_PRESENT_MASK)) {

                goto do_fault;

            }

            rsvd_mask |= PG_HI_USER_MASK | PG_NX_MASK;

            if (pdpe & rsvd_mask) {

                goto do_fault_rsvd;

            }

            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;

        }

        pde_addr = ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3)) &

            env->a20_mask;

        pde = ldq_phys(cs->as, pde_addr);

        if (!(pde & PG_PRESENT_MASK)) {

            goto do_fault;

        }

        if (pde & rsvd_mask) {

            goto do_fault_rsvd;

        }

        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {

            goto do_fault_rsvd;

        }

        ptep &= pde ^ PG_NX_MASK;

        if (pde & PG_PSE_MASK) {

            /* 2 MB page */

            page_size = 2048 * 1024;

            pte_addr = pde_addr;

            pte = pde;

            goto do_check_protect;

        }

        /* 4 KB page */

        if (!(pde & PG_ACCESSED_MASK)) {

            pde |= PG_ACCESSED_MASK;

            stl_phys_notdirty(cs->as, pde_addr, pde);

        }

        pte_addr = ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3)) &

            env->a20_mask;

        pte = ldq_phys(cs->as, pte_addr);

        if (!(pte & PG_PRESENT_MASK)) {

            goto do_fault;

        }

        if (pte & rsvd_mask) {

            goto do_fault_rsvd;

        }

        if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {

            goto do_fault_rsvd;

        }

        /* combine pde and pte nx, user and rw protections */

        ptep &= pte ^ PG_NX_MASK;

        page_size = 4096;

    } else {

        uint32_t pde;

        /* page directory entry */

        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &

            env->a20_mask;

        pde = ldl_phys(cs->as, pde_addr);

        if (!(pde & PG_PRESENT_MASK)) {

            goto do_fault;

        }

        ptep = pde | PG_NX_MASK;

        /* if PSE bit is set, then we use a 4MB page */

        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {

            page_size = 4096 * 1024;

            pte_addr = pde_addr;

            pte = pde;

            goto do_check_protect;

        }

        if (!(pde & PG_ACCESSED_MASK)) {

            pde |= PG_ACCESSED_MASK;

            stl_phys_notdirty(cs->as, pde_addr, pde);

        }

        /* page directory entry */

        pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &

            env->a20_mask;

        pte = ldl_phys(cs->as, pte_addr);

        if (!(pte & PG_PRESENT_MASK)) {

            goto do_fault;

        }

        /* combine pde and pte user and rw protections */

        ptep &= pte | PG_NX_MASK;

        page_size = 4096;

        rsvd_mask = 0;

    }

do_check_protect:

    if (pte & rsvd_mask) {

        goto do_fault_rsvd;

    }

    ptep ^= PG_NX_MASK;

    if ((ptep & PG_NX_MASK) && is_write1 == 2) {

        goto do_fault_protect;

    }

    switch (mmu_idx) {

    case MMU_USER_IDX:

        if (!(ptep & PG_USER_MASK)) {

            goto do_fault_protect;

        }

        if (is_write && !(ptep & PG_RW_MASK)) {

            goto do_fault_protect;

        }

        break;

    case MMU_KSMAP_IDX:

        if (is_write1 != 2 && (ptep & PG_USER_MASK)) {

            goto do_fault_protect;

        }

        /* fall through */

    case MMU_KNOSMAP_IDX:

        if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&

            (ptep & PG_USER_MASK)) {

            goto do_fault_protect;

        }

        if ((env->cr[0] & CR0_WP_MASK) &&

            is_write && !(ptep & PG_RW_MASK)) {

            goto do_fault_protect;

        }

        break;

    default: /* cannot happen */

        break;

    }

    is_dirty = is_write && !(pte & PG_DIRTY_MASK);

    if (!(pte & PG_ACCESSED_MASK) || is_dirty) {

        pte |= PG_ACCESSED_MASK;

        if (is_dirty) {

            pte |= PG_DIRTY_MASK;

        }

        stl_phys_notdirty(cs->as, pte_addr, pte);

    }

    /* the page can be put in the TLB */

    prot = PAGE_READ;

    if (!(ptep & PG_NX_MASK))

        prot |= PAGE_EXEC;

    if (pte & PG_DIRTY_MASK) {

        /* only set write access if already dirty... otherwise wait

           for dirty access */

        if (is_user) {

            if (ptep & PG_RW_MASK)

                prot |= PAGE_WRITE;

        } else {

            if (!(env->cr[0] & CR0_WP_MASK) ||

                (ptep & PG_RW_MASK))

                prot |= PAGE_WRITE;

        }

    }

 do_mapping:

    pte = pte & env->a20_mask;

    /* align to page_size */

    pte &= PG_ADDRESS_MASK & ~(page_size - 1);

    /* Even if 4MB pages, we map only one 4KB page in the cache to

       avoid filling it too fast */

    vaddr = addr & TARGET_PAGE_MASK;

    page_offset = vaddr & (page_size - 1);

    paddr = pte + page_offset;

    tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);

    return 0;

 do_fault_rsvd:

    error_code |= PG_ERROR_RSVD_MASK;

 do_fault_protect:

    error_code |= PG_ERROR_P_MASK;

 do_fault:

    error_code |= (is_write << PG_ERROR_W_BIT);

    if (is_user)

        error_code |= PG_ERROR_U_MASK;

    if (is_write1 == 2 &&

        (((env->efer & MSR_EFER_NXE) &&

          (env->cr[4] & CR4_PAE_MASK)) ||

         (env->cr[4] & CR4_SMEP_MASK)))

        error_code |= PG_ERROR_I_D_MASK;

    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {

        /* cr2 is not modified in case of exceptions */

        stq_phys(cs->as,

                 env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),

                 addr);

    } else {

        env->cr[2] = addr;

    }

    env->error_code = error_code;

    cs->exception_index = EXCP0E_PAGE;

    return 1;

}


int kvmppc_reset_htab(int shift_hint)

{

    uint32_t shift = shift_hint;

    if (!kvm_enabled()) {

        /* Full emulation, tell caller to allocate htab itself */

        return 0;

    }

    if (kvm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) {

        int ret;

        ret = kvm_vm_ioctl(kvm_state, KVM_PPC_ALLOCATE_HTAB, &shift);

        if (ret == -ENOTTY) {

            /* At least some versions of PR KVM advertise the

             * capability, but don't implement the ioctl().  Oops.

             * Return 0 so that we allocate the htab in qemu, as is

             * correct for PR. */

            return 0;

        } else if (ret < 0) {

            return ret;

        }

        return shift;

    }

    /* We have a kernel that predates the htab reset calls.  For PR

     * KVM, we need to allocate the htab ourselves, for an HV KVM of

     * this era, it has allocated a 16MB fixed size hash table

     * already.  Kernels of this era have the GET_PVINFO capability

     * only on PR, so we use this hack to determine the right

     * answer */

    if (kvm_check_extension(kvm_state, KVM_CAP_PPC_GET_PVINFO)) {

        /* PR - tell caller to allocate htab */

        return 0;

    } else {

        /* HV - assume 16MB kernel allocated htab */

        return 24;

    }

}


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

{

    AVStream *st;

    MOVStreamContext *sc;

    int ret;

    st = av_new_stream(c->fc, c->fc->nb_streams);

    if (!st) return AVERROR(ENOMEM);

    sc = av_mallocz(sizeof(MOVStreamContext));

    if (!sc) return AVERROR(ENOMEM);

    st->priv_data = sc;

    st->codec->codec_type = CODEC_TYPE_DATA;

    sc->ffindex = st->index;

    if ((ret = mov_read_default(c, pb, atom)) < 0)

        return ret;

    /* sanity checks */

    if(sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||

                           (!sc->sample_size && !sc->sample_count))){

        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",

               st->index);

        sc->sample_count = 0; //ignore track

        return 0;

    }

    if(!sc->time_rate)

        sc->time_rate=1;

    if(!sc->time_scale)

        sc->time_scale= c->time_scale;

    av_set_pts_info(st, 64, sc->time_rate, sc->time_scale);

    if (st->codec->codec_type == CODEC_TYPE_AUDIO &&

        !st->codec->frame_size && sc->stts_count == 1) {

        st->codec->frame_size = av_rescale(sc->stts_data[0].duration,

                                           st->codec->sample_rate, sc->time_scale);

        dprintf(c->fc, "frame size %d\n", st->codec->frame_size);

    }

    if(st->duration != AV_NOPTS_VALUE){

        assert(st->duration % sc->time_rate == 0);

        st->duration /= sc->time_rate;

    }

    mov_build_index(c, st);

    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {

        if (url_fopen(&sc->pb, sc->drefs[sc->dref_id-1].path, URL_RDONLY) < 0)

            av_log(c->fc, AV_LOG_ERROR, "stream %d, error opening file %s: %s\n",

                   st->index, sc->drefs[sc->dref_id-1].path, strerror(errno));

    } else

        sc->pb = c->fc->pb;

    switch (st->codec->codec_id) {

#if CONFIG_H261_DECODER

    case CODEC_ID_H261:

#endif

#if CONFIG_H263_DECODER

    case CODEC_ID_H263:

#endif

#if CONFIG_MPEG4_DECODER

    case CODEC_ID_MPEG4:

#endif

        st->codec->width= 0; /* let decoder init width/height */

        st->codec->height= 0;

        break;

    }

    /* Do not need those anymore. */

    av_freep(&sc->chunk_offsets);

    av_freep(&sc->stsc_data);

    av_freep(&sc->sample_sizes);

    av_freep(&sc->keyframes);

    av_freep(&sc->stts_data);

    return 0;

}


static void FUNCC(pred8x8_horizontal_add)(uint8_t *pix, const int *block_offset,

                                          const int16_t *block,

                                          ptrdiff_t stride)

{

    int i;

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

        FUNCC(pred4x4_horizontal_add)(pix + block_offset[i], block + i*16*sizeof(pixel), stride);

}


void init_checksum(ByteIOContext *s, unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), unsigned long checksum){

    s->update_checksum= update_checksum;

    s->checksum= s->update_checksum(checksum, NULL, 0);

    s->checksum_ptr= s->buf_ptr;

}


static av_cold int hap_init(AVCodecContext *avctx)

{

    HapContext *ctx = avctx->priv_data;

    int ratio;

    int corrected_chunk_count;

    int ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);

    if (ret < 0) {

        av_log(avctx, AV_LOG_ERROR, "Invalid video size %dx%d.\n",

               avctx->width, avctx->height);

        return ret;

    }

    if (avctx->width % 4 || avctx->height % 4) {

        av_log(avctx, AV_LOG_ERROR, "Video size %dx%d is not multiple of 4.\n",

               avctx->width, avctx->height);

        return AVERROR_INVALIDDATA;

    }

    ff_texturedspenc_init(&ctx->dxtc);

    switch (ctx->opt_tex_fmt) {

    case HAP_FMT_RGBDXT1:

        ratio = 8;

        avctx->codec_tag = MKTAG('H', 'a', 'p', '1');

        avctx->bits_per_coded_sample = 24;

        ctx->tex_fun = ctx->dxtc.dxt1_block;

        break;

    case HAP_FMT_RGBADXT5:

        ratio = 4;

        avctx->codec_tag = MKTAG('H', 'a', 'p', '5');

        avctx->bits_per_coded_sample = 32;

        ctx->tex_fun = ctx->dxtc.dxt5_block;

        break;

    case HAP_FMT_YCOCGDXT5:

        ratio = 4;

        avctx->codec_tag = MKTAG('H', 'a', 'p', 'Y');

        avctx->bits_per_coded_sample = 24;

        ctx->tex_fun = ctx->dxtc.dxt5ys_block;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Invalid format %02X\n", ctx->opt_tex_fmt);

        return AVERROR_INVALIDDATA;

    }

    /* Texture compression ratio is constant, so can we computer

     * beforehand the final size of the uncompressed buffer. */

    ctx->tex_size   = FFALIGN(avctx->width,  TEXTURE_BLOCK_W) *

                      FFALIGN(avctx->height, TEXTURE_BLOCK_H) * 4 / ratio;

    /* Round the chunk count to divide evenly on DXT block edges */

    corrected_chunk_count = av_clip(ctx->opt_chunk_count, 1, HAP_MAX_CHUNKS);

    while ((ctx->tex_size / (64 / ratio)) % corrected_chunk_count != 0) {

        corrected_chunk_count--;

    }

    if (corrected_chunk_count != ctx->opt_chunk_count) {

        av_log(avctx, AV_LOG_INFO, "%d chunks requested but %d used.\n",

                                    ctx->opt_chunk_count, corrected_chunk_count);

    }

    ret = ff_hap_set_chunk_count(ctx, corrected_chunk_count, 1);

    if (ret != 0)

        return ret;

    ctx->max_snappy = snappy_max_compressed_length(ctx->tex_size / corrected_chunk_count);

    ctx->tex_buf  = av_malloc(ctx->tex_size);

    if (!ctx->tex_buf)

        return AVERROR(ENOMEM);

    return 0;

}


static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index,

                                 const uint8_t *buf, int size, int64_t pts)

{

    MpegMuxContext *s = ctx->priv_data;

    AVStream *st = ctx->streams[stream_index];

    StreamInfo *stream = st->priv_data;

    int len;

    while (size > 0) {

        /* set pts */

        if (stream->start_pts == -1) {

            stream->start_pts = pts;

        }

        len = s->packet_data_max_size - stream->buffer_ptr;

        if (len > size)

            len = size;

        memcpy(stream->buffer + stream->buffer_ptr, buf, len);

        stream->buffer_ptr += len;

        buf += len;

        size -= len;

        while (stream->buffer_ptr >= s->packet_data_max_size) {

            /* output the packet */

            if (stream->start_pts == -1)

                stream->start_pts = pts;

            flush_packet(ctx, stream_index, 0);

        }

    }

    return 0;

}


static int decode_i_block(FourXContext *f, int16_t *block)

{

    int code, i, j, level, val;

    if (get_bits_left(&f->gb) < 2){

        av_log(f->avctx, AV_LOG_ERROR, "%d bits left before decode_i_block()\n", get_bits_left(&f->gb));

        return -1;

    }

    /* DC coef */

    val = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);

    if (val >> 4)

        av_log(f->avctx, AV_LOG_ERROR, "error dc run != 0\n");

    if (val)

        val = get_xbits(&f->gb, val);

    val        = val * dequant_table[0] + f->last_dc;

    f->last_dc = block[0] = val;

    /* AC coefs */

    i = 1;

    for (;;) {

        code = get_vlc2(&f->pre_gb, f->pre_vlc.table, ACDC_VLC_BITS, 3);

        /* EOB */

        if (code == 0)

            break;

        if (code == 0xf0) {

            i += 16;

        } else {

            level = get_xbits(&f->gb, code & 0xf);

            i    += code >> 4;

            if (i >= 64) {

                av_log(f->avctx, AV_LOG_ERROR, "run %d oveflow\n", i);

                return 0;

            }

            j = ff_zigzag_direct[i];

            block[j] = level * dequant_table[j];

            i++;

            if (i >= 64)

                break;

        }

    }

    return 0;

}


static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y,

                             const uint8_t **buf, int buf_size)

{

    MpegEncContext *s = &s1->mpeg_enc_ctx;

    AVCodecContext *avctx= s->avctx;

    const int field_pic= s->picture_structure != PICT_FRAME;

    const int lowres= s->avctx->lowres;

    s->resync_mb_x=

    s->resync_mb_y= -1;

    if (mb_y >= s->mb_height){

        av_log(s->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s->mb_height);

        return -1;

    }

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

    ff_mpeg1_clean_buffers(s);

    s->interlaced_dct = 0;

    s->qscale = get_qscale(s);

    if(s->qscale == 0){

        av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");

        return -1;

    }

    /* extra slice info */

    while (get_bits1(&s->gb) != 0) {

        skip_bits(&s->gb, 8);

    }

    s->mb_x=0;

    for(;;) {

        int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);

        if (code < 0){

            av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");

            return -1;

        }

        if (code >= 33) {

            if (code == 33) {

                s->mb_x += 33;

            }

            /* otherwise, stuffing, nothing to do */

        } else {

            s->mb_x += code;

            break;

        }

    }

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

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

        return -1;

    }

    if (avctx->hwaccel) {

        const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */

        int start_code = -1;

        buf_end = ff_find_start_code(buf_start + 2, *buf + buf_size, &start_code);

        if (buf_end < *buf + buf_size)

            buf_end -= 4;

        s->mb_y = mb_y;

        if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0)

            return DECODE_SLICE_ERROR;

        *buf = buf_end;

        return DECODE_SLICE_OK;

    }

    s->resync_mb_x= s->mb_x;

    s->resync_mb_y= s->mb_y= mb_y;

    s->mb_skip_run= 0;

    ff_init_block_index(s);

    if (s->mb_y==0 && s->mb_x==0 && (s->first_field || s->picture_structure==PICT_FRAME)) {

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

             av_log(s->avctx, AV_LOG_DEBUG, "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",

                 s->qscale, s->mpeg_f_code[0][0],s->mpeg_f_code[0][1],s->mpeg_f_code[1][0],s->mpeg_f_code[1][1],

                 s->pict_type == FF_I_TYPE ? "I" : (s->pict_type == FF_P_TYPE ? "P" : (s->pict_type == FF_B_TYPE ? "B" : "S")),

                 s->progressive_sequence ? "ps" :"", s->progressive_frame ? "pf" : "", s->alternate_scan ? "alt" :"", s->top_field_first ? "top" :"",

                 s->intra_dc_precision, s->picture_structure, s->frame_pred_frame_dct, s->concealment_motion_vectors,

                 s->q_scale_type, s->intra_vlc_format, s->repeat_first_field, s->chroma_420_type ? "420" :"");

        }

    }

    for(;;) {

        //If 1, we memcpy blocks in xvmcvideo.

        if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)

            ff_xvmc_init_block(s);//set s->block

        if(mpeg_decode_mb(s, s->block) < 0)

            return -1;

        if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs

            const int wrap = s->b8_stride;

            int xy = s->mb_x*2 + s->mb_y*2*wrap;

            int motion_x, motion_y, dir, i;

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

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

                    if (s->mb_intra || (dir==1 && s->pict_type != FF_B_TYPE)) {

                        motion_x = motion_y = 0;

                    }else if (s->mv_type == MV_TYPE_16X16 || (s->mv_type == MV_TYPE_FIELD && field_pic)){

                        motion_x = s->mv[dir][0][0];

                        motion_y = s->mv[dir][0][1];

                    } else /*if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8))*/ {

                        motion_x = s->mv[dir][i][0];

                        motion_y = s->mv[dir][i][1];

                    }

                    s->current_picture.motion_val[dir][xy    ][0] = motion_x;

                    s->current_picture.motion_val[dir][xy    ][1] = motion_y;

                    s->current_picture.motion_val[dir][xy + 1][0] = motion_x;

                    s->current_picture.motion_val[dir][xy + 1][1] = motion_y;

                    s->current_picture.ref_index [dir][xy    ]=

                    s->current_picture.ref_index [dir][xy + 1]= s->field_select[dir][i];

                    assert(s->field_select[dir][i]==0 || s->field_select[dir][i]==1);

                }

                xy += wrap;

            }

        }

        s->dest[0] += 16 >> lowres;

        s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift;

        s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift;

        MPV_decode_mb(s, s->block);

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

            const int mb_size= 16>>s->avctx->lowres;

            ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size);

            s->mb_x = 0;

            s->mb_y += 1<<field_pic;

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

                int left= get_bits_left(&s->gb);

                int is_d10= s->chroma_format==2 && s->pict_type==FF_I_TYPE && avctx->profile==0 && avctx->level==5

                            && s->intra_dc_precision == 2 && s->q_scale_type == 1 && s->alternate_scan == 0

                            && s->progressive_frame == 0 /* vbv_delay == 0xBBB || 0xE10*/;

                if(left < 0 || (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10)

                   || (avctx->error_recognition >= FF_ER_AGGRESSIVE && left>8)){

                    av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", left, show_bits(&s->gb, FFMIN(left, 23)));

                    return -1;

                }else

                    goto eos;

            }

            ff_init_block_index(s);

        }

        /* skip mb handling */

        if (s->mb_skip_run == -1) {

            /* read increment again */

            s->mb_skip_run = 0;

            for(;;) {

                int code = get_vlc2(&s->gb, mbincr_vlc.table, MBINCR_VLC_BITS, 2);

                if (code < 0){

                    av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");

                    return -1;

                }

                if (code >= 33) {

                    if (code == 33) {

                        s->mb_skip_run += 33;

                    }else if(code == 35){

                        if(s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0){

                            av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n");

                            return -1;

                        }

                        goto eos; /* end of slice */

                    }

                    /* otherwise, stuffing, nothing to do */

                } else {

                    s->mb_skip_run += code;

                    break;

                }

            }

            if(s->mb_skip_run){

                int i;

                if(s->pict_type == FF_I_TYPE){

                    av_log(s->avctx, AV_LOG_ERROR, "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y);

                    return -1;

                }

                /* skip mb */

                s->mb_intra = 0;

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

                    s->block_last_index[i] = -1;

                if(s->picture_structure == PICT_FRAME)

                    s->mv_type = MV_TYPE_16X16;

                else

                    s->mv_type = MV_TYPE_FIELD;

                if (s->pict_type == FF_P_TYPE) {

                    /* if P type, zero motion vector is implied */

                    s->mv_dir = MV_DIR_FORWARD;

                    s->mv[0][0][0] = s->mv[0][0][1] = 0;

                    s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;

                    s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;

                    s->field_select[0][0]= (s->picture_structure - 1) & 1;

                } else {

                    /* if B type, reuse previous vectors and directions */

                    s->mv[0][0][0] = s->last_mv[0][0][0];

                    s->mv[0][0][1] = s->last_mv[0][0][1];

                    s->mv[1][0][0] = s->last_mv[1][0][0];

                    s->mv[1][0][1] = s->last_mv[1][0][1];

                }

            }

        }

    }

eos: // end of slice

    *buf += (get_bits_count(&s->gb)-1)/8;

//printf("y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y);

    return 0;

}


static inline void RENAME(rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,

	long width, long height,

	long lumStride, long chromStride, long srcStride)

{

	long y;

	const long chromWidth= width>>1;

#ifdef HAVE_MMX

	for(y=0; y<height-2; y+=2)

	{

		long i;

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

		{

			asm volatile(

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

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

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

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

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

				ASMALIGN16

				"1:				\n\t"

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

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

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

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

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

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

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

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

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

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

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

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

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

#ifndef FAST_BGR2YV12

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

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

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

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

#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#ifndef FAST_BGR2YV12

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

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

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

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

#endif

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

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

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

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

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

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

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

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

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

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

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

				" js 1b				\n\t"

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

				: "%"REG_a, "%"REG_b

			);

			ydst += lumStride;

			src  += srcStride;

		}

		src -= srcStride*2;

		asm volatile(

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

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

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

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

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

			"add %%"REG_b", %%"REG_b"	\n\t"

			ASMALIGN16

			"1:				\n\t"

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

			PREFETCH" 64(%1, %%"REG_b")	\n\t"

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

			"movq (%0, %%"REG_b"), %%mm0	\n\t"

			"movq (%1, %%"REG_b"), %%mm1	\n\t"

			"movq 6(%0, %%"REG_b"), %%mm2	\n\t"

			"movq 6(%1, %%"REG_b"), %%mm3	\n\t"

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

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

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

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

			"psrlq $24, %%mm0		\n\t"

			"psrlq $24, %%mm2		\n\t"

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

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

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

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

#else

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

			"movd (%1, %%"REG_b"), %%mm1	\n\t"

			"movd 3(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 3(%1, %%"REG_b"), %%mm3	\n\t"

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

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

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

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

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

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

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

			"movd 6(%0, %%"REG_b"), %%mm4	\n\t"

			"movd 6(%1, %%"REG_b"), %%mm1	\n\t"

			"movd 9(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 9(%1, %%"REG_b"), %%mm3	\n\t"

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

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

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

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

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

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

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

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

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

#endif

			"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

			"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

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

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

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

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

#ifndef FAST_BGR2YV12

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

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

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

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

#endif

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

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

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

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

			"packssdw %%mm1, %%mm0		\n\t" // V1 V0 U1 U0

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

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

			"movq 12(%0, %%"REG_b"), %%mm4	\n\t"

			"movq 12(%1, %%"REG_b"), %%mm1	\n\t"

			"movq 18(%0, %%"REG_b"), %%mm2	\n\t"

			"movq 18(%1, %%"REG_b"), %%mm3	\n\t"

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

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

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

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

			"psrlq $24, %%mm4		\n\t"

			"psrlq $24, %%mm2		\n\t"

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

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

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

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

#else

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

			"movd 12(%1, %%"REG_b"), %%mm1	\n\t"

			"movd 15(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 15(%1, %%"REG_b"), %%mm3	\n\t"

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

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

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

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

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

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

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

			"movd 18(%0, %%"REG_b"), %%mm5	\n\t"

			"movd 18(%1, %%"REG_b"), %%mm1	\n\t"

			"movd 21(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 21(%1, %%"REG_b"), %%mm3	\n\t"

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

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

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

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

			"paddw %%mm1, %%mm5		\n\t"

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

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

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

			"psrlw $2, %%mm4		\n\t"

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

#endif

			"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

			"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

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

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

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

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

#ifndef FAST_BGR2YV12

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

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

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

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

#endif

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

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

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

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

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

			"packssdw %%mm1, %%mm4		\n\t" // V3 V2 U3 U2

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

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

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

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

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

			"paddb "MANGLE(bgr2UVOffset)", %%mm0	\n\t"

			"movd %%mm0, (%2, %%"REG_a")	\n\t"

			"punpckhdq %%mm0, %%mm0		\n\t"

			"movd %%mm0, (%3, %%"REG_a")	\n\t"

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

			" js 1b				\n\t"

			: : "r" (src+chromWidth*6), "r" (src+srcStride+chromWidth*6), "r" (udst+chromWidth), "r" (vdst+chromWidth), "g" (-chromWidth)

			: "%"REG_a, "%"REG_b

		);

		udst += chromStride;

		vdst += chromStride;

		src  += srcStride*2;

	}

	asm volatile(   EMMS" \n\t"

			SFENCE" \n\t"

			:::"memory");

#else

	y=0;

#endif

	for(; y<height; y+=2)

	{

		long i;

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

		{

			unsigned int b= src[6*i+0];

			unsigned int g= src[6*i+1];

			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;

			unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;

			udst[i] 	= U;

			vdst[i] 	= V;

			ydst[2*i] 	= Y;

			b= src[6*i+3];

			g= src[6*i+4];

			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[2*i+1] 	= Y;

		}

		ydst += lumStride;

		src  += srcStride;

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

		{

			unsigned int b= src[6*i+0];

			unsigned int g= src[6*i+1];

			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[2*i] 	= Y;

			b= src[6*i+3];

			g= src[6*i+4];

			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[2*i+1] 	= Y;

		}

		udst += chromStride;

		vdst += chromStride;

		ydst += lumStride;

		src  += srcStride;

	}

}


static int paf_vid_decode(AVCodecContext *avctx, void *data,

                          int *data_size, AVPacket *pkt)

{

    PAFVideoDecContext *c = avctx->priv_data;

    uint8_t code, *dst, *src, *end;

    int i, frame, ret;

    c->pic.reference = 3;

    if ((ret = avctx->reget_buffer(avctx, &c->pic)) < 0)

        return ret;

    bytestream2_init(&c->gb, pkt->data, pkt->size);

    code = bytestream2_get_byte(&c->gb);

    if (code & 0x20) {

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

            memset(c->frame[i], 0, c->frame_size);

        memset(c->pic.data[1], 0, AVPALETTE_SIZE);

        c->current_frame = 0;

        c->pic.key_frame = 1;

        c->pic.pict_type = AV_PICTURE_TYPE_I;

    } else {

        c->pic.key_frame = 0;

        c->pic.pict_type = AV_PICTURE_TYPE_P;

    }

    if (code & 0x40) {

        uint32_t *out = (uint32_t *)c->pic.data[1];

        int index, count;

        index = bytestream2_get_byte(&c->gb);

        count = bytestream2_get_byte(&c->gb) + 1;

        if (index + count > AVPALETTE_SIZE)

            return AVERROR_INVALIDDATA;

        if (bytestream2_get_bytes_left(&c->gb) < 3 * AVPALETTE_SIZE)

            return AVERROR_INVALIDDATA;

        out += index;

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

            unsigned r, g, b;

            r = bytestream2_get_byteu(&c->gb);

            r = r << 2 | r >> 4;

            g = bytestream2_get_byteu(&c->gb);

            g = g << 2 | g >> 4;

            b = bytestream2_get_byteu(&c->gb);

            b = b << 2 | b >> 4;

            *out++ = 0xFFU << 24 | r << 16 | g << 8 | b;

        }

        c->pic.palette_has_changed = 1;

    }

    switch (code & 0x0F) {

    case 0:

        if ((ret = decode_0(avctx, code, pkt->data)) < 0)

            return ret;

        break;

    case 1:

        dst = c->frame[c->current_frame];

        bytestream2_skip(&c->gb, 2);

        if (bytestream2_get_bytes_left(&c->gb) < c->video_size)

            return AVERROR_INVALIDDATA;

        bytestream2_get_bufferu(&c->gb, dst, c->video_size);

        break;

    case 2:

        frame = bytestream2_get_byte(&c->gb);

        if (frame > 3)

            return AVERROR_INVALIDDATA;

        if (frame != c->current_frame)

            memcpy(c->frame[c->current_frame], c->frame[frame], c->frame_size);

        break;

    case 4:

        dst = c->frame[c->current_frame];

        end = dst + c->video_size;

        bytestream2_skip(&c->gb, 2);

        while (dst < end) {

            int8_t code;

            int count;

            if (bytestream2_get_bytes_left(&c->gb) < 2)

                return AVERROR_INVALIDDATA;

            code  = bytestream2_get_byteu(&c->gb);

            count = FFABS(code) + 1;

            if (dst + count > end)

                return AVERROR_INVALIDDATA;

            if (code < 0)

                memset(dst, bytestream2_get_byteu(&c->gb), count);

            else

                bytestream2_get_buffer(&c->gb, dst, count);

            dst += count;

        }

        break;

    default:

        av_log_ask_for_sample(avctx, "unknown/invalid code\n");

        return AVERROR_INVALIDDATA;

    }

    dst = c->pic.data[0];

    src = c->frame[c->current_frame];

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

        memcpy(dst, src, avctx->width);

        dst += c->pic.linesize[0];

        src += avctx->width;

    }

    c->current_frame = (c->current_frame + 1) & 3;

    *data_size       = sizeof(AVFrame);

    *(AVFrame *)data = c->pic;

    return pkt->size;

}


static int file_read(URLContext *h, unsigned char *buf, int size)

{

    FileContext *c = h->priv_data;

    int r = read(c->fd, buf, size);

    return (-1 == r)?AVERROR(errno):r;

}


static void realview_init(ram_addr_t ram_size,

                     const char *boot_device,

                     const char *kernel_filename, const char *kernel_cmdline,

                     const char *initrd_filename, const char *cpu_model)

{

    CPUState *env;

    ram_addr_t ram_offset;

    DeviceState *dev;

    qemu_irq *irqp;

    qemu_irq pic[64];

    PCIBus *pci_bus;

    NICInfo *nd;

    int n;

    int done_smc = 0;

    qemu_irq cpu_irq[4];

    int ncpu;

    if (!cpu_model)

        cpu_model = "arm926";

    /* FIXME: obey smp_cpus.  */

    if (strcmp(cpu_model, "arm11mpcore") == 0) {

        ncpu = 4;

    } else {

        ncpu = 1;

    }

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

        env = cpu_init(cpu_model);

        if (!env) {

            fprintf(stderr, "Unable to find CPU definition\n");

            exit(1);

        }

        irqp = arm_pic_init_cpu(env);

        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];

        if (n > 0) {

            /* Set entry point for secondary CPUs.  This assumes we're using

               the init code from arm_boot.c.  Real hardware resets all CPUs

               the same.  */

            env->regs[15] = 0x80000000;

        }

    }

    ram_offset = qemu_ram_alloc(ram_size);

    /* ??? RAM should repeat to fill physical memory space.  */

    /* SDRAM at address zero.  */

    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);

    arm_sysctl_init(0x10000000, 0xc1400400);

    if (ncpu == 1) {

        /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3

           is nIRQ (there are inconsistencies).  However Linux 2.6.17 expects

           GIC1 to be nIRQ and ignores all the others, so do that for now.  */

        dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]);

    } else {

        dev = sysbus_create_varargs("realview_mpcore", -1,

                                    cpu_irq[0], cpu_irq[1], cpu_irq[2],

                                    cpu_irq[3], NULL);

    }

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

        pic[n] = qdev_get_gpio_in(dev, n);

    }

    sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);

    sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);

    sysbus_create_simple("pl011", 0x10009000, pic[12]);

    sysbus_create_simple("pl011", 0x1000a000, pic[13]);

    sysbus_create_simple("pl011", 0x1000b000, pic[14]);

    sysbus_create_simple("pl011", 0x1000c000, pic[15]);

    /* DMA controller is optional, apparently.  */

    sysbus_create_simple("pl081", 0x10030000, pic[24]);

    sysbus_create_simple("sp804", 0x10011000, pic[4]);

    sysbus_create_simple("sp804", 0x10012000, pic[5]);

    sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]);

    sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);

    sysbus_create_simple("pl031", 0x10017000, pic[10]);

    dev = sysbus_create_varargs("realview_pci", 0x60000000,

                                pic[48], pic[49], pic[50], pic[51], NULL);

    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");

    if (usb_enabled) {

        usb_ohci_init_pci(pci_bus, -1);

    }

    n = drive_get_max_bus(IF_SCSI);

    while (n >= 0) {

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

        n--;

    }

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

        nd = &nd_table[n];

        if ((!nd->model && !done_smc) || strcmp(nd->model, "smc91c111") == 0) {

            smc91c111_init(nd, 0x4e000000, pic[28]);

            done_smc = 1;

        } else {

            pci_nic_init(nd, "rtl8139", NULL);

        }

    }

    /* Memory map for RealView Emulation Baseboard:  */

    /* 0x10000000 System registers.  */

    /*  0x10001000 System controller.  */

    /*  0x10002000 Two-Wire Serial Bus.  */

    /* 0x10003000 Reserved.  */

    /*  0x10004000 AACI.  */

    /*  0x10005000 MCI.  */

    /* 0x10006000 KMI0.  */

    /* 0x10007000 KMI1.  */

    /*  0x10008000 Character LCD.  */

    /* 0x10009000 UART0.  */

    /* 0x1000a000 UART1.  */

    /* 0x1000b000 UART2.  */

    /* 0x1000c000 UART3.  */

    /*  0x1000d000 SSPI.  */

    /*  0x1000e000 SCI.  */

    /* 0x1000f000 Reserved.  */

    /*  0x10010000 Watchdog.  */

    /* 0x10011000 Timer 0+1.  */

    /* 0x10012000 Timer 2+3.  */

    /*  0x10013000 GPIO 0.  */

    /*  0x10014000 GPIO 1.  */

    /*  0x10015000 GPIO 2.  */

    /* 0x10016000 Reserved.  */

    /* 0x10017000 RTC.  */

    /*  0x10018000 DMC.  */

    /*  0x10019000 PCI controller config.  */

    /*  0x10020000 CLCD.  */

    /* 0x10030000 DMA Controller.  */

    /* 0x10040000 GIC1.  */

    /* 0x10050000 GIC2.  */

    /* 0x10060000 GIC3.  */

    /* 0x10070000 GIC4.  */

    /*  0x10080000 SMC.  */

    /*  0x40000000 NOR flash.  */

    /*  0x44000000 DoC flash.  */

    /*  0x48000000 SRAM.  */

    /*  0x4c000000 Configuration flash.  */

    /* 0x4e000000 Ethernet.  */

    /*  0x4f000000 USB.  */

    /*  0x50000000 PISMO.  */

    /*  0x54000000 PISMO.  */

    /*  0x58000000 PISMO.  */

    /*  0x5c000000 PISMO.  */

    /* 0x60000000 PCI.  */

    /* 0x61000000 PCI Self Config.  */

    /* 0x62000000 PCI Config.  */

    /* 0x63000000 PCI IO.  */

    /* 0x64000000 PCI mem 0.  */

    /* 0x68000000 PCI mem 1.  */

    /* 0x6c000000 PCI mem 2.  */

    /* ??? Hack to map an additional page of ram for the secondary CPU

       startup code.  I guess this works on real hardware because the

       BootROM happens to be in ROM/flash or in memory that isn't clobbered

       until after Linux boots the secondary CPUs.  */

    ram_offset = qemu_ram_alloc(0x1000);

    cpu_register_physical_memory(0x80000000, 0x1000, ram_offset | IO_MEM_RAM);

    realview_binfo.ram_size = ram_size;

    realview_binfo.kernel_filename = kernel_filename;

    realview_binfo.kernel_cmdline = kernel_cmdline;

    realview_binfo.initrd_filename = initrd_filename;

    realview_binfo.nb_cpus = ncpu;

    arm_load_kernel(first_cpu, &realview_binfo);

}


int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt,

                        const uint8_t *buf, int len)

{

    int len1;

    len1 = len;

    ts->pkt = pkt;

    ts->stop_parse = 0;

    for(;;) {

        if (ts->stop_parse>0)

            break;

        if (len < TS_PACKET_SIZE)

            return -1;

        if (buf[0] != 0x47) {

            buf++;

            len--;

        } else {

            handle_packet(ts, buf);

            buf += TS_PACKET_SIZE;

            len -= TS_PACKET_SIZE;

        }

    }

    return len1 - len;

}


static int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr)

{

    unsigned char *destptr_bak = destptr;

    unsigned char mask = 0;

    unsigned char maskbit = 0;

    unsigned int ofs, cnt;

    while (srclen > 0) {

        if (maskbit == 0) {

            mask = *(srcptr++);

            maskbit = 8;

            srclen--;

            continue;

        }

        if ((mask & (1 << (--maskbit))) == 0) {

            *(int*)destptr = *(int*)srcptr;

            srclen -= 4;

            destptr += 4;

            srcptr += 4;

        } else {

            ofs = *(srcptr++);

            cnt = *(srcptr++);

            ofs += cnt * 256;;

            cnt = ((cnt >> 3) & 0x1f) + 1;

            ofs &= 0x7ff;

            srclen -= 2;

            cnt *= 4;

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

                *(destptr) = *(destptr - ofs);

                destptr++;

            }

        }

    }

    return (destptr - destptr_bak);

}


int ff_split_xiph_headers(uint8_t *extradata, int extradata_size,

                          int first_header_size, uint8_t *header_start[3],

                          int header_len[3])

{

    int i, j;

    if (AV_RB16(extradata) == first_header_size) {

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

            header_len[i] = AV_RB16(extradata);

            extradata += 2;

            header_start[i] = extradata;

            extradata += header_len[i];

        }

    } else if (extradata[0] == 2) {

        for (i=0,j=1; i<2; i++,j++) {

            header_len[i] = 0;

            for (; j<extradata_size && extradata[j]==0xff; j++) {

                header_len[i] += 0xff;

            }

            if (j >= extradata_size)

                return -1;

            header_len[i] += extradata[j];

        }

        header_len[2] = extradata_size - header_len[0] - header_len[1] - j;

        extradata += j;

        header_start[0] = extradata;

        header_start[1] = header_start[0] + header_len[0];

        header_start[2] = header_start[1] + header_len[1];

    } else {

        return -1;

    }

    return 0;

}


static int vp3_decode_init(AVCodecContext *avctx)

{

    Vp3DecodeContext *s = avctx->priv_data;

    int i;

    s->avctx = avctx;

    s->width = avctx->width;

    s->height = avctx->height;

    avctx->pix_fmt = PIX_FMT_YUV420P;

    avctx->has_b_frames = 0;

    dsputil_init(&s->dsp, avctx);

    /* initialize to an impossible value which will force a recalculation

     * in the first frame decode */

    s->quality_index = -1;

    s->superblock_width = (s->width + 31) / 32;

    s->superblock_height = (s->height + 31) / 32;

    s->superblock_count = s->superblock_width * s->superblock_height * 3 / 2;

    s->u_superblock_start = s->superblock_width * s->superblock_height;

    s->v_superblock_start = s->superblock_width * s->superblock_height * 5 / 4;

    s->superblock_coding = av_malloc(s->superblock_count);

    s->macroblock_width = (s->width + 15) / 16;

    s->macroblock_height = (s->height + 15) / 16;

    s->macroblock_count = s->macroblock_width * s->macroblock_height;

    s->fragment_width = s->width / FRAGMENT_PIXELS;

    s->fragment_height = s->height / FRAGMENT_PIXELS;

    /* fragment count covers all 8x8 blocks for all 3 planes */

    s->fragment_count = s->fragment_width * s->fragment_height * 3 / 2;

    s->u_fragment_start = s->fragment_width * s->fragment_height;

    s->v_fragment_start = s->fragment_width * s->fragment_height * 5 / 4;

    debug_init("  width: %d x %d\n", s->width, s->height);

    debug_init("  superblocks: %d x %d, %d total\n",

        s->superblock_width, s->superblock_height, s->superblock_count);

    debug_init("  macroblocks: %d x %d, %d total\n",

        s->macroblock_width, s->macroblock_height, s->macroblock_count);

    debug_init("  %d fragments, %d x %d, u starts @ %d, v starts @ %d\n",

        s->fragment_count,

        s->fragment_width,

        s->fragment_height,

        s->u_fragment_start,

        s->v_fragment_start);

    s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment));

    s->coded_fragment_list = av_malloc(s->fragment_count * sizeof(int));

    s->pixel_addresses_inited = 0;

    /* init VLC tables */

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

        /* Dc histograms */

        init_vlc(&s->dc_vlc[i], 5, 32,

            &dc_bias[i][0][1], 4, 2,

            &dc_bias[i][0][0], 4, 2);

        /* level 1 AC histograms */

        init_vlc(&s->ac_vlc_1[i], 5, 32,

            &ac_bias_0[i][0][1], 4, 2,

            &ac_bias_0[i][0][0], 4, 2);

        /* level 2 AC histograms */

        init_vlc(&s->ac_vlc_2[i], 5, 32,

            &ac_bias_1[i][0][1], 4, 2,

            &ac_bias_1[i][0][0], 4, 2);

        /* level 3 AC histograms */

        init_vlc(&s->ac_vlc_3[i], 5, 32,

            &ac_bias_2[i][0][1], 4, 2,

            &ac_bias_2[i][0][0], 4, 2);

        /* level 4 AC histograms */

        init_vlc(&s->ac_vlc_4[i], 5, 32,

            &ac_bias_3[i][0][1], 4, 2,

            &ac_bias_3[i][0][0], 4, 2);

    }

    /* build quantization table */

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

        quant_index[dequant_index[i]] = i;

    /* work out the block mapping tables */

    s->superblock_fragments = av_malloc(s->superblock_count * 16 * sizeof(int));

    s->superblock_macroblocks = av_malloc(s->superblock_count * 4 * sizeof(int));

    s->macroblock_fragments = av_malloc(s->macroblock_count * 6 * sizeof(int));

    s->macroblock_coded = av_malloc(s->macroblock_count + 1);

    init_block_mapping(s);

    /* make sure that frames are available to be freed on the first decode */

    if(avctx->get_buffer(avctx, &s->golden_frame) < 0) {

        printf("vp3: get_buffer() failed\n");

        return -1;

    }

    return 0;

}


uint16_t qpci_io_readw(QPCIDevice *dev, void *data)

{

    uintptr_t addr = (uintptr_t)data;

    if (addr < QPCI_PIO_LIMIT) {

        return dev->bus->pio_readw(dev->bus, addr);

    } else {

        uint16_t val;

        dev->bus->memread(dev->bus, addr, &val, sizeof(val));

        return le16_to_cpu(val);

    }

}