static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)

{

    AVFilterContext *ctx  = inlink->dst;

    Stereo3DContext *s = ctx->priv;

    AVFilterLink *outlink = ctx->outputs[0];

    AVFrame *out, *oleft, *oright, *ileft, *iright;

    int out_off_left[4], out_off_right[4];

    int i;

    if (s->in.format == s->out.format)

        return ff_filter_frame(outlink, inpicref);

    switch (s->in.format) {

    case ALTERNATING_LR:

    case ALTERNATING_RL:

        if (!s->prev) {

            s->prev = inpicref;

            return 0;

        }

        ileft  = s->prev;

        iright = inpicref;

        if (s->in.format == ALTERNATING_RL)

            FFSWAP(AVFrame *, ileft, iright);

        break;

    default:

        ileft = iright = inpicref;

    };

    if ((s->out.format == ALTERNATING_LR ||

         s->out.format == ALTERNATING_RL) &&

        (s->in.format == SIDE_BY_SIDE_LR ||

         s->in.format == SIDE_BY_SIDE_RL ||

         s->in.format == SIDE_BY_SIDE_2_LR ||

         s->in.format == SIDE_BY_SIDE_2_RL ||

         s->in.format == ABOVE_BELOW_LR ||

         s->in.format == ABOVE_BELOW_RL ||

         s->in.format == ABOVE_BELOW_2_LR ||

         s->in.format == ABOVE_BELOW_2_RL)) {

        oright = av_frame_clone(inpicref);

        oleft  = av_frame_clone(inpicref);

        if (!oright || !oleft) {

            av_frame_free(&oright);

            av_frame_free(&oleft);

            av_frame_free(&s->prev);

            av_frame_free(&inpicref);

            return AVERROR(ENOMEM);

        }

    } else if ((s->out.format == MONO_L ||

                s->out.format == MONO_R) &&

        (s->in.format == SIDE_BY_SIDE_LR ||

         s->in.format == SIDE_BY_SIDE_RL ||

         s->in.format == SIDE_BY_SIDE_2_LR ||

         s->in.format == SIDE_BY_SIDE_2_RL ||

         s->in.format == ABOVE_BELOW_LR ||

         s->in.format == ABOVE_BELOW_RL ||

         s->in.format == ABOVE_BELOW_2_LR ||

         s->in.format == ABOVE_BELOW_2_RL)) {

        out = oleft = oright = av_frame_clone(inpicref);

        if (!out) {

            av_frame_free(&s->prev);

            av_frame_free(&inpicref);

            return AVERROR(ENOMEM);

        }

    } else {

        out = oleft = oright = ff_get_video_buffer(outlink, outlink->w, outlink->h);

        if (!out) {

            av_frame_free(&s->prev);

            av_frame_free(&inpicref);

            return AVERROR(ENOMEM);

        }

        av_frame_copy_props(out, inpicref);

        if (s->out.format == ALTERNATING_LR ||

            s->out.format == ALTERNATING_RL) {

            oright = ff_get_video_buffer(outlink, outlink->w, outlink->h);

            if (!oright) {

                av_frame_free(&oleft);

                av_frame_free(&s->prev);

                av_frame_free(&inpicref);

                return AVERROR(ENOMEM);

            }

            av_frame_copy_props(oright, inpicref);

        }

    }

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

        int hsub = i == 1 || i == 2 ? s->hsub : 0;

        int vsub = i == 1 || i == 2 ? s->vsub : 0;

        s->in_off_left[i]   = (FF_CEIL_RSHIFT(s->in.row_left,   vsub) + s->in.off_lstep)  * ileft->linesize[i]  + FF_CEIL_RSHIFT(s->in.off_left   * s->pixstep[i], hsub);

        s->in_off_right[i]  = (FF_CEIL_RSHIFT(s->in.row_right,  vsub) + s->in.off_rstep)  * iright->linesize[i] + FF_CEIL_RSHIFT(s->in.off_right  * s->pixstep[i], hsub);

        out_off_left[i]  = (FF_CEIL_RSHIFT(s->out.row_left,  vsub) + s->out.off_lstep) * oleft->linesize[i]  + FF_CEIL_RSHIFT(s->out.off_left  * s->pixstep[i], hsub);

        out_off_right[i] = (FF_CEIL_RSHIFT(s->out.row_right, vsub) + s->out.off_rstep) * oright->linesize[i] + FF_CEIL_RSHIFT(s->out.off_right * s->pixstep[i], hsub);

    }

    switch (s->out.format) {

    case ALTERNATING_LR:

    case ALTERNATING_RL:

        switch (s->in.format) {

        case ABOVE_BELOW_LR:

        case ABOVE_BELOW_RL:

        case ABOVE_BELOW_2_LR:

        case ABOVE_BELOW_2_RL:

        case SIDE_BY_SIDE_LR:

        case SIDE_BY_SIDE_RL:

        case SIDE_BY_SIDE_2_LR:

        case SIDE_BY_SIDE_2_RL:

            oleft->width   = outlink->w;

            oright->width  = outlink->w;

            oleft->height  = outlink->h;

            oright->height = outlink->h;

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

                oleft->data[i]  += s->in_off_left[i];

                oright->data[i] += s->in_off_right[i];

            }

            break;

        default:

            goto copy;

            break;

        }

        break;

    case HDMI:

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

            int j, h = s->height >> ((i == 1 || i == 2) ? s->vsub : 0);

            int b = (s->blanks) >> ((i == 1 || i == 2) ? s->vsub : 0);

            for (j = h; j < h + b; j++)

                memset(oleft->data[i] + j * s->linesize[i], 0, s->linesize[i]);

        }

    case SIDE_BY_SIDE_LR:

    case SIDE_BY_SIDE_RL:

    case SIDE_BY_SIDE_2_LR:

    case SIDE_BY_SIDE_2_RL:

    case ABOVE_BELOW_LR:

    case ABOVE_BELOW_RL:

    case ABOVE_BELOW_2_LR:

    case ABOVE_BELOW_2_RL:

    case INTERLEAVE_ROWS_LR:

    case INTERLEAVE_ROWS_RL:

copy:

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

            av_image_copy_plane(oleft->data[i] + out_off_left[i],

                                oleft->linesize[i] * s->out.row_step,

                                ileft->data[i] + s->in_off_left[i],

                                ileft->linesize[i] * s->in.row_step,

                                s->linesize[i], s->pheight[i]);

            av_image_copy_plane(oright->data[i] + out_off_right[i],

                                oright->linesize[i] * s->out.row_step,

                                iright->data[i] + s->in_off_right[i],

                                iright->linesize[i] * s->in.row_step,

                                s->linesize[i], s->pheight[i]);

        }

        break;

    case MONO_L:

        iright = ileft;

    case MONO_R:

        switch (s->in.format) {

        case ABOVE_BELOW_LR:

        case ABOVE_BELOW_RL:

        case ABOVE_BELOW_2_LR:

        case ABOVE_BELOW_2_RL:

        case SIDE_BY_SIDE_LR:

        case SIDE_BY_SIDE_RL:

        case SIDE_BY_SIDE_2_LR:

        case SIDE_BY_SIDE_2_RL:

            out->width  = outlink->w;

            out->height = outlink->h;

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

                out->data[i] += s->in_off_left[i];

            }

            break;

        default:

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

                av_image_copy_plane(out->data[i], out->linesize[i],

                                    iright->data[i] + s->in_off_left[i],

                                    iright->linesize[i] * s->in.row_step,

                                    s->linesize[i], s->pheight[i]);

            }

            break;

        }

        break;

    case ANAGLYPH_RB_GRAY:

    case ANAGLYPH_RG_GRAY:

    case ANAGLYPH_RC_GRAY:

    case ANAGLYPH_RC_HALF:

    case ANAGLYPH_RC_COLOR:

    case ANAGLYPH_RC_DUBOIS:

    case ANAGLYPH_GM_GRAY:

    case ANAGLYPH_GM_HALF:

    case ANAGLYPH_GM_COLOR:

    case ANAGLYPH_GM_DUBOIS:

    case ANAGLYPH_YB_GRAY:

    case ANAGLYPH_YB_HALF:

    case ANAGLYPH_YB_COLOR:

    case ANAGLYPH_YB_DUBOIS: {

        ThreadData td;

        td.ileft = ileft; td.iright = iright; td.out = out;

        ctx->internal->execute(ctx, filter_slice, &td, NULL,

                               FFMIN(s->out.height, ctx->graph->nb_threads));

        break;

    }

    case CHECKERBOARD_RL:

    case CHECKERBOARD_LR:

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

            int x, y;

            for (y = 0; y < s->pheight[i]; y++) {

                uint8_t *dst = out->data[i] + out->linesize[i] * y;

                uint8_t *left = ileft->data[i] + ileft->linesize[i] * y + s->in_off_left[i];

                uint8_t *right = iright->data[i] + iright->linesize[i] * y + s->in_off_right[i];

                int p, b;

                if (s->out.format == CHECKERBOARD_RL)

                    FFSWAP(uint8_t*, left, right);

                switch (s->pixstep[i]) {

                case 1:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=2, p++, b++) {

                        dst[x  ] = (b&1) == (y&1) ? left[p] : right[p];

                        dst[x+1] = (b&1) != (y&1) ? left[p] : right[p];

                    }

                    break;

                case 2:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=4, p+=2, b++) {

                        AV_WN16(&dst[x  ], (b&1) == (y&1) ? AV_RN16(&left[p]) : AV_RN16(&right[p]));

                        AV_WN16(&dst[x+2], (b&1) != (y&1) ? AV_RN16(&left[p]) : AV_RN16(&right[p]));

                    }

                    break;

                case 3:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=6, p+=3, b++) {

                        AV_WB24(&dst[x  ], (b&1) == (y&1) ? AV_RB24(&left[p]) : AV_RB24(&right[p]));

                        AV_WB24(&dst[x+3], (b&1) != (y&1) ? AV_RB24(&left[p]) : AV_RB24(&right[p]));

                    }

                    break;

                case 4:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=8, p+=4, b++) {

                        AV_WN32(&dst[x  ], (b&1) == (y&1) ? AV_RN32(&left[p]) : AV_RN32(&right[p]));

                        AV_WN32(&dst[x+4], (b&1) != (y&1) ? AV_RN32(&left[p]) : AV_RN32(&right[p]));

                    }

                    break;

                case 6:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=12, p+=6, b++) {

                        AV_WB48(&dst[x  ], (b&1) == (y&1) ? AV_RB48(&left[p]) : AV_RB48(&right[p]));

                        AV_WB48(&dst[x+6], (b&1) != (y&1) ? AV_RB48(&left[p]) : AV_RB48(&right[p]));

                    }

                    break;

                case 8:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=16, p+=8, b++) {

                        AV_WN64(&dst[x  ], (b&1) == (y&1) ? AV_RN64(&left[p]) : AV_RN64(&right[p]));

                        AV_WN64(&dst[x+8], (b&1) != (y&1) ? AV_RN64(&left[p]) : AV_RN64(&right[p]));

                    }

                    break;

                }

            }

        }

        break;

    case INTERLEAVE_COLS_LR:

    case INTERLEAVE_COLS_RL:

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

            int x, y;

            for (y = 0; y < s->pheight[i]; y++) {

                uint8_t *dst = out->data[i] + out->linesize[i] * y;

                uint8_t *left = ileft->data[i] + ileft->linesize[i] * y * s->in.row_step + s->in_off_left[i];

                uint8_t *right = iright->data[i] + iright->linesize[i] * y * s->in.row_step + s->in_off_right[i];

                int p, b;

                if (s->out.format == INTERLEAVE_COLS_LR)

                    FFSWAP(uint8_t*, left, right);

                switch (s->pixstep[i]) {

                case 1:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=2, p++, b++) {

                        dst[x  ] =   b&1  ? left[p] : right[p];

                        dst[x+1] = !(b&1) ? left[p] : right[p];

                    }

                    break;

                case 2:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=4, p+=2, b++) {

                        AV_WN16(&dst[x  ],   b&1  ? AV_RN16(&left[p]) : AV_RN16(&right[p]));

                        AV_WN16(&dst[x+2], !(b&1) ? AV_RN16(&left[p]) : AV_RN16(&right[p]));

                    }

                    break;

                case 3:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=6, p+=3, b++) {

                        AV_WB24(&dst[x  ],   b&1  ? AV_RB24(&left[p]) : AV_RB24(&right[p]));

                        AV_WB24(&dst[x+3], !(b&1) ? AV_RB24(&left[p]) : AV_RB24(&right[p]));

                    }

                    break;

                case 4:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=8, p+=4, b++) {

                        AV_WN32(&dst[x  ],   b&1  ? AV_RN32(&left[p]) : AV_RN32(&right[p]));

                        AV_WN32(&dst[x+4], !(b&1) ? AV_RN32(&left[p]) : AV_RN32(&right[p]));

                    }

                    break;

                case 6:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=12, p+=6, b++) {

                        AV_WB48(&dst[x  ],   b&1  ? AV_RB48(&left[p]) : AV_RB48(&right[p]));

                        AV_WB48(&dst[x+6], !(b&1) ? AV_RB48(&left[p]) : AV_RB48(&right[p]));

                    }

                    break;

                case 8:

                    for (x = 0, b = 0, p = 0; x < s->linesize[i] * 2; x+=16, p+=8, b++) {

                        AV_WN64(&dst[x  ],   b&1 ?  AV_RN64(&left[p]) : AV_RN64(&right[p]));

                        AV_WN64(&dst[x+8], !(b&1) ? AV_RN64(&left[p]) : AV_RN64(&right[p]));

                    }

                    break;

                }

            }

        }

        break;

    default:

        av_assert0(0);

    }

    av_frame_free(&inpicref);

    av_frame_free(&s->prev);

    if (oright != oleft) {

        if (s->out.format == ALTERNATING_LR)

            FFSWAP(AVFrame *, oleft, oright);

        oright->pts = outlink->frame_count * s->ts_unit;

        ff_filter_frame(outlink, oright);

        out = oleft;

        oleft->pts = outlink->frame_count * s->ts_unit;

    } else if (s->in.format == ALTERNATING_LR ||

               s->in.format == ALTERNATING_RL) {

        out->pts = outlink->frame_count * s->ts_unit;

    }

    return ff_filter_frame(outlink, out);

}


static int unpack_parse_unit(DiracParseUnit *pu, DiracParseContext *pc,

                             int offset)

{

    int8_t *start;

    if (offset < 0 || pc->index - 13 < offset)

        return 0;

    start = pc->buffer + offset;

    pu->pu_type = start[4];

    pu->next_pu_offset = AV_RB32(start + 5);

    pu->prev_pu_offset = AV_RB32(start + 9);

    if (pu->pu_type == 0x10 && pu->next_pu_offset == 0)

        pu->next_pu_offset = 13;

    if (pu->next_pu_offset && pu->next_pu_offset < 13) {

        av_log(NULL, AV_LOG_ERROR, "next_pu_offset %d is invalid\n", pu->next_pu_offset);

        return 0;

    }

    if (pu->prev_pu_offset && pu->prev_pu_offset < 13) {

        av_log(NULL, AV_LOG_ERROR, "prev_pu_offset %d is invalid\n", pu->prev_pu_offset);

        return 0;

    }

    return 1;

}


static void quantize_all(DCAEncContext *c)

{

    int sample, band, ch;

    for (sample = 0; sample < SUBBAND_SAMPLES; sample++)

        for (band = 0; band < 32; band++)

            for (ch = 0; ch < c->fullband_channels; ch++)

                c->quantized[sample][band][ch] = quantize_value(c->subband[sample][band][ch], c->quant[band][ch]);

}


static int video_thread(void *arg)

{

    VideoState *is = arg;

    AVPacket pkt1, *pkt = &pkt1;

    int len1, got_picture;

    AVFrame *frame= avcodec_alloc_frame();

    double pts;

    for(;;) {

        while (is->paused && !is->videoq.abort_request) {

            SDL_Delay(10);

        }

        if (packet_queue_get(&is->videoq, pkt, 1) < 0)

            break;

        if(pkt->data == flush_pkt.data){

            avcodec_flush_buffers(is->video_st->codec);

            is->last_dts_for_fault_detection=

            is->last_pts_for_fault_detection= INT64_MIN;

            continue;

        }

        /* NOTE: ipts is the PTS of the _first_ picture beginning in

           this packet, if any */

        is->video_st->codec->reordered_opaque= pkt->pts;

        len1 = avcodec_decode_video2(is->video_st->codec,

                                    frame, &got_picture,

                                    pkt);

        if(pkt->dts != AV_NOPTS_VALUE){

            is->faulty_dts += pkt->dts <= is->last_dts_for_fault_detection;

            is->last_dts_for_fault_detection= pkt->dts;

        }

        if(frame->reordered_opaque != AV_NOPTS_VALUE){

            is->faulty_pts += frame->reordered_opaque <= is->last_pts_for_fault_detection;

            is->last_pts_for_fault_detection= frame->reordered_opaque;

        }

        if(   (   decoder_reorder_pts==1

               || decoder_reorder_pts && is->faulty_pts<is->faulty_dts

               || pkt->dts == AV_NOPTS_VALUE)

           && frame->reordered_opaque != AV_NOPTS_VALUE)

            pts= frame->reordered_opaque;

        else if(pkt->dts != AV_NOPTS_VALUE)

            pts= pkt->dts;

        else

            pts= 0;

        pts *= av_q2d(is->video_st->time_base);

//            if (len1 < 0)

//                break;

        if (got_picture) {

            if (output_picture2(is, frame, pts) < 0)

                goto the_end;

        }

        av_free_packet(pkt);

        if (step)

            if (cur_stream)

                stream_pause(cur_stream);

    }

 the_end:

    av_free(frame);

    return 0;

}


static int nut_write_header(AVFormatContext *s)

{

    NUTContext *nut = s->priv_data;

    AVIOContext *bc = s->pb;

    int i, j, ret;

    nut->avf = s;

    nut->version = FFMAX(NUT_STABLE_VERSION, 3 + !!nut->flags);

    if (nut->flags && s->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {

        av_log(s, AV_LOG_ERROR,

               "The additional syncpoint modes require version %d, "

               "that is currently not finalized, "

               "please set -f_strict experimental in order to enable it.\n",

               nut->version);

        return AVERROR_EXPERIMENTAL;

    }

    nut->stream   = av_calloc(s->nb_streams,  sizeof(*nut->stream ));

    nut->chapter  = av_calloc(s->nb_chapters, sizeof(*nut->chapter));

    nut->time_base= av_calloc(s->nb_streams +

                              s->nb_chapters, sizeof(*nut->time_base));

    if (!nut->stream || !nut->chapter || !nut->time_base) {

        av_freep(&nut->stream);

        av_freep(&nut->chapter);

        av_freep(&nut->time_base);

        return AVERROR(ENOMEM);

    }

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

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

        int ssize;

        AVRational time_base;

        ff_parse_specific_params(st->codec, &time_base.den, &ssize, &time_base.num);

        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->sample_rate) {

            time_base = (AVRational) {1, st->codec->sample_rate};

        } else {

            time_base = ff_choose_timebase(s, st, 48000);

        }

        avpriv_set_pts_info(st, 64, time_base.num, time_base.den);

        for (j = 0; j < nut->time_base_count; j++)

            if (!memcmp(&time_base, &nut->time_base[j], sizeof(AVRational))) {

                break;

            }

        nut->time_base[j]        = time_base;

        nut->stream[i].time_base = &nut->time_base[j];

        if (j == nut->time_base_count)

            nut->time_base_count++;

        if (INT64_C(1000) * time_base.num >= time_base.den)

            nut->stream[i].msb_pts_shift = 7;

        else

            nut->stream[i].msb_pts_shift = 14;

        nut->stream[i].max_pts_distance =

            FFMAX(time_base.den, time_base.num) / time_base.num;

    }

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

        AVChapter *ch = s->chapters[i];

        for (j = 0; j < nut->time_base_count; j++)

            if (!memcmp(&ch->time_base, &nut->time_base[j], sizeof(AVRational)))

                break;

        nut->time_base[j]         = ch->time_base;

        nut->chapter[i].time_base = &nut->time_base[j];

        if (j == nut->time_base_count)

            nut->time_base_count++;

    }

    nut->max_distance = MAX_DISTANCE;

    build_elision_headers(s);

    build_frame_code(s);

    av_assert0(nut->frame_code['N'].flags == FLAG_INVALID);

    avio_write(bc, ID_STRING, strlen(ID_STRING));

    avio_w8(bc, 0);

    if ((ret = write_headers(s, bc)) < 0)

        return ret;

    if (s->avoid_negative_ts < 0)

        s->avoid_negative_ts = 1;

    avio_flush(bc);

    return 0;

}


static void skip_input(DBEContext *s, int nb_words)

{

    s->input      += nb_words * s->word_bytes;

    s->input_size -= nb_words;

}


static void g364fb_screen_dump(void *opaque, const char *filename)
{
    G364State *s = opaque;
    int y, x;
    uint8_t index;
    uint8_t *data_buffer;
    FILE *f;
    if (s->depth != 8) {
        error_report("g364: unknown guest depth %d", s->depth);
        return;
    }
    f = fopen(filename, "wb");
    if (!f)
        return;
    if (s->ctla & CTLA_FORCE_BLANK) {
        /* blank screen */
        fprintf(f, "P4\n%d %d\n",
            s->width, s->height);
        for (y = 0; y < s->height; y++)
            for (x = 0; x < s->width; x++)
                fputc(0, f);
    } else {
        data_buffer = s->vram + s->top_of_screen;
        fprintf(f, "P6\n%d %d\n%d\n",
            s->width, s->height, 255);
        for (y = 0; y < s->height; y++)
            for (x = 0; x < s->width; x++, data_buffer++) {
                index = *data_buffer;
                fputc(s->color_palette[index][0], f);
                fputc(s->color_palette[index][1], f);
                fputc(s->color_palette[index][2], f);
        }
    }
    fclose(f);
}


int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)

{

    Coroutine *co;

    DiscardCo rwco = {

        .bs = bs,

        .sector_num = sector_num,

        .nb_sectors = nb_sectors,

        .ret = NOT_DONE,

    };

    if (qemu_in_coroutine()) {

        /* Fast-path if already in coroutine context */

        bdrv_discard_co_entry(&rwco);

    } else {

        AioContext *aio_context = bdrv_get_aio_context(bs);

        co = qemu_coroutine_create(bdrv_discard_co_entry);

        qemu_coroutine_enter(co, &rwco);

        while (rwco.ret == NOT_DONE) {

            aio_poll(aio_context, true);

        }

    }

    return rwco.ret;

}


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

{

    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    CG3State *s = CG3(dev);

    int ret;

    char *fcode_filename;

    /* FCode ROM */

    vmstate_register_ram_global(&s->rom);

    fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, CG3_ROM_FILE);

    if (fcode_filename) {

        ret = load_image_targphys(fcode_filename, s->prom_addr,

                                  FCODE_MAX_ROM_SIZE);

        g_free(fcode_filename);

        if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {

            error_report("cg3: could not load prom '%s'", CG3_ROM_FILE);

        }

    }

    memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size,

                           &error_abort);

    memory_region_set_log(&s->vram_mem, true, DIRTY_MEMORY_VGA);

    vmstate_register_ram_global(&s->vram_mem);

    sysbus_init_mmio(sbd, &s->vram_mem);

    sysbus_init_irq(sbd, &s->irq);

    s->con = graphic_console_init(DEVICE(dev), 0, &cg3_ops, s);

    qemu_console_resize(s->con, s->width, s->height);

}


static void virtio_gpu_set_scanout(VirtIOGPU *g,

                                   struct virtio_gpu_ctrl_command *cmd)

{

    struct virtio_gpu_simple_resource *res;

    struct virtio_gpu_scanout *scanout;

    pixman_format_code_t format;

    uint32_t offset;

    int bpp;

    struct virtio_gpu_set_scanout ss;

    VIRTIO_GPU_FILL_CMD(ss);

    trace_virtio_gpu_cmd_set_scanout(ss.scanout_id, ss.resource_id,

                                     ss.r.width, ss.r.height, ss.r.x, ss.r.y);

    if (ss.scanout_id >= g->conf.max_outputs) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout id specified %d",

                      __func__, ss.scanout_id);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

        return;

    }

    g->enable = 1;

    if (ss.resource_id == 0) {

        scanout = &g->scanout[ss.scanout_id];

        if (scanout->resource_id) {

            res = virtio_gpu_find_resource(g, scanout->resource_id);

            if (res) {

                res->scanout_bitmask &= ~(1 << ss.scanout_id);

            }

        }

        if (ss.scanout_id == 0) {

            qemu_log_mask(LOG_GUEST_ERROR,

                          "%s: illegal scanout id specified %d",

                          __func__, ss.scanout_id);

            cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID;

            return;

        }

        dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, NULL);

        scanout->ds = NULL;

        scanout->width = 0;

        scanout->height = 0;

        return;

    }

    /* create a surface for this scanout */

    res = virtio_gpu_find_resource(g, ss.resource_id);

    if (!res) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal resource specified %d\n",

                      __func__, ss.resource_id);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;

        return;

    }

    if (ss.r.x > res->width ||

        ss.r.y > res->height ||

        ss.r.width > res->width ||

        ss.r.height > res->height ||

        ss.r.x + ss.r.width > res->width ||

        ss.r.y + ss.r.height > res->height) {

        qemu_log_mask(LOG_GUEST_ERROR, "%s: illegal scanout %d bounds for"

                      " resource %d, (%d,%d)+%d,%d vs %d %d\n",

                      __func__, ss.scanout_id, ss.resource_id, ss.r.x, ss.r.y,

                      ss.r.width, ss.r.height, res->width, res->height);

        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;

        return;

    }

    scanout = &g->scanout[ss.scanout_id];

    format = pixman_image_get_format(res->image);

    bpp = (PIXMAN_FORMAT_BPP(format) + 7) / 8;

    offset = (ss.r.x * bpp) + ss.r.y * pixman_image_get_stride(res->image);

    if (!scanout->ds || surface_data(scanout->ds)

        != ((uint8_t *)pixman_image_get_data(res->image) + offset) ||

        scanout->width != ss.r.width ||

        scanout->height != ss.r.height) {

        pixman_image_t *rect;

        void *ptr = (uint8_t *)pixman_image_get_data(res->image) + offset;

        rect = pixman_image_create_bits(format, ss.r.width, ss.r.height, ptr,

                                        pixman_image_get_stride(res->image));

        pixman_image_ref(res->image);

        pixman_image_set_destroy_function(rect, virtio_unref_resource,

                                          res->image);

        /* realloc the surface ptr */

        scanout->ds = qemu_create_displaysurface_pixman(rect);

        if (!scanout->ds) {

            cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;

            return;

        }

        dpy_gfx_replace_surface(g->scanout[ss.scanout_id].con, scanout->ds);

    }

    res->scanout_bitmask |= (1 << ss.scanout_id);

    scanout->resource_id = ss.resource_id;

    scanout->x = ss.r.x;

    scanout->y = ss.r.y;

    scanout->width = ss.r.width;

    scanout->height = ss.r.height;

}


void kbd_put_keycode(int keycode)

{

    QEMUPutKbdEntry *entry = QTAILQ_FIRST(&kbd_handlers);

    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {

        return;

    }

    if (entry) {

        entry->put_kbd(entry->opaque, keycode);

    }

}


static av_cold int libx265_encode_init(AVCodecContext *avctx)

{

    libx265Context *ctx = avctx->priv_data;

    ctx->api = x265_api_get(av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth);

    if (!ctx->api)

        ctx->api = x265_api_get(0);

    ctx->params = ctx->api->param_alloc();

    if (!ctx->params) {

        av_log(avctx, AV_LOG_ERROR, "Could not allocate x265 param structure.\n");

        return AVERROR(ENOMEM);

    if (ctx->api->param_default_preset(ctx->params, ctx->preset, ctx->tune) < 0) {

        int i;

        av_log(avctx, AV_LOG_ERROR, "Error setting preset/tune %s/%s.\n", ctx->preset, ctx->tune);

        av_log(avctx, AV_LOG_INFO, "Possible presets:");

        for (i = 0; x265_preset_names[i]; i++)

            av_log(avctx, AV_LOG_INFO, " %s", x265_preset_names[i]);

        av_log(avctx, AV_LOG_INFO, "\n");

        av_log(avctx, AV_LOG_INFO, "Possible tunes:");

        for (i = 0; x265_tune_names[i]; i++)

            av_log(avctx, AV_LOG_INFO, " %s", x265_tune_names[i]);

        av_log(avctx, AV_LOG_INFO, "\n");

        return AVERROR(EINVAL);

    ctx->params->frameNumThreads = avctx->thread_count;

    ctx->params->fpsNum          = avctx->time_base.den;

    ctx->params->fpsDenom        = avctx->time_base.num * avctx->ticks_per_frame;

    ctx->params->sourceWidth     = avctx->width;

    ctx->params->sourceHeight    = avctx->height;

    ctx->params->bEnablePsnr     = !!(avctx->flags & AV_CODEC_FLAG_PSNR);

    if ((avctx->color_primaries <= AVCOL_PRI_BT2020 &&

         avctx->color_primaries != AVCOL_PRI_UNSPECIFIED) ||

        (avctx->color_trc <= AVCOL_TRC_BT2020_12 &&

         avctx->color_trc != AVCOL_TRC_UNSPECIFIED) ||

        (avctx->colorspace <= AVCOL_SPC_BT2020_CL &&

         avctx->colorspace != AVCOL_SPC_UNSPECIFIED)) {

        ctx->params->vui.bEnableVideoSignalTypePresentFlag  = 1;

        ctx->params->vui.bEnableColorDescriptionPresentFlag = 1;

        // x265 validates the parameters internally

        ctx->params->vui.colorPrimaries          = avctx->color_primaries;

        ctx->params->vui.transferCharacteristics = avctx->color_trc;

        ctx->params->vui.matrixCoeffs            = avctx->colorspace;

    if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) {

        char sar[12];

        int sar_num, sar_den;

        av_reduce(&sar_num, &sar_den,

                  avctx->sample_aspect_ratio.num,

                  avctx->sample_aspect_ratio.den, 65535);

        snprintf(sar, sizeof(sar), "%d:%d", sar_num, sar_den);

        if (ctx->api->param_parse(ctx->params, "sar", sar) == X265_PARAM_BAD_VALUE) {

            av_log(avctx, AV_LOG_ERROR, "Invalid SAR: %d:%d.\n", sar_num, sar_den);

    switch (avctx->pix_fmt) {

    case AV_PIX_FMT_YUV420P:

    case AV_PIX_FMT_YUV420P10:

    case AV_PIX_FMT_YUV420P12:

        ctx->params->internalCsp = X265_CSP_I420;

    case AV_PIX_FMT_YUV422P:

    case AV_PIX_FMT_YUV422P10:

    case AV_PIX_FMT_YUV422P12:

        ctx->params->internalCsp = X265_CSP_I422;

    case AV_PIX_FMT_GBRP:

    case AV_PIX_FMT_GBRP10:

    case AV_PIX_FMT_GBRP12:

        ctx->params->vui.matrixCoeffs = AVCOL_SPC_RGB;

        ctx->params->vui.bEnableVideoSignalTypePresentFlag  = 1;

        ctx->params->vui.bEnableColorDescriptionPresentFlag = 1;

    case AV_PIX_FMT_YUV444P:

    case AV_PIX_FMT_YUV444P10:

    case AV_PIX_FMT_YUV444P12:

        ctx->params->internalCsp = X265_CSP_I444;

    if (ctx->crf >= 0) {

        char crf[6];

        snprintf(crf, sizeof(crf), "%2.2f", ctx->crf);

        if (ctx->api->param_parse(ctx->params, "crf", crf) == X265_PARAM_BAD_VALUE) {

            av_log(avctx, AV_LOG_ERROR, "Invalid crf: %2.2f.\n", ctx->crf);

            return AVERROR(EINVAL);

    } else if (avctx->bit_rate > 0) {

        ctx->params->rc.bitrate         = avctx->bit_rate / 1000;

        ctx->params->rc.rateControlMode = X265_RC_ABR;

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

        ctx->params->bRepeatHeaders = 1;

    if (ctx->x265_opts) {

        AVDictionary *dict    = NULL;

        AVDictionaryEntry *en = NULL;

        if (!av_dict_parse_string(&dict, ctx->x265_opts, "=", ":", 0)) {

            while ((en = av_dict_get(dict, "", en, AV_DICT_IGNORE_SUFFIX))) {

                int parse_ret = ctx->api->param_parse(ctx->params, en->key, en->value);

                switch (parse_ret) {

                case X265_PARAM_BAD_NAME:

                    av_log(avctx, AV_LOG_WARNING,

                          "Unknown option: %s.\n", en->key);

                case X265_PARAM_BAD_VALUE:

                    av_log(avctx, AV_LOG_WARNING,

                          "Invalid value for %s: %s.\n", en->key, en->value);

                default:

            av_dict_free(&dict);

    ctx->encoder = ctx->api->encoder_open(ctx->params);

    if (!ctx->encoder) {

        av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n");

        libx265_encode_close(avctx);

    if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {

        x265_nal *nal;

        int nnal;

        avctx->extradata_size = ctx->api->encoder_headers(ctx->encoder, &nal, &nnal);

        if (avctx->extradata_size <= 0) {

            av_log(avctx, AV_LOG_ERROR, "Cannot encode headers.\n");

            libx265_encode_close(avctx);

        avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);

        if (!avctx->extradata) {

                   "Cannot allocate HEVC header of size %d.\n", avctx->extradata_size);

            libx265_encode_close(avctx);

            return AVERROR(ENOMEM);

        memcpy(avctx->extradata, nal[0].payload, avctx->extradata_size);

    return 0;


static void nbd_coroutine_end(BlockDriverState *bs,

                              NBDRequest *request)

{

    NBDClientSession *s = nbd_get_client_session(bs);

    int i = HANDLE_TO_INDEX(s, request->handle);

    s->recv_coroutine[i] = NULL;

    s->in_flight--;

    qemu_co_queue_next(&s->free_sema);

    /* Kick the read_reply_co to get the next reply.  */

    if (s->read_reply_co) {

        aio_co_wake(s->read_reply_co);

    }

}


static int dump_init(DumpState *s, int fd, bool has_format,

                     DumpGuestMemoryFormat format, bool paging, bool has_filter,

                     int64_t begin, int64_t length, Error **errp)

{

    CPUState *cpu;

    int nr_cpus;

    Error *err = NULL;

    int ret;

    /* kdump-compressed is conflict with paging and filter */

    if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {

        assert(!paging && !has_filter);

    }

    if (runstate_is_running()) {

        vm_stop(RUN_STATE_SAVE_VM);

        s->resume = true;

    } else {

        s->resume = false;

    }

    /* If we use KVM, we should synchronize the registers before we get dump

     * info or physmap info.

     */

    cpu_synchronize_all_states();

    nr_cpus = 0;

    CPU_FOREACH(cpu) {

        nr_cpus++;

    }

    s->fd = fd;

    s->has_filter = has_filter;

    s->begin = begin;

    s->length = length;

    guest_phys_blocks_init(&s->guest_phys_blocks);

    guest_phys_blocks_append(&s->guest_phys_blocks);

    s->start = get_start_block(s);

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

        error_set(errp, QERR_INVALID_PARAMETER, "begin");

        goto cleanup;

    }

    /* get dump info: endian, class and architecture.

     * If the target architecture is not supported, cpu_get_dump_info() will

     * return -1.

     */

    ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);

    if (ret < 0) {

        error_set(errp, QERR_UNSUPPORTED);

        goto cleanup;

    }

    s->note_size = cpu_get_note_size(s->dump_info.d_class,

                                     s->dump_info.d_machine, nr_cpus);

    if (s->note_size < 0) {

        error_set(errp, QERR_UNSUPPORTED);

        goto cleanup;

    }

    /* get memory mapping */

    memory_mapping_list_init(&s->list);

    if (paging) {

        qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err);

        if (err != NULL) {

            error_propagate(errp, err);

            goto cleanup;

        }

    } else {

        qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);

    }

    s->nr_cpus = nr_cpus;

    get_max_mapnr(s);

    uint64_t tmp;

    tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), TARGET_PAGE_SIZE);

    s->len_dump_bitmap = tmp * TARGET_PAGE_SIZE;

    /* init for kdump-compressed format */

    if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {

        switch (format) {

        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:

            s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;

            break;

        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:

#ifdef CONFIG_LZO

            if (lzo_init() != LZO_E_OK) {

                error_setg(errp, "failed to initialize the LZO library");

                goto cleanup;

            }

#endif

            s->flag_compress = DUMP_DH_COMPRESSED_LZO;

            break;

        case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:

            s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;

            break;

        default:

            s->flag_compress = 0;

        }

        return 0;

    }

    if (s->has_filter) {

        memory_mapping_filter(&s->list, s->begin, s->length);

    }

    /*

     * calculate phdr_num

     *

     * the type of ehdr->e_phnum is uint16_t, so we should avoid overflow

     */

    s->phdr_num = 1; /* PT_NOTE */

    if (s->list.num < UINT16_MAX - 2) {

        s->phdr_num += s->list.num;

        s->have_section = false;

    } else {

        s->have_section = true;

        s->phdr_num = PN_XNUM;

        s->sh_info = 1; /* PT_NOTE */

        /* the type of shdr->sh_info is uint32_t, so we should avoid overflow */

        if (s->list.num <= UINT32_MAX - 1) {

            s->sh_info += s->list.num;

        } else {

            s->sh_info = UINT32_MAX;

        }

    }

    if (s->dump_info.d_class == ELFCLASS64) {

        if (s->have_section) {

            s->memory_offset = sizeof(Elf64_Ehdr) +

                               sizeof(Elf64_Phdr) * s->sh_info +

                               sizeof(Elf64_Shdr) + s->note_size;

        } else {

            s->memory_offset = sizeof(Elf64_Ehdr) +

                               sizeof(Elf64_Phdr) * s->phdr_num + s->note_size;

        }

    } else {

        if (s->have_section) {

            s->memory_offset = sizeof(Elf32_Ehdr) +

                               sizeof(Elf32_Phdr) * s->sh_info +

                               sizeof(Elf32_Shdr) + s->note_size;

        } else {

            s->memory_offset = sizeof(Elf32_Ehdr) +

                               sizeof(Elf32_Phdr) * s->phdr_num + s->note_size;

        }

    }

    return 0;

cleanup:

    guest_phys_blocks_free(&s->guest_phys_blocks);

    if (s->resume) {

        vm_start();

    }

    return -1;

}


static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit,

                                 int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))

{

    return wrap_timestamp(s->streams[stream_index], read_timestamp(s, stream_index, ppos, pos_limit));

}


gboolean vnc_client_io(QIOChannel *ioc G_GNUC_UNUSED,

                       GIOCondition condition, void *opaque)

{

    VncState *vs = opaque;

    if (condition & G_IO_IN) {

        vnc_client_read(vs);

    }

    if (condition & G_IO_OUT) {

        vnc_client_write(vs);

    }

    return TRUE;

}


float128 float128_scalbn( float128 a, int n STATUS_PARAM )

{

    flag aSign;

    int32 aExp;

    uint64_t aSig0, aSig1;

    aSig1 = extractFloat128Frac1( a );

    aSig0 = extractFloat128Frac0( a );

    aExp = extractFloat128Exp( a );

    aSign = extractFloat128Sign( a );

    if ( aExp == 0x7FFF ) {

        return a;

    }

    if ( aExp != 0 )

        aSig0 |= LIT64( 0x0001000000000000 );

    else if ( aSig0 == 0 && aSig1 == 0 )

        return a;

    aExp += n - 1;

    return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1

                                          STATUS_VAR );

}


static void process_synthesis_subpackets(QDM2Context *q, QDM2SubPNode *list)

{

    QDM2SubPNode *nodes[4];

    nodes[0] = qdm2_search_subpacket_type_in_list(list, 9);

    if (nodes[0] != NULL)

        process_subpacket_9(q, nodes[0]);

    nodes[1] = qdm2_search_subpacket_type_in_list(list, 10);

    if (nodes[1] != NULL)

        process_subpacket_10(q, nodes[1]);

    else

        process_subpacket_10(q, NULL);

    nodes[2] = qdm2_search_subpacket_type_in_list(list, 11);

    if (nodes[0] != NULL && nodes[1] != NULL && nodes[2] != NULL)

        process_subpacket_11(q, nodes[2]);

    else

        process_subpacket_11(q, NULL);

    nodes[3] = qdm2_search_subpacket_type_in_list(list, 12);

    if (nodes[0] != NULL && nodes[1] != NULL && nodes[3] != NULL)

        process_subpacket_12(q, nodes[3]);

    else

        process_subpacket_12(q, NULL);

}


static int ffm_read_data(AVFormatContext *s,

                         uint8_t *buf, int size, int header)

{

    FFMContext *ffm = s->priv_data;

    AVIOContext *pb = s->pb;

    int len, fill_size, size1, frame_offset, id;

    int64_t last_pos = -1;

    size1 = size;

    while (size > 0) {

    redo:

        len = ffm->packet_end - ffm->packet_ptr;

        if (len < 0)

            return -1;

        if (len > size)

            len = size;

        if (len == 0) {

            if (avio_tell(pb) == ffm->file_size)

                avio_seek(pb, ffm->packet_size, SEEK_SET);

    retry_read:

            if (pb->buffer_size != ffm->packet_size) {

                int64_t tell = avio_tell(pb);

                ffio_set_buf_size(pb, ffm->packet_size);

                avio_seek(pb, tell, SEEK_SET);

            }

            id = avio_rb16(pb); /* PACKET_ID */

            if (id != PACKET_ID) {

                if (ffm_resync(s, id) < 0)

                    return -1;

                last_pos = avio_tell(pb);

            }

            fill_size = avio_rb16(pb);

            ffm->dts = avio_rb64(pb);

            frame_offset = avio_rb16(pb);

            avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);

            ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);

            if (ffm->packet_end < ffm->packet || frame_offset < 0)

                return -1;

            /* if first packet or resynchronization packet, we must

               handle it specifically */

            if (ffm->first_packet || (frame_offset & 0x8000)) {

                if (!frame_offset) {

                    /* This packet has no frame headers in it */

                    if (avio_tell(pb) >= ffm->packet_size * 3LL) {

                        int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos);

                        seekback = FFMAX(seekback, 0);

                        avio_seek(pb, -seekback, SEEK_CUR);

                        goto retry_read;

                    }

                    /* This is bad, we cannot find a valid frame header */

                    return 0;

                }

                ffm->first_packet = 0;

                if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE)

                    return -1;

                ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;

                if (!header)

                    break;

            } else {

                ffm->packet_ptr = ffm->packet;

            }

            goto redo;

        }

        memcpy(buf, ffm->packet_ptr, len);

        buf += len;

        ffm->packet_ptr += len;

        size -= len;

        header = 0;

    }

    return size1 - size;

}


static int udp_close(URLContext *h)

{

    UDPContext *s = h->priv_data;

    int ret;

    if (s->is_multicast && (h->flags & AVIO_FLAG_READ))

        udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);

    closesocket(s->udp_fd);

    av_fifo_free(s->fifo);

#if HAVE_PTHREADS

    if (s->thread_started) {

        pthread_cancel(s->circular_buffer_thread);

        ret = pthread_join(s->circular_buffer_thread, NULL);

        if (ret != 0)

            av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", strerror(ret));

    }

    pthread_mutex_destroy(&s->mutex);

    pthread_cond_destroy(&s->cond);

#endif

    return 0;

}