static int av_encode(AVFormatContext **output_files,

                     int nb_output_files,

                     AVFormatContext **input_files,

                     int nb_input_files,

                     AVStreamMap *stream_maps, int nb_stream_maps)

{

    int ret, i, j, k, n, nb_istreams = 0, nb_ostreams = 0;

    AVFormatContext *is, *os;

    AVCodecContext *codec, *icodec;

    AVOutputStream *ost, **ost_table = NULL;

    AVInputStream *ist, **ist_table = NULL;

    AVInputFile *file_table;

    AVFormatContext *stream_no_data;

    int key;

    file_table= (AVInputFile*) av_mallocz(nb_input_files * sizeof(AVInputFile));

    if (!file_table)

        goto fail;

    /* input stream init */

    j = 0;

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

        is = input_files[i];

        file_table[i].ist_index = j;

        file_table[i].nb_streams = is->nb_streams;

        j += is->nb_streams;

    }

    nb_istreams = j;

    ist_table = av_mallocz(nb_istreams * sizeof(AVInputStream *));

    if (!ist_table)

        goto fail;

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

        ist = av_mallocz(sizeof(AVInputStream));

        if (!ist)

            goto fail;

        ist_table[i] = ist;

    }

    j = 0;

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

        is = input_files[i];

        for(k=0;k<is->nb_streams;k++) {

            ist = ist_table[j++];

            ist->st = is->streams[k];

            ist->file_index = i;

            ist->index = k;

            ist->discard = 1; /* the stream is discarded by default

                                 (changed later) */

            if (ist->st->codec.rate_emu) {

                ist->start = av_gettime();

                ist->frame = 0;

            }

        }

    }

    /* output stream init */

    nb_ostreams = 0;

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

        os = output_files[i];

        nb_ostreams += os->nb_streams;

    }

    if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {

        fprintf(stderr, "Number of stream maps must match number of output streams\n");

        exit(1);

    }

    /* Sanity check the mapping args -- do the input files & streams exist? */

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

        int fi = stream_maps[i].file_index;

        int si = stream_maps[i].stream_index;

        if (fi < 0 || fi > nb_input_files - 1 ||

            si < 0 || si > file_table[fi].nb_streams - 1) {

            fprintf(stderr,"Could not find input stream #%d.%d\n", fi, si);

            exit(1);

        }

    }

    ost_table = av_mallocz(sizeof(AVOutputStream *) * nb_ostreams);

    if (!ost_table)

        goto fail;

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

        ost = av_mallocz(sizeof(AVOutputStream));

        if (!ost)

            goto fail;

        ost_table[i] = ost;

    }

    n = 0;

    for(k=0;k<nb_output_files;k++) {

        os = output_files[k];

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

            int found;

            ost = ost_table[n++];

            ost->file_index = k;

            ost->index = i;

            ost->st = os->streams[i];

            if (nb_stream_maps > 0) {

                ost->source_index = file_table[stream_maps[n-1].file_index].ist_index +

                    stream_maps[n-1].stream_index;

                /* Sanity check that the stream types match */

                if (ist_table[ost->source_index]->st->codec.codec_type != ost->st->codec.codec_type) {

                    fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n",

                        stream_maps[n-1].file_index, stream_maps[n-1].stream_index,

                        ost->file_index, ost->index);

                    exit(1);

                }

            } else {

                /* get corresponding input stream index : we select the first one with the right type */

                found = 0;

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

                    ist = ist_table[j];

                    if (ist->discard &&

                        ist->st->codec.codec_type == ost->st->codec.codec_type) {

                        ost->source_index = j;

                        found = 1;

                    }

                }

                if (!found) {

                    /* try again and reuse existing stream */

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

                        ist = ist_table[j];

                        if (ist->st->codec.codec_type == ost->st->codec.codec_type) {

                            ost->source_index = j;

                            found = 1;

                        }

                    }

                    if (!found) {

                        fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",

                                ost->file_index, ost->index);

                        exit(1);

                    }

                }

            }

            ist = ist_table[ost->source_index];

            ist->discard = 0;

        }

    }

    /* for each output stream, we compute the right encoding parameters */

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

        ost = ost_table[i];

        ist = ist_table[ost->source_index];

        codec = &ost->st->codec;

        icodec = &ist->st->codec;

        if (ost->st->stream_copy) {

            /* if stream_copy is selected, no need to decode or encode */

            codec->codec_id = icodec->codec_id;

            codec->codec_type = icodec->codec_type;

            codec->codec_tag = icodec->codec_tag;

            codec->bit_rate = icodec->bit_rate;

            switch(codec->codec_type) {

            case CODEC_TYPE_AUDIO:

                codec->sample_rate = icodec->sample_rate;

                codec->channels = icodec->channels;

                break;

            case CODEC_TYPE_VIDEO:

                codec->frame_rate = icodec->frame_rate;

                codec->frame_rate_base = icodec->frame_rate_base;

                codec->width = icodec->width;

                codec->height = icodec->height;

                break;

            default:

                av_abort();

            }

        } else {

            switch(codec->codec_type) {

            case CODEC_TYPE_AUDIO:

                if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))

                    goto fail;

                if (codec->channels == icodec->channels &&

                    codec->sample_rate == icodec->sample_rate) {

                    ost->audio_resample = 0;

                } else {

                    if (codec->channels != icodec->channels &&

                        icodec->codec_id == CODEC_ID_AC3) {

                        /* Special case for 5:1 AC3 input */

                        /* and mono or stereo output      */

                        /* Request specific number of channels */

                        icodec->channels = codec->channels;

                        if (codec->sample_rate == icodec->sample_rate)

                            ost->audio_resample = 0;

                        else {

                            ost->audio_resample = 1;

                            ost->resample = audio_resample_init(codec->channels, icodec->channels,

                                                        codec->sample_rate,

                                                        icodec->sample_rate);

			    if(!ost->resample)

			      {

				printf("Can't resample.  Aborting.\n");

				av_abort();

			      }

                        }

                        /* Request specific number of channels */

                        icodec->channels = codec->channels;

                    } else {

                        ost->audio_resample = 1;

                        ost->resample = audio_resample_init(codec->channels, icodec->channels,

                                                        codec->sample_rate,

                                                        icodec->sample_rate);

			if(!ost->resample)

			  {

			    printf("Can't resample.  Aborting.\n");

			    av_abort();

			  }

                    }

                }

                ist->decoding_needed = 1;

                ost->encoding_needed = 1;

                break;

            case CODEC_TYPE_VIDEO:

                if (codec->width == icodec->width &&

                    codec->height == icodec->height &&

                    frame_topBand == 0 &&

                    frame_bottomBand == 0 &&

                    frame_leftBand == 0 &&

                    frame_rightBand == 0)

                {

                    ost->video_resample = 0;

                    ost->video_crop = 0;

                } else if ((codec->width == icodec->width -

                                (frame_leftBand + frame_rightBand)) &&

                        (codec->height == icodec->height -

                                (frame_topBand  + frame_bottomBand)))

                {

                    ost->video_resample = 0;

                    ost->video_crop = 1;

                    ost->topBand = frame_topBand;

                    ost->leftBand = frame_leftBand;

                } else {

                    ost->video_resample = 1;

                    ost->video_crop = 0; // cropping is handled as part of resample

                    if( avpicture_alloc( &ost->pict_tmp, PIX_FMT_YUV420P,

                                         codec->width, codec->height ) )

                        goto fail;

                    ost->img_resample_ctx = img_resample_full_init(

                                      ost->st->codec.width, ost->st->codec.height,

                                      ist->st->codec.width, ist->st->codec.height,

                                      frame_topBand, frame_bottomBand,

                                      frame_leftBand, frame_rightBand);

                }

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

                break;

            default:

                av_abort();

            }

            /* two pass mode */

            if (ost->encoding_needed &&

                (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {

                char logfilename[1024];

                FILE *f;

                int size;

                char *logbuffer;

                snprintf(logfilename, sizeof(logfilename), "%s-%d.log",

                         pass_logfilename ?

                         pass_logfilename : DEFAULT_PASS_LOGFILENAME, i);

                if (codec->flags & CODEC_FLAG_PASS1) {

                    f = fopen(logfilename, "w");

                    if (!f) {

                        perror(logfilename);

                        exit(1);

                    }

                    ost->logfile = f;

                } else {

                    /* read the log file */

                    f = fopen(logfilename, "r");

                    if (!f) {

                        perror(logfilename);

                        exit(1);

                    }

                    fseek(f, 0, SEEK_END);

                    size = ftell(f);

                    fseek(f, 0, SEEK_SET);

                    logbuffer = av_malloc(size + 1);

                    if (!logbuffer) {

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

                        exit(1);

                    }

                    size = fread(logbuffer, 1, size, f);

                    fclose(f);

                    logbuffer[size] = '\0';

                    codec->stats_in = logbuffer;

                }

            }

        }

    }

    /* dump the file output parameters - cannot be done before in case

       of stream copy */

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

        dump_format(output_files[i], i, output_files[i]->filename, 1);

    }

    /* dump the stream mapping */

    fprintf(stderr, "Stream mapping:\n");

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

        ost = ost_table[i];

        fprintf(stderr, "  Stream #%d.%d -> #%d.%d\n",

                ist_table[ost->source_index]->file_index,

                ist_table[ost->source_index]->index,

                ost->file_index,

                ost->index);

    }

    /* open each encoder */

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

        ost = ost_table[i];

        if (ost->encoding_needed) {

            AVCodec *codec;

            codec = avcodec_find_encoder(ost->st->codec.codec_id);

            if (!codec) {

                fprintf(stderr, "Unsupported codec for output stream #%d.%d\n",

                        ost->file_index, ost->index);

                exit(1);

            }

            if (avcodec_open(&ost->st->codec, codec) < 0) {

                fprintf(stderr, "Error while opening codec for stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height\n",

                        ost->file_index, ost->index);

                exit(1);

            }

        }

    }

    /* open each decoder */

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

        ist = ist_table[i];

        if (ist->decoding_needed) {

            AVCodec *codec;

            codec = avcodec_find_decoder(ist->st->codec.codec_id);

            if (!codec) {

                fprintf(stderr, "Unsupported codec (id=%d) for input stream #%d.%d\n",

                        ist->st->codec.codec_id, ist->file_index, ist->index);

                exit(1);

            }

            if (avcodec_open(&ist->st->codec, codec) < 0) {

                fprintf(stderr, "Error while opening codec for input stream #%d.%d\n",

                        ist->file_index, ist->index);

                exit(1);

            }

            //if (ist->st->codec.codec_type == CODEC_TYPE_VIDEO)

            //    ist->st->codec.flags |= CODEC_FLAG_REPEAT_FIELD;

        }

    }

    /* init pts */

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

        ist = ist_table[i];

	is = input_files[ist->file_index];

        ist->pts = 0;

        ist->next_pts = 0;

    }

    /* compute buffer size max (should use a complete heuristic) */

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

        file_table[i].buffer_size_max = 2048;

    }

    /* open files and write file headers */

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

        os = output_files[i];

        if (av_write_header(os) < 0) {

            fprintf(stderr, "Could not write header for output file #%d (incorrect codec paramters ?)\n", i);

            ret = -EINVAL;

            goto fail;

        }

    }

#ifndef CONFIG_WIN32

    if ( !using_stdin )

        fprintf(stderr, "Press [q] to stop encoding\n");

#endif

    term_init();

    stream_no_data = 0;

    key = -1;

    for(; received_sigterm == 0;) {

        int file_index, ist_index;

        AVPacket pkt;

        double pts_min;

    redo:

        /* if 'q' pressed, exits */

        if (!using_stdin) {

            /* read_key() returns 0 on EOF */

            key = read_key();

            if (key == 'q')

                break;

        }

        /* select the stream that we must read now by looking at the

           smallest output pts */

        file_index = -1;

        pts_min = 1e10;

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

            double pts;

            ost = ost_table[i];

            os = output_files[ost->file_index];

            ist = ist_table[ost->source_index];

            pts = (double)ost->st->pts.val * os->pts_num / os->pts_den;

            if (!file_table[ist->file_index].eof_reached &&

                pts < pts_min) {

                pts_min = pts;

                file_index = ist->file_index;

            }

        }

        /* if none, if is finished */

        if (file_index < 0) {

            break;

        }

        /* finish if recording time exhausted */

        if (recording_time > 0 && pts_min >= (recording_time / 1000000.0))

            break;

        /* read a frame from it and output it in the fifo */

        is = input_files[file_index];

        if (av_read_frame(is, &pkt) < 0) {

            file_table[file_index].eof_reached = 1;

            continue;

        }

        if (!pkt.size) {

            stream_no_data = is;

        } else {

            stream_no_data = 0;

        }

        if (do_pkt_dump) {

            av_pkt_dump(stdout, &pkt, do_hex_dump);

        }

        /* the following test is needed in case new streams appear

           dynamically in stream : we ignore them */

        if (pkt.stream_index >= file_table[file_index].nb_streams)

            goto discard_packet;

        ist_index = file_table[file_index].ist_index + pkt.stream_index;

        ist = ist_table[ist_index];

        if (ist->discard)

            goto discard_packet;

        //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->index, pkt.size);

        if (output_packet(ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) {

            fprintf(stderr, "Error while decoding stream #%d.%d\n",

                    ist->file_index, ist->index);

            av_free_packet(&pkt);

            goto redo;

        }

    discard_packet:

        av_free_packet(&pkt);

        /* dump report by using the output first video and audio streams */

        print_report(output_files, ost_table, nb_ostreams, 0);

    }

    /* at the end of stream, we must flush the decoder buffers */

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

        ist = ist_table[i];

        if (ist->decoding_needed) {

            output_packet(ist, i, ost_table, nb_ostreams, NULL);

        }

    }

    term_exit();

    /* dump report by using the first video and audio streams */

    print_report(output_files, ost_table, nb_ostreams, 1);

    /* write the trailer if needed and close file */

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

        os = output_files[i];

        av_write_trailer(os);

    }

    /* close each encoder */

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

        ost = ost_table[i];

        if (ost->encoding_needed) {

            av_freep(&ost->st->codec.stats_in);

            avcodec_close(&ost->st->codec);

        }

    }

    /* close each decoder */

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

        ist = ist_table[i];

        if (ist->decoding_needed) {

            avcodec_close(&ist->st->codec);

        }

    }

    /* finished ! */

    ret = 0;

 fail1:

    av_free(file_table);

    if (ist_table) {

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

            ist = ist_table[i];

            av_free(ist);

        }

        av_free(ist_table);

    }

    if (ost_table) {

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

            ost = ost_table[i];

            if (ost) {

                if (ost->logfile) {

                    fclose(ost->logfile);

                    ost->logfile = NULL;

                }

                fifo_free(&ost->fifo); /* works even if fifo is not

                                          initialized but set to zero */

                av_free(ost->pict_tmp.data[0]);

                if (ost->video_resample)

                    img_resample_close(ost->img_resample_ctx);

                if (ost->audio_resample)

                    audio_resample_close(ost->resample);

                av_free(ost);

            }

        }

        av_free(ost_table);

    }

    return ret;

 fail:

    ret = -ENOMEM;

    goto fail1;

}


static void vm_change_state_handler(void *opaque, int running,

                                    RunState state)

{

    GICv3ITSState *s = (GICv3ITSState *)opaque;

    Error *err = NULL;

    int ret;

    if (running) {

        return;

    }

    ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,

                            KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);

    if (err) {

        error_report_err(err);

    }

    if (ret < 0 && ret != -EFAULT) {

        abort();

    }

}


static uint8_t usb_linux_get_alt_setting(USBHostDevice *s,

    uint8_t configuration, uint8_t interface)

{

    char device_name[64], line[1024];

    int alt_setting;

    sprintf(device_name, "%d-%s:%d.%d", s->bus_num, s->port,

            (int)configuration, (int)interface);

    if (!usb_host_read_file(line, sizeof(line), "bAlternateSetting",

                            device_name)) {

        /* Assume alt 0 on error */

        return 0;

    }

    if (sscanf(line, "%d", &alt_setting) != 1) {

        /* Assume alt 0 on error */

        return 0;

    }

    return alt_setting;

}


static int append_extradata(APNGDemuxContext *ctx, AVIOContext *pb, int len)

{

    int previous_size = ctx->extra_data_size;

    int new_size, ret;

    uint8_t *new_extradata;

    if (previous_size > INT_MAX - len)

        return AVERROR_INVALIDDATA;

    new_size = previous_size + len;

    new_extradata = av_realloc(ctx->extra_data, new_size + AV_INPUT_BUFFER_PADDING_SIZE);

    if (!new_extradata)

        return AVERROR(ENOMEM);

    ctx->extra_data = new_extradata;

    ctx->extra_data_size = new_size;

    if ((ret = avio_read(pb, ctx->extra_data + previous_size, len)) < 0)

        return ret;

    return previous_size;

}


void dnxhd_get_blocks(DNXHDEncContext *ctx, int mb_x, int mb_y)

{

    const int bs = ctx->block_width_l2;

    const int bw = 1 << bs;

    int dct_y_offset = ctx->dct_y_offset;

    int dct_uv_offset = ctx->dct_uv_offset;

    int linesize = ctx->m.linesize;

    int uvlinesize = ctx->m.uvlinesize;

    const uint8_t *ptr_y = ctx->thread[0]->src[0] +

                           ((mb_y << 4) * ctx->m.linesize) + (mb_x << bs + 1);

    const uint8_t *ptr_u = ctx->thread[0]->src[1] +

                           ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs + ctx->is_444);

    const uint8_t *ptr_v = ctx->thread[0]->src[2] +

                           ((mb_y << 4) * ctx->m.uvlinesize) + (mb_x << bs + ctx->is_444);

    PixblockDSPContext *pdsp = &ctx->m.pdsp;

    VideoDSPContext *vdsp = &ctx->m.vdsp;

    if (ctx->bit_depth != 10 && vdsp->emulated_edge_mc && ((mb_x << 4) + 16 > ctx->m.avctx->width ||

                                                           (mb_y << 4) + 16 > ctx->m.avctx->height)) {

        int y_w = ctx->m.avctx->width  - (mb_x << 4);

        int y_h = ctx->m.avctx->height - (mb_y << 4);

        int uv_w = (y_w + 1) / 2;

        int uv_h = y_h;

        linesize = 16;

        uvlinesize = 8;

        vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y,

                               linesize, ctx->m.linesize,

                               linesize, 16,

                               0, 0, y_w, y_h);

        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u,

                               uvlinesize, ctx->m.uvlinesize,

                               uvlinesize, 16,

                               0, 0, uv_w, uv_h);

        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v,

                               uvlinesize, ctx->m.uvlinesize,

                               uvlinesize, 16,

                               0, 0, uv_w, uv_h);

        dct_y_offset =  bw * linesize;

        dct_uv_offset = bw * uvlinesize;

        ptr_y = &ctx->edge_buf_y[0];

        ptr_u = &ctx->edge_buf_uv[0][0];

        ptr_v = &ctx->edge_buf_uv[1][0];

    } else if (ctx->bit_depth == 10 && vdsp->emulated_edge_mc && ((mb_x << 3) + 8 > ctx->m.avctx->width ||

                                                                  (mb_y << 3) + 8 > ctx->m.avctx->height)) {

        int y_w = ctx->m.avctx->width  - (mb_x << 3);

        int y_h = ctx->m.avctx->height - (mb_y << 3);

        int uv_w = ctx->is_444 ? y_w : (y_w + 1) / 2;

        int uv_h = y_h;

        linesize = 16;

        uvlinesize = 8 + 8 * ctx->is_444;

        vdsp->emulated_edge_mc(&ctx->edge_buf_y[0], ptr_y,

                               linesize, ctx->m.linesize,

                               linesize / 2, 16,

                               0, 0, y_w, y_h);

        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[0][0], ptr_u,

                               uvlinesize, ctx->m.uvlinesize,

                               uvlinesize / 2, 16,

                               0, 0, uv_w, uv_h);

        vdsp->emulated_edge_mc(&ctx->edge_buf_uv[1][0], ptr_v,

                               uvlinesize, ctx->m.uvlinesize,

                               uvlinesize / 2, 16,

                               0, 0, uv_w, uv_h);

        dct_y_offset =  bw * linesize;

        dct_uv_offset = bw * uvlinesize;

        ptr_y = &ctx->edge_buf_y[0];

        ptr_u = &ctx->edge_buf_uv[0][0];

        ptr_v = &ctx->edge_buf_uv[1][0];

    }

    if (!ctx->is_444) {

        pdsp->get_pixels(ctx->blocks[0], ptr_y,      linesize);

        pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize);

        pdsp->get_pixels(ctx->blocks[2], ptr_u,      uvlinesize);

        pdsp->get_pixels(ctx->blocks[3], ptr_v,      uvlinesize);

        if (mb_y + 1 == ctx->m.mb_height && ctx->m.avctx->height == 1080) {

            if (ctx->interlaced) {

                ctx->get_pixels_8x4_sym(ctx->blocks[4],

                                        ptr_y + dct_y_offset,

                                        linesize);

                ctx->get_pixels_8x4_sym(ctx->blocks[5],

                                        ptr_y + dct_y_offset + bw,

                                        linesize);

                ctx->get_pixels_8x4_sym(ctx->blocks[6],

                                        ptr_u + dct_uv_offset,

                                        uvlinesize);

                ctx->get_pixels_8x4_sym(ctx->blocks[7],

                                        ptr_v + dct_uv_offset,

                                        uvlinesize);

            } else {

                ctx->bdsp.clear_block(ctx->blocks[4]);

                ctx->bdsp.clear_block(ctx->blocks[5]);

                ctx->bdsp.clear_block(ctx->blocks[6]);

                ctx->bdsp.clear_block(ctx->blocks[7]);

            }

        } else {

            pdsp->get_pixels(ctx->blocks[4],

                             ptr_y + dct_y_offset, linesize);

            pdsp->get_pixels(ctx->blocks[5],

                             ptr_y + dct_y_offset + bw, linesize);

            pdsp->get_pixels(ctx->blocks[6],

                             ptr_u + dct_uv_offset, uvlinesize);

            pdsp->get_pixels(ctx->blocks[7],

                             ptr_v + dct_uv_offset, uvlinesize);

        }

    } else {

        pdsp->get_pixels(ctx->blocks[0], ptr_y,      linesize);

        pdsp->get_pixels(ctx->blocks[1], ptr_y + bw, linesize);

        pdsp->get_pixels(ctx->blocks[6], ptr_y + dct_y_offset, linesize);

        pdsp->get_pixels(ctx->blocks[7], ptr_y + dct_y_offset + bw, linesize);

        pdsp->get_pixels(ctx->blocks[2], ptr_u,      uvlinesize);

        pdsp->get_pixels(ctx->blocks[3], ptr_u + bw, uvlinesize);

        pdsp->get_pixels(ctx->blocks[8], ptr_u + dct_uv_offset, uvlinesize);

        pdsp->get_pixels(ctx->blocks[9], ptr_u + dct_uv_offset + bw, uvlinesize);

        pdsp->get_pixels(ctx->blocks[4], ptr_v,      uvlinesize);

        pdsp->get_pixels(ctx->blocks[5], ptr_v + bw, uvlinesize);

        pdsp->get_pixels(ctx->blocks[10], ptr_v + dct_uv_offset, uvlinesize);

        pdsp->get_pixels(ctx->blocks[11], ptr_v + dct_uv_offset + bw, uvlinesize);

    }

}


bool virtio_scsi_handle_event_vq(VirtIOSCSI *s, VirtQueue *vq)

{

    virtio_scsi_acquire(s);

    if (s->events_dropped) {

        virtio_scsi_push_event(s, NULL, VIRTIO_SCSI_T_NO_EVENT, 0);

        virtio_scsi_release(s);

        return true;

    }

    virtio_scsi_release(s);

    return false;

}


static attribute_align_arg void *frame_worker_thread(void *arg)

{

    PerThreadContext *p = arg;

    FrameThreadContext *fctx = p->parent;

    AVCodecContext *avctx = p->avctx;

    AVCodec *codec = avctx->codec;

    while (1) {

        int i;

        if (p->state == STATE_INPUT_READY && !fctx->die) {

            pthread_mutex_lock(&p->mutex);

            while (p->state == STATE_INPUT_READY && !fctx->die)

                pthread_cond_wait(&p->input_cond, &p->mutex);

            pthread_mutex_unlock(&p->mutex);

        }

        if (fctx->die) break;

        if (!codec->update_thread_context && (avctx->thread_safe_callbacks || avctx->get_buffer == avcodec_default_get_buffer))

            ff_thread_finish_setup(avctx);

        pthread_mutex_lock(&p->mutex);

        avcodec_get_frame_defaults(&p->frame);

        p->got_frame = 0;

        p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt);

        if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx);

        pthread_mutex_lock(&p->progress_mutex);

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

            if (p->progress_used[i]) {

                p->progress[i][0] = INT_MAX;

                p->progress[i][1] = INT_MAX;

            }

        p->state = STATE_INPUT_READY;

        pthread_cond_broadcast(&p->progress_cond);

        pthread_cond_signal(&p->output_cond);

        pthread_mutex_unlock(&p->progress_mutex);

        pthread_mutex_unlock(&p->mutex);

    }

    return NULL;

}


static void gen_spr_970_pmu_sup(CPUPPCState *env)

{

    spr_register(env, SPR_970_PMC7, "PMC7",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_970_PMC8, "PMC8",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

}


static av_cold int hevc_sdp_parse_fmtp_config(AVFormatContext *s,

                                              AVStream *stream,

                                              PayloadContext *hevc_data,

                                              char *attr, char *value)

{

    /* profile-space: 0-3 */

    /* profile-id: 0-31 */

    if (!strcmp(attr, "profile-id")) {

        hevc_data->profile_id = atoi(value);

        av_dlog(s, "SDP: found profile-id: %d\n", hevc_data->profile_id);

    }

    /* tier-flag: 0-1 */

    /* level-id: 0-255 */

    /* interop-constraints: [base16] */

    /* profile-compatibility-indicator: [base16] */

    /* sprop-sub-layer-id: 0-6, defines highest possible value for TID, default: 6 */

    /* recv-sub-layer-id: 0-6 */

    /* max-recv-level-id: 0-255 */

    /* tx-mode: MSM,SSM */

    /* sprop-vps: [base64] */

    /* sprop-sps: [base64] */

    /* sprop-pps: [base64] */

    /* sprop-sei: [base64] */

    if (!strcmp(attr, "sprop-vps") || !strcmp(attr, "sprop-sps") ||

        !strcmp(attr, "sprop-pps") || !strcmp(attr, "sprop-sei")) {

        uint8_t **data_ptr;

        int *size_ptr;

        if (!strcmp(attr, "sprop-vps")) {

            data_ptr = &hevc_data->vps;

            size_ptr = &hevc_data->vps_size;

        } else if (!strcmp(attr, "sprop-sps")) {

            data_ptr = &hevc_data->sps;

            size_ptr = &hevc_data->sps_size;

        } else if (!strcmp(attr, "sprop-pps")) {

            data_ptr = &hevc_data->pps;

            size_ptr = &hevc_data->pps_size;

        } else if (!strcmp(attr, "sprop-sei")) {

            data_ptr = &hevc_data->sei;

            size_ptr = &hevc_data->sei_size;

        }

        while (*value) {

            char base64packet[1024];

            uint8_t decoded_packet[1024];

            int decoded_packet_size;

            char *dst = base64packet;

            while (*value && *value != ',' &&

                   (dst - base64packet) < sizeof(base64packet) - 1) {

                *dst++ = *value++;

            }

            *dst++ = '\0';

            if (*value == ',')

                value++;

            decoded_packet_size = av_base64_decode(decoded_packet, base64packet,

                                                   sizeof(decoded_packet));

            if (decoded_packet_size > 0) {

                uint8_t *tmp = av_realloc(*data_ptr, decoded_packet_size +

                                          sizeof(start_sequence) + *size_ptr);

                if (!tmp) {

                    av_log(s, AV_LOG_ERROR,

                           "Unable to allocate memory for extradata!\n");

                    return AVERROR(ENOMEM);

                }

                *data_ptr = tmp;

                memcpy(*data_ptr + *size_ptr, start_sequence,

                       sizeof(start_sequence));

                memcpy(*data_ptr + *size_ptr + sizeof(start_sequence),

                       decoded_packet, decoded_packet_size);

                *size_ptr += sizeof(start_sequence) + decoded_packet_size;

            }

        }

    }

    /* max-lsr, max-lps, max-cpb, max-dpb, max-br, max-tr, max-tc */

    /* max-fps */

    /* sprop-max-don-diff: 0-32767

         When the RTP stream depends on one or more other RTP

         streams (in this case tx-mode MUST be equal to "MSM" and

         MSM is in use), this parameter MUST be present and the

         value MUST be greater than 0.

    */

    if (!strcmp(attr, "sprop-max-don-diff")) {

        if (atoi(value) > 0)

            hevc_data->using_donl_field = 1;

        av_dlog(s, "Found sprop-max-don-diff in SDP, DON field usage is: %d\n",

                hevc_data->using_donl_field);

    }

    /* sprop-depack-buf-nalus: 0-32767 */

    if (!strcmp(attr, "sprop-depack-buf-nalus")) {

        if (atoi(value) > 0)

            hevc_data->using_donl_field = 1;

        av_dlog(s, "Found sprop-depack-buf-nalus in SDP, DON field usage is: %d\n",

                hevc_data->using_donl_field);

    }

    /* sprop-depack-buf-bytes: 0-4294967295 */

    /* depack-buf-cap */

    /* sprop-segmentation-id: 0-3 */

    /* sprop-spatial-segmentation-idc: [base16] */

    /* dec-parallel-ca: */

    /* include-dph */

    return 0;

}


static int svq3_decode_frame (AVCodecContext *avctx,

			      void *data, int *data_size,

			      uint8_t *buf, int buf_size) {

  MpegEncContext *const s = avctx->priv_data;

  H264Context *const h = avctx->priv_data;

  int m, mb_type;

  unsigned char *extradata;

  unsigned int size;

  s->flags = avctx->flags;

  s->flags2 = avctx->flags2;

  s->unrestricted_mv = 1;

  if (!s->context_initialized) {

    s->width = avctx->width;

    s->height = avctx->height;

    h->pred4x4[DIAG_DOWN_LEFT_PRED] = pred4x4_down_left_svq3_c;

    h->pred16x16[PLANE_PRED8x8] = pred16x16_plane_svq3_c;

    h->halfpel_flag = 1;

    h->thirdpel_flag = 1;

    h->unknown_svq3_flag = 0;

    h->chroma_qp = 4;

    if (MPV_common_init (s) < 0)

      return -1;

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

    alloc_tables (h);

    /* prowl for the "SEQH" marker in the extradata */

    extradata = (unsigned char *)avctx->extradata;

    for (m = 0; m < avctx->extradata_size; m++) {

      if (!memcmp (extradata, "SEQH", 4))

        break;

      extradata++;

    }

    /* if a match was found, parse the extra data */

    if (!memcmp (extradata, "SEQH", 4)) {

      GetBitContext gb;

      size = BE_32(&extradata[4]);

      init_get_bits (&gb, extradata + 8, size);

      /* 'frame size code' and optional 'width, height' */

      if (get_bits (&gb, 3) == 7) {

	get_bits (&gb, 12);

	get_bits (&gb, 12);

      }

      h->halfpel_flag = get_bits1 (&gb);

      h->thirdpel_flag = get_bits1 (&gb);

      /* unknown fields */

      get_bits1 (&gb);

      get_bits1 (&gb);

      get_bits1 (&gb);

      get_bits1 (&gb);

      s->low_delay = get_bits1 (&gb);

      /* unknown field */

      get_bits1 (&gb);

      while (get_bits1 (&gb)) {

	get_bits (&gb, 8);

      }

      h->unknown_svq3_flag = get_bits1 (&gb);

      avctx->has_b_frames = !s->low_delay;

    }

  }

  /* special case for last picture */

  if (buf_size == 0) {

    if (s->next_picture_ptr && !s->low_delay) {

      *(AVFrame *) data = *(AVFrame *) &s->next_picture;

      *data_size = sizeof(AVFrame);

    }

    return 0;

  }

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

  s->mb_x = s->mb_y = 0;

  if (svq3_decode_slice_header (h))

    return -1;

  s->pict_type = h->slice_type;

  s->picture_number = h->slice_num;

  if(avctx->debug&FF_DEBUG_PICT_INFO){

      av_log(h->s.avctx, AV_LOG_DEBUG, "%c hpel:%d, tpel:%d aqp:%d qp:%d\n",

      av_get_pict_type_char(s->pict_type), h->halfpel_flag, h->thirdpel_flag,

      s->adaptive_quant, s->qscale

      );

  }

  /* for hurry_up==5 */

  s->current_picture.pict_type = s->pict_type;

  s->current_picture.key_frame = (s->pict_type == I_TYPE);

  /* skip b frames if we dont have reference frames */

  if (s->last_picture_ptr == NULL && s->pict_type == B_TYPE) return 0;

  /* skip b frames if we are in a hurry */

  if (avctx->hurry_up && s->pict_type == B_TYPE) return 0;

  /* skip everything if we are in a hurry >= 5 */

  if (avctx->hurry_up >= 5) return 0;

  if(  (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE)

     ||(avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE)

     || avctx->skip_frame >= AVDISCARD_ALL)

      return 0;

  if (s->next_p_frame_damaged) {

    if (s->pict_type == B_TYPE)

      return 0;

    else

      s->next_p_frame_damaged = 0;

  }

  frame_start (h);

  if (s->pict_type == B_TYPE) {

    h->frame_num_offset = (h->slice_num - h->prev_frame_num);

    if (h->frame_num_offset < 0) {

      h->frame_num_offset += 256;

    }

    if (h->frame_num_offset == 0 || h->frame_num_offset >= h->prev_frame_num_offset) {

      av_log(h->s.avctx, AV_LOG_ERROR, "error in B-frame picture id\n");

      return -1;

    }

  } else {

    h->prev_frame_num = h->frame_num;

    h->frame_num = h->slice_num;

    h->prev_frame_num_offset = (h->frame_num - h->prev_frame_num);

    if (h->prev_frame_num_offset < 0) {

      h->prev_frame_num_offset += 256;

    }

  }

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

    int i;

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

      int j;

      for(j=-1; j<4; j++)

	h->ref_cache[m][scan8[0] + 8*i + j]= 1;

      h->ref_cache[m][scan8[0] + 8*i + j]= PART_NOT_AVAILABLE;

    }

  }

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

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

      if ( (get_bits_count(&s->gb) + 7) >= s->gb.size_in_bits &&

	  ((get_bits_count(&s->gb) & 7) == 0 || show_bits (&s->gb, (-get_bits_count(&s->gb) & 7)) == 0)) {

	skip_bits(&s->gb, h->next_slice_index - get_bits_count(&s->gb));

	s->gb.size_in_bits = 8*buf_size;

	if (svq3_decode_slice_header (h))

	  return -1;

	/* TODO: support s->mb_skip_run */

      }

      mb_type = svq3_get_ue_golomb (&s->gb);

      if (s->pict_type == I_TYPE) {

	mb_type += 8;

      } else if (s->pict_type == B_TYPE && mb_type >= 4) {

	mb_type += 4;

      }

      if (mb_type > 33 || svq3_decode_mb (h, mb_type)) {

	av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding MB %d %d\n", s->mb_x, s->mb_y);

	return -1;

      }

      if (mb_type != 0) {

	hl_decode_mb (h);

      }

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

	s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride] =

			(s->pict_type == P_TYPE && mb_type < 8) ? (mb_type - 1) : -1;

      }

    }

    ff_draw_horiz_band(s, 16*s->mb_y, 16);

  }

  MPV_frame_end(s);

  if (s->pict_type == B_TYPE || s->low_delay) {

    *(AVFrame *) data = *(AVFrame *) &s->current_picture;

  } else {

    *(AVFrame *) data = *(AVFrame *) &s->last_picture;

  }

  avctx->frame_number = s->picture_number - 1;

  /* dont output the last pic after seeking */

  if (s->last_picture_ptr || s->low_delay) {

    *data_size = sizeof(AVFrame);

  }

  return buf_size;

}


static int qemu_rdma_reg_whole_ram_blocks(RDMAContext *rdma)

{

    int i;

    RDMALocalBlocks *local = &rdma->local_ram_blocks;

    for (i = 0; i < local->nb_blocks; i++) {

        local->block[i].mr =

            ibv_reg_mr(rdma->pd,

                    local->block[i].local_host_addr,

                    local->block[i].length,

                    IBV_ACCESS_LOCAL_WRITE |

                    IBV_ACCESS_REMOTE_WRITE

                    );

        if (!local->block[i].mr) {

            perror("Failed to register local dest ram block!\n");

            break;

        }

        rdma->total_registrations++;

    }

    if (i >= local->nb_blocks) {

        return 0;

    }

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

        ibv_dereg_mr(local->block[i].mr);

        rdma->total_registrations--;

    }

    return -1;

}


static int encode_plane(AVCodecContext *avctx, uint8_t *src,

                        uint8_t *dst, int step, int stride,

                        int width, int height, PutByteContext *pb)

{

    UtvideoContext *c        = avctx->priv_data;

    uint8_t  lengths[256];

    uint32_t counts[256]     = { 0 };

    HuffEntry he[256];

    uint32_t offset = 0, slice_len = 0;

    int      i, sstart, send = 0;

    int      symbol;

    /* Do prediction / make planes */

    switch (c->frame_pred) {

    case PRED_NONE:

        for (i = 0; i < c->slices; i++) {

            sstart = send;

            send   = height * (i + 1) / c->slices;

            write_plane(src + sstart * stride, dst + sstart * width,

                        step, stride, width, send - sstart);

        }

        break;

    case PRED_LEFT:

        for (i = 0; i < c->slices; i++) {

            sstart = send;

            send   = height * (i + 1) / c->slices;

            left_predict(src + sstart * stride, dst + sstart * width,

                         step, stride, width, send - sstart);

        }

        break;

    case PRED_MEDIAN:

        for (i = 0; i < c->slices; i++) {

            sstart = send;

            send   = height * (i + 1) / c->slices;

            median_predict(src + sstart * stride, dst + sstart * width,

                           step, stride, width, send - sstart);

        }

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unknown prediction mode: %d\n",

               c->frame_pred);

        return AVERROR_OPTION_NOT_FOUND;

    }

    /* Count the usage of values */

    count_usage(dst, width, height, counts);

    /* Check for a special case where only one symbol was used */

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

        /* If non-zero count is found, see if it matches width * height */

        if (counts[symbol]) {

            /* Special case if only one symbol was used */

            if (counts[symbol] == width * height) {

                /*

                 * Write a zero for the single symbol

                 * used in the plane, else 0xFF.

                 */

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

                    if (i == symbol)

                        bytestream2_put_byte(pb, 0);

                    else

                        bytestream2_put_byte(pb, 0xFF);

                }

                /* Write zeroes for lengths */

                for (i = 0; i < c->slices; i++)

                    bytestream2_put_le32(pb, 0);

                /* And that's all for that plane folks */

                return 0;

            }

            break;

        }

    }

    /* Calculate huffman lengths */

    calculate_code_lengths(lengths, counts);

    /*

     * Write the plane's header into the output packet:

     * - huffman code lengths (256 bytes)

     * - slice end offsets (gotten from the slice lengths)

     */

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

        bytestream2_put_byte(pb, lengths[i]);

        he[i].len = lengths[i];

        he[i].sym = i;

    }

    /* Calculate the huffman codes themselves */

    calculate_codes(he);

    send = 0;

    for (i = 0; i < c->slices; i++) {

        sstart  = send;

        send    = height * (i + 1) / c->slices;

        /*

         * Write the huffman codes to a buffer,

         * get the offset in bits and convert to bytes.

         */

        offset += write_huff_codes(dst + sstart * width, c->slice_bits,

                                   width * (send - sstart), width,

                                   send - sstart, he) >> 3;

        slice_len = offset - slice_len;

        /* Byteswap the written huffman codes */

        c->dsp.bswap_buf((uint32_t *) c->slice_bits,

                         (uint32_t *) c->slice_bits,

                         slice_len >> 2);

        /* Write the offset to the stream */

        bytestream2_put_le32(pb, offset);

        /* Seek to the data part of the packet */

        bytestream2_seek_p(pb, 4 * (c->slices - i - 1) +

                           offset - slice_len, SEEK_CUR);

        /* Write the slices' data into the output packet */

        bytestream2_put_buffer(pb, c->slice_bits, slice_len);

        /* Seek back to the slice offsets */

        bytestream2_seek_p(pb, -4 * (c->slices - i - 1) - offset,

                           SEEK_CUR);

        slice_len = offset;

    }

    /* And at the end seek to the end of written slice(s) */

    bytestream2_seek_p(pb, offset, SEEK_CUR);

    return 0;

}


static void init_excp_4xx_real (CPUPPCState *env)

{

#if !defined(CONFIG_USER_ONLY)

    env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;

    env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;

    env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;

    env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;

    env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;

    env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;

    env->excp_vectors[POWERPC_EXCP_PIT]      = 0x00001000;

    env->excp_vectors[POWERPC_EXCP_FIT]      = 0x00001010;

    env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00001020;

    env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00002000;

    env->excp_prefix = 0x00000000;

    env->ivor_mask = 0x0000FFF0;

    env->ivpr_mask = 0xFFFF0000;

    /* Hardware reset vector */

    env->hreset_vector = 0xFFFFFFFCUL;

#endif

}


static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf,

                                               void *priv)

{

    av_freep(&priv);

}


void aio_set_dispatching(AioContext *ctx, bool dispatching)

{

    ctx->dispatching = dispatching;

    if (!dispatching) {

        /* Write ctx->dispatching before reading e.g. bh->scheduled.

         * Optimization: this is only needed when we're entering the "unsafe"

         * phase where other threads must call event_notifier_set.

         */

        smp_mb();

    }

}


static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize)

{

#if 0

	struct {

		uint32_t offset; /* 0x80000000 + sample start - 4 */

		unsigned char unknown1[3]; /* 03 12 04 */

		unsigned char channel; /* 1 or 2 */

		uint32_t freq;

		uint32_t size;

		uint32_t unknown2; /* 01 f4 03 00 */

		uint32_t unknown3; /* 00 00 00 00 */

		uint32_t unknown4; /* 00 00 00 00 */

	/* if loop

		unknown3 00 15 00 01

		unknown4 00 00 00 01

		long loop_start_sample;

		long loop_start_byte;

		long loop_end_sample;

		long loop_end_byte;

		long

	*/

	} adxhdr; /* big endian */

	/* offset-6 "(c)CRI" */

#endif

	write_long(buf+0x00,0x80000000|0x20);

	write_long(buf+0x04,0x03120400|avctx->channels);

	write_long(buf+0x08,avctx->sample_rate);

	write_long(buf+0x0c,0); /* FIXME: set after */

	write_long(buf+0x10,0x01040300);

	write_long(buf+0x14,0x00000000);

	write_long(buf+0x18,0x00000000);

	memcpy(buf+0x1c,"\0\0(c)CRI",8);

	return 0x20+4;

}


static vscsi_req *vscsi_find_req(VSCSIState *s, uint32_t tag)

{

    if (tag >= VSCSI_REQ_LIMIT || !s->reqs[tag].active) {

        return NULL;

    }

    return &s->reqs[tag];

}


static inline void RENAME(rgb24tobgr15)(const uint8_t *src, uint8_t *dst, unsigned src_size)

{

	const uint8_t *s = src;

	const uint8_t *end;

#ifdef HAVE_MMX

	const uint8_t *mm_end;

#endif

	uint16_t *d = (uint16_t *)dst;

	end = s + src_size;

#ifdef HAVE_MMX

	__asm __volatile(PREFETCH"	%0"::"m"(*src):"memory");

	__asm __volatile(

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

	    "movq	%1, %%mm6\n\t"

	    ::"m"(red_15mask),"m"(green_15mask));

	mm_end = end - 15;

	while(s < mm_end)

	{

	    __asm __volatile(

		PREFETCH" 32%1\n\t"

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

		"movd	3%1, %%mm3\n\t"

		"punpckldq 6%1, %%mm0\n\t"

		"punpckldq 9%1, %%mm3\n\t"

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

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

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

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

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

		"psllq	$7, %%mm3\n\t"

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

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

		"psrlq	$6, %%mm1\n\t"

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

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

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

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

		"psrlq	$19, %%mm5\n\t"

		"pand	%2, %%mm2\n\t"

		"pand	%2, %%mm5\n\t"

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

		"por	%%mm4, %%mm3\n\t"

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

		"por	%%mm5, %%mm3\n\t"

		"psllq	$16, %%mm3\n\t"

		"por	%%mm3, %%mm0\n\t"

		MOVNTQ"	%%mm0, %0\n\t"

		:"=m"(*d):"m"(*s),"m"(blue_15mask):"memory");

		d += 4;

		s += 12;

	}

	__asm __volatile(SFENCE:::"memory");

	__asm __volatile(EMMS:::"memory");

#endif

	while(s < end)

	{

		const int r= *s++;

		const int g= *s++;

		const int b= *s++;

		*d++ = (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7);

	}

}


static void read_tree(GetBitContext *gb, Tree *tree)

{

    uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2;

    int i, t, len;

    tree->vlc_num = get_bits(gb, 4);

    if (!tree->vlc_num) {

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

            tree->syms[i] = i;

        return;

    }

    if (get_bits1(gb)) {

        len = get_bits(gb, 3);

        memset(tmp1, 0, sizeof(tmp1));

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

            tree->syms[i] = get_bits(gb, 4);

            tmp1[tree->syms[i]] = 1;

        }

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

            if (!tmp1[i])

                tree->syms[++len] = i;

    } else {

        len = get_bits(gb, 2);

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

            in[i] = i;

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

            int size = 1 << i;

            for (t = 0; t < 16; t += size << 1)

                merge(gb, out + t, in + t, size);

            FFSWAP(uint8_t*, in, out);

        }

        memcpy(tree->syms, in, 16);

    }

}


uint32_t ide_data_readl(void *opaque, uint32_t addr)
{
    IDEBus *bus = opaque;
    IDEState *s = idebus_active_if(bus);
    uint8_t *p;
    int ret;
    /* PIO data access allowed only when DRQ bit is set. The result of a read
     * during PIO in is indeterminate, return 0 and don't move forward. */
    if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
    p = s->data_ptr;
    ret = cpu_to_le32(*(uint32_t *)p);
    p += 4;
    s->data_ptr = p;
    if (p >= s->data_end)
        s->end_transfer_func(s);
    return ret;


void do_commit(Monitor *mon, const QDict *qdict)

{

    const char *device = qdict_get_str(qdict, "device");

    BlockDriverState *bs;

    if (!strcmp(device, "all")) {

        bdrv_commit_all();

    } else {

        int ret;

        bs = bdrv_find(device);

        if (!bs) {

            qerror_report(QERR_DEVICE_NOT_FOUND, device);

            return;

        }

        ret = bdrv_commit(bs);

        if (ret == -EBUSY) {

            qerror_report(QERR_DEVICE_IN_USE, device);

            return;

        }

    }

}


void avfilter_start_frame(AVFilterLink *link, AVFilterPicRef *picref)

{

    void (*start_frame)(AVFilterLink *, AVFilterPicRef *);

    AVFilterPad *dst = &link_dpad(link);

    if(!(start_frame = dst->start_frame))

        start_frame = avfilter_default_start_frame;

    /* prepare to copy the picture if it has insufficient permissions */

    if((dst->min_perms & picref->perms) != dst->min_perms ||

        dst->rej_perms & picref->perms) {

        /*

        av_log(link->dst, AV_LOG_INFO,

                "frame copy needed (have perms %x, need %x, reject %x)\n",

                picref->perms,

                link_dpad(link).min_perms, link_dpad(link).rej_perms);

        */

        link->cur_pic = avfilter_default_get_video_buffer(link, dst->min_perms);

        link->srcpic = picref;

        link->cur_pic->pts = link->srcpic->pts;

    }

    else

        link->cur_pic = picref;

    start_frame(link, link->cur_pic);

}


static void ffserver_apply_stream_config(AVCodecContext *enc, const AVDictionary *conf, AVDictionary **opts)

{

    AVDictionaryEntry *e;

    /* Return values from ffserver_set_*_param are ignored.

       Values are initially parsed and checked before inserting to

       AVDictionary. */

    //video params

    if ((e = av_dict_get(conf, "VideoBitRateRangeMin", NULL, 0)))

        ffserver_set_int_param(&enc->rc_min_rate, e->value, 1000, INT_MIN,

                INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoBitRateRangeMax", NULL, 0)))

        ffserver_set_int_param(&enc->rc_max_rate, e->value, 1000, INT_MIN,

                INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "Debug", NULL, 0)))

        ffserver_set_int_param(&enc->debug, e->value, 0, INT_MIN, INT_MAX,

                NULL, 0, NULL);

    if ((e = av_dict_get(conf, "Strict", NULL, 0)))

        ffserver_set_int_param(&enc->strict_std_compliance, e->value, 0,

                INT_MIN, INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoBufferSize", NULL, 0)))

        ffserver_set_int_param(&enc->rc_buffer_size, e->value, 8*1024,

                INT_MIN, INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoBitRateTolerance", NULL, 0)))

        ffserver_set_int_param(&enc->bit_rate_tolerance, e->value, 1000,

                INT_MIN, INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoBitRate", NULL, 0)))

        ffserver_set_int_param(&enc->bit_rate, e->value, 1000, INT_MIN,

                INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoSizeWidth", NULL, 0)))

        ffserver_set_int_param(&enc->width, e->value, 0, INT_MIN, INT_MAX,

                NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoSizeHeight", NULL, 0)))

        ffserver_set_int_param(&enc->height, e->value, 0, INT_MIN, INT_MAX,

                NULL, 0, NULL);

    if ((e = av_dict_get(conf, "PixelFormat", NULL, 0))) {

        int val;

        ffserver_set_int_param(&val, e->value, 0, INT_MIN, INT_MAX, NULL, 0,

                NULL);

        enc->pix_fmt = val;

    }

    if ((e = av_dict_get(conf, "VideoGopSize", NULL, 0)))

        ffserver_set_int_param(&enc->gop_size, e->value, 0, INT_MIN, INT_MAX,

                NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoFrameRateNum", NULL, 0)))

        ffserver_set_int_param(&enc->time_base.num, e->value, 0, INT_MIN,

                INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoFrameRateDen", NULL, 0)))

        ffserver_set_int_param(&enc->time_base.den, e->value, 0, INT_MIN,

                INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoQDiff", NULL, 0)))

        ffserver_set_int_param(&enc->max_qdiff, e->value, 0, INT_MIN, INT_MAX,

                NULL, 0, NULL);

    if ((e = av_dict_get(conf, "VideoQMax", NULL, 0)))

        ffserver_set_int_param(&enc->qmax, e->value, 0, INT_MIN, INT_MAX, NULL,

                0, NULL);

    if ((e = av_dict_get(conf, "VideoQMin", NULL, 0)))

        ffserver_set_int_param(&enc->qmin, e->value, 0, INT_MIN, INT_MAX, NULL,

                0, NULL);

    if ((e = av_dict_get(conf, "LumiMask", NULL, 0)))

        ffserver_set_float_param(&enc->lumi_masking, e->value, 0, -FLT_MAX,

                FLT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "DarkMask", NULL, 0)))

        ffserver_set_float_param(&enc->dark_masking, e->value, 0, -FLT_MAX,

                FLT_MAX, NULL, 0, NULL);

    if (av_dict_get(conf, "BitExact", NULL, 0))

        enc->flags |= CODEC_FLAG_BITEXACT;

    if (av_dict_get(conf, "DctFastint", NULL, 0))

        enc->dct_algo  = FF_DCT_FASTINT;

    if (av_dict_get(conf, "IdctSimple", NULL, 0))

        enc->idct_algo = FF_IDCT_SIMPLE;

    if (av_dict_get(conf, "VideoHighQuality", NULL, 0))

        enc->mb_decision = FF_MB_DECISION_BITS;

    if ((e = av_dict_get(conf, "VideoTag", NULL, 0)))

        enc->codec_tag = MKTAG(e->value[0], e->value[1], e->value[2], e->value[3]);

    if (av_dict_get(conf, "Qscale", NULL, 0)) {

        enc->flags |= CODEC_FLAG_QSCALE;

        ffserver_set_int_param(&enc->global_quality, e->value, FF_QP2LAMBDA,

                INT_MIN, INT_MAX, NULL, 0, NULL);

    }

    if (av_dict_get(conf, "Video4MotionVector", NULL, 0)) {

        enc->mb_decision = FF_MB_DECISION_BITS; //FIXME remove

        enc->flags |= CODEC_FLAG_4MV;

    }

    //audio params

    if ((e = av_dict_get(conf, "AudioChannels", NULL, 0)))

        ffserver_set_int_param(&enc->channels, e->value, 0, INT_MIN, INT_MAX,

                NULL, 0, NULL);

    if ((e = av_dict_get(conf, "AudioSampleRate", NULL, 0)))

        ffserver_set_int_param(&enc->sample_rate, e->value, 0, INT_MIN,

                INT_MAX, NULL, 0, NULL);

    if ((e = av_dict_get(conf, "AudioBitRate", NULL, 0)))

        ffserver_set_int_param(&enc->bit_rate, e->value, 0, INT_MIN, INT_MAX,

                NULL, 0, NULL);

    av_opt_set_dict2(enc->priv_data, opts, AV_OPT_SEARCH_CHILDREN);

    av_opt_set_dict2(enc, opts, AV_OPT_SEARCH_CHILDREN);

    if (av_dict_count(*opts))

        av_log(NULL, AV_LOG_ERROR, "Something went wrong, %d options not set!!!\n", av_dict_count(*opts));

}


static uint32_t grlib_gptimer_readl(void *opaque, target_phys_addr_t addr)

{

    GPTimerUnit        *unit  = opaque;

    target_phys_addr_t  timer_addr;

    int                 id;

    uint32_t            value = 0;

    addr &= 0xff;

    /* Unit registers */

    switch (addr) {

    case SCALER_OFFSET:

        trace_grlib_gptimer_readl(-1, "scaler:", unit->scaler);

        return unit->scaler;

    case SCALER_RELOAD_OFFSET:

        trace_grlib_gptimer_readl(-1, "reload:", unit->reload);

        return unit->reload;

    case CONFIG_OFFSET:

        trace_grlib_gptimer_readl(-1, "config:", unit->config);

        return unit->config;

    default:

        break;

    }

    timer_addr = (addr % TIMER_BASE);

    id         = (addr - TIMER_BASE) / TIMER_BASE;

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

        /* GPTimer registers */

        switch (timer_addr) {

        case COUNTER_OFFSET:

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

            trace_grlib_gptimer_readl(id, "counter value:", value);

            return value;

        case COUNTER_RELOAD_OFFSET:

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

            trace_grlib_gptimer_readl(id, "reload value:", value);

            return value;

        case CONFIG_OFFSET:

            trace_grlib_gptimer_readl(id, "scaler value:",

                                      unit->timers[id].config);

            return unit->timers[id].config;

        default:

            break;

        }

    }

    trace_grlib_gptimer_unknown_register("read", addr);

    return 0;

}


static void new_subtitle_stream(AVFormatContext *oc, int file_idx)

{

    AVStream *st;

    AVOutputStream *ost;

    AVCodec *codec=NULL;

    AVCodecContext *subtitle_enc;

    enum CodecID codec_id;

    st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0);

    if (!st) {

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

        ffmpeg_exit(1);

    }

    ost = new_output_stream(oc, file_idx);

    subtitle_enc = st->codec;

    output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1);

    if(!subtitle_stream_copy){

        if (subtitle_codec_name) {

            codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1,

                                         avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);

            codec= output_codecs[nb_output_codecs-1] = avcodec_find_encoder_by_name(subtitle_codec_name);

        } else {

            codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_SUBTITLE);

            codec = avcodec_find_encoder(codec_id);

        }

    }

    avcodec_get_context_defaults3(st->codec, codec);

    ost->bitstream_filters = subtitle_bitstream_filters;

    subtitle_bitstream_filters= NULL;

    subtitle_enc->codec_type = AVMEDIA_TYPE_SUBTITLE;

    if(subtitle_codec_tag)

        subtitle_enc->codec_tag= subtitle_codec_tag;

    if (oc->oformat->flags & AVFMT_GLOBALHEADER) {

        subtitle_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;

        avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->flags |= CODEC_FLAG_GLOBAL_HEADER;

    }

    if (subtitle_stream_copy) {

        st->stream_copy = 1;

    } else {

        subtitle_enc->codec_id = codec_id;

        set_context_opts(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], subtitle_enc, AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec);

    }

    if (subtitle_language) {

        av_metadata_set2(&st->metadata, "language", subtitle_language, 0);

        av_freep(&subtitle_language);

    }

    subtitle_disable = 0;

    av_freep(&subtitle_codec_name);

    subtitle_stream_copy = 0;

}


static inline void RENAME(bgr24ToUV_mmx)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src, int width, enum PixelFormat srcFormat)

{

    __asm__ volatile(

        "movq                    24+%4, %%mm6       \n\t"

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

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

        "1:                                         \n\t"

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

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

        "movd                    2(%0), %%mm1       \n\t"

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

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

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

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

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

        "pmaddwd                  8+%4, %%mm1       \n\t"

        "pmaddwd                 16+%4, %%mm2       \n\t"

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

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

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

        "movd                    6(%0), %%mm1       \n\t"

        "movd                    8(%0), %%mm3       \n\t"

        "add                       $12, %0          \n\t"

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

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

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

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

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

        "pmaddwd                  8+%4, %%mm3       \n\t"

        "pmaddwd                 16+%4, %%mm4       \n\t"

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

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

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

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

        "paddd                   %%mm3, %%mm0       \n\t"

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

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

        "paddd                   %%mm3, %%mm4       \n\t"

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

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

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

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

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

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

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

        "packuswb                %%mm2, %%mm2       \n\t"

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

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

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

        " js                        1b              \n\t"

    : "+r" (src)

    : "r" (dstU+width), "r" (dstV+width), "g" ((x86_reg)-width), "m"(ff_bgr24toUV[srcFormat == PIX_FMT_RGB24][0])

    : "%"REG_a

    );

}


static ram_addr_t find_ram_offset(ram_addr_t size)

{

    RAMBlock *block, *next_block;

    ram_addr_t offset, mingap = ULONG_MAX;

    if (QLIST_EMPTY(&ram_list.blocks))

        return 0;

    QLIST_FOREACH(block, &ram_list.blocks, next) {

        ram_addr_t end, next = ULONG_MAX;

        end = block->offset + block->length;

        QLIST_FOREACH(next_block, &ram_list.blocks, next) {

            if (next_block->offset >= end) {

                next = MIN(next, next_block->offset);

            }

        }

        if (next - end >= size && next - end < mingap) {

            offset =  end;

            mingap = next - end;

        }

    }

    return offset;

}


static void guess_dc(MpegEncContext *s, int16_t *dc, int w,

                     int h, int stride, int is_luma)

{

    int b_x, b_y;

    int16_t  (*col )[4] = av_malloc(stride*h*sizeof( int16_t)*4);

    uint32_t (*dist)[4] = av_malloc(stride*h*sizeof(uint32_t)*4);

    for(b_y=0; b_y<h; b_y++){

        int color= 1024;

        int distance= -1;

        for(b_x=0; b_x<w; b_x++){

            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;

            int error_j= s->error_status_table[mb_index_j];

            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);

            if(intra_j==0 || !(error_j&ER_DC_ERROR)){

                color= dc[b_x + b_y*stride];

                distance= b_x;

            }

            col [b_x + b_y*stride][1]= color;

            dist[b_x + b_y*stride][1]= distance >= 0 ? b_x-distance : 9999;

        }

        color= 1024;

        distance= -1;

        for(b_x=w-1; b_x>=0; b_x--){

            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;

            int error_j= s->error_status_table[mb_index_j];

            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);

            if(intra_j==0 || !(error_j&ER_DC_ERROR)){

                color= dc[b_x + b_y*stride];

                distance= b_x;

            }

            col [b_x + b_y*stride][0]= color;

            dist[b_x + b_y*stride][0]= distance >= 0 ? distance-b_x : 9999;

        }

    }

    for(b_x=0; b_x<w; b_x++){

        int color= 1024;

        int distance= -1;

        for(b_y=0; b_y<h; b_y++){

            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;

            int error_j= s->error_status_table[mb_index_j];

            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);

            if(intra_j==0 || !(error_j&ER_DC_ERROR)){

                color= dc[b_x + b_y*stride];

                distance= b_y;

            }

            col [b_x + b_y*stride][3]= color;

            dist[b_x + b_y*stride][3]= distance >= 0 ? b_y-distance : 9999;

        }

        color= 1024;

        distance= -1;

        for(b_y=h-1; b_y>=0; b_y--){

            int mb_index_j= (b_x>>is_luma) + (b_y>>is_luma)*s->mb_stride;

            int error_j= s->error_status_table[mb_index_j];

            int intra_j = IS_INTRA(s->current_picture.f.mb_type[mb_index_j]);

            if(intra_j==0 || !(error_j&ER_DC_ERROR)){

                color= dc[b_x + b_y*stride];

                distance= b_y;

            }

            col [b_x + b_y*stride][2]= color;

            dist[b_x + b_y*stride][2]= distance >= 0 ? distance-b_y : 9999;

        }

    }

    for (b_y = 0; b_y < h; b_y++) {

        for (b_x = 0; b_x < w; b_x++) {

            int mb_index, error, j;

            int64_t guess, weight_sum;

            mb_index = (b_x >> is_luma) + (b_y >> is_luma) * s->mb_stride;

            error    = s->error_status_table[mb_index];

            if (IS_INTER(s->current_picture.f.mb_type[mb_index]))

                continue; // inter

            if (!(error & ER_DC_ERROR))

                continue; // dc-ok

            weight_sum = 0;

            guess      = 0;

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

                int64_t weight  = 256 * 256 * 256 * 16 / dist[b_x + b_y*stride][j];

                guess          += weight*(int64_t)col[b_x + b_y*stride][j];

                weight_sum     += weight;

            }

            guess = (guess + weight_sum / 2) / weight_sum;

            dc[b_x + b_y * stride] = guess;

        }

    }

    av_freep(&col);

    av_freep(&dist);

}


Coroutine *qemu_coroutine_create(CoroutineEntry *entry)

{

    Coroutine *co = NULL;

    if (CONFIG_COROUTINE_POOL) {

        co = QSLIST_FIRST(&alloc_pool);

        if (!co) {

            if (release_pool_size > POOL_BATCH_SIZE) {

                /* Slow path; a good place to register the destructor, too.  */

                if (!coroutine_pool_cleanup_notifier.notify) {

                    coroutine_pool_cleanup_notifier.notify = coroutine_pool_cleanup;

                    qemu_thread_atexit_add(&coroutine_pool_cleanup_notifier);

                }

                /* This is not exact; there could be a little skew between

                 * release_pool_size and the actual size of release_pool.  But

                 * it is just a heuristic, it does not need to be perfect.

                 */

                alloc_pool_size = atomic_xchg(&release_pool_size, 0);

                QSLIST_MOVE_ATOMIC(&alloc_pool, &release_pool);

                co = QSLIST_FIRST(&alloc_pool);

            }

        }

        if (co) {

            QSLIST_REMOVE_HEAD(&alloc_pool, pool_next);

            alloc_pool_size--;

        }

    }

    if (!co) {

        co = qemu_coroutine_new();

    }

    co->entry = entry;

    QSIMPLEQ_INIT(&co->co_queue_wakeup);

    return co;

}


static void pxa2xx_gpio_write(void *opaque,

                target_phys_addr_t offset, uint32_t value)

{

    struct pxa2xx_gpio_info_s *s = (struct pxa2xx_gpio_info_s *) opaque;

    int bank;

    offset -= s->base;

    if (offset >= 0x200)

        return;

    bank = pxa2xx_gpio_regs[offset].bank;

    switch (pxa2xx_gpio_regs[offset].reg) {

    case GPDR:		/* GPIO Pin-Direction registers */

        s->dir[bank] = value;

        pxa2xx_gpio_handler_update(s);

        break;

    case GPSR:		/* GPIO Pin-Output Set registers */

        s->olevel[bank] |= value;

        pxa2xx_gpio_handler_update(s);

        break;

    case GPCR:		/* GPIO Pin-Output Clear registers */

        s->olevel[bank] &= ~value;

        pxa2xx_gpio_handler_update(s);

        break;

    case GRER:		/* GPIO Rising-Edge Detect Enable registers */

        s->rising[bank] = value;

        break;

    case GFER:		/* GPIO Falling-Edge Detect Enable registers */

        s->falling[bank] = value;

        break;

    case GAFR_L:	/* GPIO Alternate Function registers */

        s->gafr[bank * 2] = value;

        break;

    case GAFR_U:	/* GPIO Alternate Function registers */

        s->gafr[bank * 2 + 1] = value;

        break;

    case GEDR:		/* GPIO Edge Detect Status registers */

        s->status[bank] &= ~value;

        pxa2xx_gpio_irq_update(s);

        break;

    default:

        cpu_abort(cpu_single_env,

                "%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);

    }

}


static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr)

{

    AVFormatContext *s = nut->avf;

    AVIOContext *bc    = s->pb;

    int64_t end;

    uint64_t tmp;

    nut->last_syncpoint_pos = avio_tell(bc) - 8;

    end  = get_packetheader(nut, bc, 1, SYNCPOINT_STARTCODE);

    end += avio_tell(bc);

    tmp       = ffio_read_varlen(bc);

    *back_ptr = nut->last_syncpoint_pos - 16 * ffio_read_varlen(bc);

    if (*back_ptr < 0)

        return -1;

    ff_nut_reset_ts(nut, nut->time_base[tmp % nut->time_base_count],

                    tmp / nut->time_base_count);

    if (skip_reserved(bc, end) || ffio_get_checksum(bc)) {

        av_log(s, AV_LOG_ERROR, "sync point checksum mismatch\n");

        return -1;

    }

    *ts = tmp / s->nb_streams *

          av_q2d(nut->time_base[tmp % s->nb_streams]) * AV_TIME_BASE;

    ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts);

    return 0;

}


static void coroutine_fn v9fs_flush(void *opaque)

{

    ssize_t err;

    int16_t tag;

    size_t offset = 7;

    V9fsPDU *cancel_pdu;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    err = pdu_unmarshal(pdu, offset, "w", &tag);

    if (err < 0) {

        pdu_complete(pdu, err);

        return;

    }

    trace_v9fs_flush(pdu->tag, pdu->id, tag);

    QLIST_FOREACH(cancel_pdu, &s->active_list, next) {

        if (cancel_pdu->tag == tag) {

            break;

        }

    }

    if (cancel_pdu) {

        cancel_pdu->cancelled = 1;

        /*

         * Wait for pdu to complete.

         */

        qemu_co_queue_wait(&cancel_pdu->complete, NULL);

        cancel_pdu->cancelled = 0;

        pdu_free(cancel_pdu);

    }

    pdu_complete(pdu, 7);

}


static inline void expand_category(COOKContext *q, int *category,

                                   int *category_index)

{

    int i;

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

        ++category[category_index[i]];

}


static int gif_encode_close(AVCodecContext *avctx)

{

    GIFContext *s = avctx->priv_data;

    av_frame_free(&avctx->coded_frame);

    av_freep(&s->lzw);

    av_freep(&s->buf);

    return 0;

}


static av_cold int vqa_decode_end(AVCodecContext *avctx)

{

    VqaContext *s = avctx->priv_data;

    av_free(s->codebook);

    av_free(s->next_codebook_buffer);

    av_free(s->decode_buffer);

    if (s->frame.data[0])

        avctx->release_buffer(avctx, &s->frame);

    return 0;

}


static av_cold int pam_encode_init(AVCodecContext *avctx)

{

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame)

        return AVERROR(ENOMEM);

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    return 0;

}


static int write_l2_entries(BlockDriverState *bs, uint64_t *l2_table,

    uint64_t l2_offset, int l2_index, int num)

{

    int l2_start_index = l2_index & ~(L1_ENTRIES_PER_SECTOR - 1);

    int start_offset = (8 * l2_index) & ~511;

    int end_offset = (8 * (l2_index + num) + 511) & ~511;

    size_t len = end_offset - start_offset;

    int ret;

    BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);

    ret = bdrv_pwrite(bs->file, l2_offset + start_offset,

        &l2_table[l2_start_index], len);

    if (ret < 0) {

        return ret;

    }

    return 0;

}


static void FUNC(put_hevc_qpel_bi_w_h)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,

                                       int16_t *src2,

                                       int height, int denom, int wx0, int wx1,

                                       int ox0, int ox1, intptr_t mx, intptr_t my, int width)

{

    int x, y;

    pixel        *src       = (pixel*)_src;

    ptrdiff_t     srcstride = _srcstride / sizeof(pixel);

    pixel *dst          = (pixel *)_dst;

    ptrdiff_t dststride = _dststride / sizeof(pixel);

    const int8_t *filter    = ff_hevc_qpel_filters[mx - 1];

    int shift = 14  + 1 - BIT_DEPTH;

    int log2Wd = denom + shift - 1;

    ox0     = ox0 * (1 << (BIT_DEPTH - 8));

    ox1     = ox1 * (1 << (BIT_DEPTH - 8));

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

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

            dst[x] = av_clip_pixel(((QPEL_FILTER(src, 1) >> (BIT_DEPTH - 8)) * wx1 + src2[x] * wx0 +

                                    ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));

        src  += srcstride;

        dst  += dststride;

        src2 += MAX_PB_SIZE;

    }

}


void virtqueue_flush(VirtQueue *vq, unsigned int count)
{
    uint16_t old, new;
    /* Make sure buffer is written before we update index. */
    smp_wmb();
    trace_virtqueue_flush(vq, count);
    old = vq->used_idx;
    new = old + count;
    vring_used_idx_set(vq, new);
    if (unlikely((int16_t)(new - vq->signalled_used) < (uint16_t)(new - old)))
        vq->signalled_used_valid = false;


static void xbr4x(AVFrame *input, AVFrame *output, const uint32_t *r2y)

{

    const int nl = output->linesize[0]>>2;

    const int nl1 = nl + nl;

    const int nl2 = nl1 + nl;

    uint32_t pprev;

    uint32_t pprev2;

    int x, y;

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

        uint32_t * E = (uint32_t *)(output->data[0] + y * output->linesize[0] * 4);

        /* middle. Offset of -8 is given */

        uint32_t * sa2 = (uint32_t *)(input->data[0] + y * input->linesize[0] - 8);

        /* up one */

        uint32_t * sa1 = sa2 - (input->linesize[0]>>2);

        /* up two */

        uint32_t * sa0 = sa1 - (input->linesize[0]>>2);

        /* down one */

        uint32_t * sa3 = sa2 + (input->linesize[0]>>2);

        /* down two */

        uint32_t * sa4 = sa3 + (input->linesize[0]>>2);

        if (y <= 1) {

            sa0 = sa1;

            if (y == 0) {

                sa0 = sa1 = sa2;

            }

        }

        if (y >= input->height - 2) {

            sa4 = sa3;

            if (y == input->height - 1) {

                sa4 = sa3 = sa2;

            }

        }

        pprev = pprev2 = 2;

        for (x = 0; x < input->width; x++) {

            uint32_t B1 = sa0[2];

            uint32_t PB = sa1[2];

            uint32_t PE = sa2[2];

            uint32_t PH = sa3[2];

            uint32_t H5 = sa4[2];

            uint32_t A1 = sa0[pprev];

            uint32_t PA = sa1[pprev];

            uint32_t PD = sa2[pprev];

            uint32_t PG = sa3[pprev];

            uint32_t G5 = sa4[pprev];

            uint32_t A0 = sa1[pprev2];

            uint32_t D0 = sa2[pprev2];

            uint32_t G0 = sa3[pprev2];

            uint32_t C1 = 0;

            uint32_t PC = 0;

            uint32_t PF = 0;

            uint32_t PI = 0;

            uint32_t I5 = 0;

            uint32_t C4 = 0;

            uint32_t F4 = 0;

            uint32_t I4 = 0;

            if (x >= input->width - 2) {

                if (x == input->width - 1) {

                    C1 = sa0[2];

                    PC = sa1[2];

                    PF = sa2[2];

                    PI = sa3[2];

                    I5 = sa4[2];

                    C4 = sa1[2];

                    F4 = sa2[2];

                    I4 = sa3[2];

                } else {

                    C1 = sa0[3];

                    PC = sa1[3];

                    PF = sa2[3];

                    PI = sa3[3];

                    I5 = sa4[3];

                    C4 = sa1[3];

                    F4 = sa2[3];

                    I4 = sa3[3];

                }

            } else {

                C1 = sa0[3];

                PC = sa1[3];

                PF = sa2[3];

                PI = sa3[3];

                I5 = sa4[3];

                C4 = sa1[4];

                F4 = sa2[4];

                I4 = sa3[4];

            }

            E[0]   = E[1]     = E[2]     = E[3]     = PE;

            E[nl]  = E[nl+1]  = E[nl+2]  = E[nl+3]  = PE; //  4,  5,  6,  7

            E[nl1] = E[nl1+1] = E[nl1+2] = E[nl1+3] = PE; //  8,  9, 10, 11

            E[nl2] = E[nl2+1] = E[nl2+2] = E[nl2+3] = PE; // 12, 13, 14, 15

            FILT4(PE, PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, nl2+3, nl2+2, nl1+3,  3,  nl+3, nl1+2, nl2+1, nl2,  nl1+1,  nl+2, 2,  1, nl+1, nl1, nl, 0);

            FILT4(PE, PC, PF, PB, PI, PA, PH, PD, PG, I4, A1, I5, H5, A0, D0, B1, C1, F4, C4, G5, G0,  3,  nl+3,  2,  0,  1,  nl+2, nl1+3, nl2+3, nl1+2,  nl+1, nl,  nl1, nl1+1,nl2+2,nl2+1,nl2);

            FILT4(PE, PA, PB, PD, PC, PG, PF, PH, PI, C1, G0, C4, F4, G5, H5, D0, A0, B1, A1, I4, I5,  0,  1,  nl, nl2,  nl1,  nl+1,  2,  3,  nl+2,  nl1+1, nl2+1,nl2+2,nl1+2, nl+3,nl1+3,nl2+3);

            FILT4(PE, PG, PD, PH, PA, PI, PB, PF, PC, A0, I5, A1, B1, I4, F4, H5, G5, D0, G0, C1, C4, nl2,  nl1, nl2+1, nl2+3, nl2+2,  nl1+1,  nl,  0,  nl+1, nl1+2, nl1+3, nl+3, nl+2, 1, 2, 3);

            sa0 += 1;

            sa1 += 1;

            sa2 += 1;

            sa3 += 1;

            sa4 += 1;

            E += 4;

            if (pprev2){

                pprev2--;

                pprev = 1;

            }

        }

    }

}


const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){

    int i, si, di;

    uint8_t *dst;

    int bufidx;

//    src[0]&0x80;                //forbidden bit

    h->nal_ref_idc= src[0]>>5;

    h->nal_unit_type= src[0]&0x1F;

    src++; length--;

#if HAVE_FAST_UNALIGNED

# if HAVE_FAST_64BIT

#   define RS 7

    for(i=0; i+1<length; i+=9){

        if(!((~AV_RN64A(src+i) & (AV_RN64A(src+i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL))

# else

#   define RS 3

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

        if(!((~AV_RN32A(src+i) & (AV_RN32A(src+i) - 0x01000101U)) & 0x80008080U))

# endif

            continue;

        if(i>0 && !src[i]) i--;

        while(src[i]) i++;

#else

#   define RS 0

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

        if(src[i]) continue;

        if(i>0 && src[i-1]==0) i--;

#endif

        if(i+2<length && src[i+1]==0 && src[i+2]<=3){

            if(src[i+2]!=3){

                /* startcode, so we must be past the end */

                length=i;

            }

            break;

        }

        i-= RS;

    }

    if(i>=length-1){ //no escaped 0

        *dst_length= length;

        *consumed= length+1; //+1 for the header

        return src;

    }

    bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data

    av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE);

    dst= h->rbsp_buffer[bufidx];

    if (dst == NULL){

        return NULL;

    }

//printf("decoding esc\n");

    memcpy(dst, src, i);

    si=di=i;

    while(si+2<length){

        //remove escapes (very rare 1:2^22)

        if(src[si+2]>3){

            dst[di++]= src[si++];

            dst[di++]= src[si++];

        }else if(src[si]==0 && src[si+1]==0){

            if(src[si+2]==3){ //escape

                dst[di++]= 0;

                dst[di++]= 0;

                si+=3;

                continue;

            }else //next start code

                goto nsc;

        }

        dst[di++]= src[si++];

    }

    while(si<length)

        dst[di++]= src[si++];

nsc:

    memset(dst+di, 0, FF_INPUT_BUFFER_PADDING_SIZE);

    *dst_length= di;

    *consumed= si + 1;//+1 for the header

//FIXME store exact number of bits in the getbitcontext (it is needed for decoding)

    return dst;

}


static void dct_unquantize_mpeg2_mmx(MpegEncContext *s,

                                     DCTELEM *block, int n, int qscale)

{

    int nCoeffs;

    const UINT16 *quant_matrix;

    if(s->alternate_scan) nCoeffs= 64;

    else nCoeffs= nCoeffs= zigzag_end[ s->block_last_index[n] ];

    if (s->mb_intra) {

        int block0;

        if (n < 4)

            block0 = block[0] * s->y_dc_scale;

        else

            block0 = block[0] * s->c_dc_scale;

        quant_matrix = s->intra_matrix;

asm volatile(

		"pcmpeqw %%mm7, %%mm7		\n\t"

		"psrlw $15, %%mm7		\n\t"

		"movd %2, %%mm6			\n\t"

		"packssdw %%mm6, %%mm6		\n\t"

		"packssdw %%mm6, %%mm6		\n\t"

                "movl %3, %%eax			\n\t"

		".balign 16\n\t"

		"1:				\n\t"

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

		"movq 8(%0, %%eax), %%mm1	\n\t"

		"movq (%1, %%eax), %%mm4	\n\t"

		"movq 8(%1, %%eax), %%mm5	\n\t"

		"pmullw %%mm6, %%mm4		\n\t" // q=qscale*quant_matrix[i]

		"pmullw %%mm6, %%mm5		\n\t" // q=qscale*quant_matrix[i]

		"pxor %%mm2, %%mm2		\n\t"

		"pxor %%mm3, %%mm3		\n\t"

		"pcmpgtw %%mm0, %%mm2		\n\t" // block[i] < 0 ? -1 : 0

		"pcmpgtw %%mm1, %%mm3		\n\t" // block[i] < 0 ? -1 : 0

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

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

		"psubw %%mm2, %%mm0		\n\t" // abs(block[i])

		"psubw %%mm3, %%mm1		\n\t" // abs(block[i])

		"pmullw %%mm4, %%mm0		\n\t" // abs(block[i])*q

		"pmullw %%mm5, %%mm1		\n\t" // abs(block[i])*q

		"pxor %%mm4, %%mm4		\n\t"

		"pxor %%mm5, %%mm5		\n\t" // FIXME slow

		"pcmpeqw (%0, %%eax), %%mm4	\n\t" // block[i] == 0 ? -1 : 0

		"pcmpeqw 8(%0, %%eax), %%mm5	\n\t" // block[i] == 0 ? -1 : 0

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

		"psraw $3, %%mm1		\n\t"

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

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

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

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

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

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

		"movq %%mm4, (%0, %%eax)	\n\t"

		"movq %%mm5, 8(%0, %%eax)	\n\t"

		"addl $16, %%eax		\n\t"

		"js 1b				\n\t"

		::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "g" (-2*nCoeffs)

		: "%eax", "memory"

	);

        block[0]= block0;

        //Note, we dont do mismatch control for intra as errors cannot accumulate

    } else {

        quant_matrix = s->non_intra_matrix;

asm volatile(

		"pcmpeqw %%mm7, %%mm7		\n\t"

                "psrlq $48, %%mm7		\n\t"

		"movd %2, %%mm6			\n\t"

		"packssdw %%mm6, %%mm6		\n\t"

		"packssdw %%mm6, %%mm6		\n\t"

                "movl %3, %%eax			\n\t"

		".balign 16\n\t"

		"1:				\n\t"

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

		"movq 8(%0, %%eax), %%mm1	\n\t"

		"movq (%1, %%eax), %%mm4	\n\t"

		"movq 8(%1, %%eax), %%mm5	\n\t"

		"pmullw %%mm6, %%mm4		\n\t" // q=qscale*quant_matrix[i]

		"pmullw %%mm6, %%mm5		\n\t" // q=qscale*quant_matrix[i]

		"pxor %%mm2, %%mm2		\n\t"

		"pxor %%mm3, %%mm3		\n\t"

		"pcmpgtw %%mm0, %%mm2		\n\t" // block[i] < 0 ? -1 : 0

		"pcmpgtw %%mm1, %%mm3		\n\t" // block[i] < 0 ? -1 : 0

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

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

		"psubw %%mm2, %%mm0		\n\t" // abs(block[i])

		"psubw %%mm3, %%mm1		\n\t" // abs(block[i])

		"paddw %%mm0, %%mm0		\n\t" // abs(block[i])*2

		"paddw %%mm1, %%mm1		\n\t" // abs(block[i])*2

		"pmullw %%mm4, %%mm0		\n\t" // abs(block[i])*2*q

		"pmullw %%mm5, %%mm1		\n\t" // abs(block[i])*2*q

		"paddw %%mm4, %%mm0		\n\t" // (abs(block[i])*2 + 1)*q

		"paddw %%mm5, %%mm1		\n\t" // (abs(block[i])*2 + 1)*q

		"pxor %%mm4, %%mm4		\n\t"

		"pxor %%mm5, %%mm5		\n\t" // FIXME slow

		"pcmpeqw (%0, %%eax), %%mm4	\n\t" // block[i] == 0 ? -1 : 0

		"pcmpeqw 8(%0, %%eax), %%mm5	\n\t" // block[i] == 0 ? -1 : 0

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

		"psrlw $4, %%mm1		\n\t"

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

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

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

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

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

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

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

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

		"movq %%mm4, (%0, %%eax)	\n\t"

		"movq %%mm5, 8(%0, %%eax)	\n\t"

		"addl $16, %%eax		\n\t"

		"js 1b				\n\t"

                "movd 124(%0, %3), %%mm0	\n\t"

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

                "psrlq $32, %%mm7		\n\t"

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

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

                "psrlq $16, %%mm7		\n\t"

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

                "pslld $31, %%mm7		\n\t"

                "psrlq $15, %%mm7		\n\t"

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

                "movd %%mm0, 124(%0, %3)	\n\t"

		::"r" (block+nCoeffs), "r"(quant_matrix+nCoeffs), "g" (qscale), "r" (-2*nCoeffs)

		: "%eax", "memory"

	);

    }

}


static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)

{

    int i;

    avio_wb32(pb, 24); /* size */

    ffio_wfourcc(pb, "ACLR");

    ffio_wfourcc(pb, "ACLR");

    ffio_wfourcc(pb, "0001");

    if (track->enc->color_range == AVCOL_RANGE_MPEG || /* Legal range (16-235) */

        track->enc->color_range == AVCOL_RANGE_UNSPECIFIED) {

        avio_wb32(pb, 1); /* Corresponds to 709 in official encoder */

    } else { /* Full range (0-255) */

        avio_wb32(pb, 2); /* Corresponds to RGB in official encoder */

    }

    avio_wb32(pb, 0); /* unknown */

    avio_wb32(pb, 24); /* size */

    ffio_wfourcc(pb, "APRG");

    ffio_wfourcc(pb, "APRG");

    ffio_wfourcc(pb, "0001");

    avio_wb32(pb, 1); /* unknown */

    avio_wb32(pb, 0); /* unknown */

    avio_wb32(pb, 120); /* size */

    ffio_wfourcc(pb, "ARES");

    ffio_wfourcc(pb, "ARES");

    ffio_wfourcc(pb, "0001");

    avio_wb32(pb, AV_RB32(track->vos_data + 0x28)); /* dnxhd cid, some id ? */

    avio_wb32(pb, track->enc->width);

    /* values below are based on samples created with quicktime and avid codecs */

    if (track->vos_data[5] & 2) { // interlaced

        avio_wb32(pb, track->enc->height / 2);

        avio_wb32(pb, 2); /* unknown */

        avio_wb32(pb, 0); /* unknown */

        avio_wb32(pb, 4); /* unknown */

    } else {

        avio_wb32(pb, track->enc->height);

        avio_wb32(pb, 1); /* unknown */

        avio_wb32(pb, 0); /* unknown */

        if (track->enc->height == 1080)

            avio_wb32(pb, 5); /* unknown */

        else

            avio_wb32(pb, 6); /* unknown */

    }

    /* padding */

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

        avio_wb64(pb, 0);

    /* extra padding for stsd needed */

    avio_wb32(pb, 0);

    return 0;

}


static qemu_irq *icp_pic_init(uint32_t base,

                              qemu_irq parent_irq, qemu_irq parent_fiq)

{

    icp_pic_state *s;

    int iomemtype;

    qemu_irq *qi;

    s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));

    if (!s)

        return NULL;

    qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32);

    s->base = base;

    s->parent_irq = parent_irq;

    s->parent_fiq = parent_fiq;

    iomemtype = cpu_register_io_memory(0, icp_pic_readfn,

                                       icp_pic_writefn, s);

    cpu_register_physical_memory(base, 0x007fffff, iomemtype);

    /* ??? Save/restore.  */

    return qi;

}


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

                               AVFrame *p)

{

    int i, j;

    uint8_t *pd      = p->data[0];

    uint8_t *pd_last = s->last_picture.f->data[0];

    uint8_t *pd_last_region = s->dispose_op == APNG_DISPOSE_OP_PREVIOUS ?

                                s->previous_picture.f->data[0] : s->last_picture.f->data[0];

    int ls = FFMIN(av_image_get_linesize(p->format, s->width, 0), s->width * s->bpp);

    if (s->blend_op == APNG_BLEND_OP_OVER &&

        avctx->pix_fmt != AV_PIX_FMT_RGBA && avctx->pix_fmt != AV_PIX_FMT_ARGB) {

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

                              av_get_pix_fmt_name(avctx->pix_fmt));

        return AVERROR_PATCHWELCOME;

    }

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

    if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS)

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

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

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

            pd[i] = pd_last[i];

        pd      += s->image_linesize;

        pd_last += s->image_linesize;

    }

    if (s->dispose_op != APNG_DISPOSE_OP_BACKGROUND && s->blend_op == APNG_BLEND_OP_OVER) {

        uint8_t ri, gi, bi, ai;

        pd_last_region += s->y_offset * s->image_linesize;

        if (avctx->pix_fmt == AV_PIX_FMT_RGBA) {

            ri = 0;

            gi = 1;

            bi = 2;

            ai = 3;

        } else {

            ri = 3;

            gi = 2;

            bi = 1;

            ai = 0;

        }

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

            for (i = 0; i < s->x_offset * s->bpp; i++)

                pd[i] = pd_last[i];

            for (; i < (s->x_offset + s->cur_w) * s->bpp; i += s->bpp) {

                uint8_t alpha = pd[i+ai];

                /* output = alpha * foreground + (1-alpha) * background */

                switch (alpha) {

                case 0:

                    pd[i+ri] = pd_last_region[i+ri];

                    pd[i+gi] = pd_last_region[i+gi];

                    pd[i+bi] = pd_last_region[i+bi];

                    pd[i+ai] = 0xff;

                    break;

                case 255:

                    break;

                default:

                    pd[i+ri] = FAST_DIV255(alpha * pd[i+ri] + (255 - alpha) * pd_last_region[i+ri]);

                    pd[i+gi] = FAST_DIV255(alpha * pd[i+gi] + (255 - alpha) * pd_last_region[i+gi]);

                    pd[i+bi] = FAST_DIV255(alpha * pd[i+bi] + (255 - alpha) * pd_last_region[i+bi]);

                    pd[i+ai] = 0xff;

                    break;

                }

            }

            for (; i < ls; i++)

                pd[i] = pd_last[i];

            pd      += s->image_linesize;

            pd_last += s->image_linesize;

            pd_last_region += s->image_linesize;

        }

    } else {

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

            for (i = 0; i < s->x_offset * s->bpp; i++)

                pd[i] = pd_last[i];

            for (i = (s->x_offset + s->cur_w) * s->bpp; i < ls; i++)

                pd[i] = pd_last[i];

            pd      += s->image_linesize;

            pd_last += s->image_linesize;

        }

    }

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

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

            pd[i] = pd_last[i];

        pd      += s->image_linesize;

        pd_last += s->image_linesize;

    }

    return 0;

}


static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8_t *n_val)

{

    OMAContext *oc = s->priv_data;

    uint32_t pos, taglen, datalen;

    struct AVDES av_des;

    if (!enc_header || !n_val)

        return -1;

    pos = OMA_ENC_HEADER_SIZE + oc->k_size;

    if (!memcmp(&enc_header[pos], "EKB ", 4))

        pos += 32;

    if (AV_RB32(&enc_header[pos]) != oc->rid)

        av_log(s, AV_LOG_DEBUG, "Mismatching RID\n");

    taglen = AV_RB32(&enc_header[pos+32]);

    datalen = AV_RB32(&enc_header[pos+36]) >> 4;

    if(taglen + (((uint64_t)datalen)<<4) + 44 > size)

        return -1;

    pos += 44 + taglen;

    av_des_init(&av_des, n_val, 192, 1);

    while (datalen-- > 0) {

        av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1);

        kset(s, oc->r_val, NULL, 16);

        if (!rprobe(s, enc_header, oc->r_val))

            return 0;

        pos += 16;

    }

    return -1;

}


REORDER_OUT_50(int8, int8_t)

REORDER_OUT_51(int8, int8_t)

REORDER_OUT_71(int8, int8_t)

REORDER_OUT_50(int16, int16_t)

REORDER_OUT_51(int16, int16_t)

REORDER_OUT_71(int16, int16_t)

REORDER_OUT_50(int32, int32_t)

REORDER_OUT_51(int32, int32_t)

REORDER_OUT_71(int32, int32_t)

REORDER_OUT_50(f32, float)

REORDER_OUT_51(f32, float)

REORDER_OUT_71(f32, float)

#define FORMAT_I8  0

#define FORMAT_I16 1

#define FORMAT_I32 2

#define FORMAT_F32 3

#define PICK_REORDER(layout)\

switch(format) {\

    case FORMAT_I8:  s->reorder_func = alsa_reorder_int8_out_ ##layout;  break;\

    case FORMAT_I16: s->reorder_func = alsa_reorder_int16_out_ ##layout; break;\

    case FORMAT_I32: s->reorder_func = alsa_reorder_int32_out_ ##layout; break;\

    case FORMAT_F32: s->reorder_func = alsa_reorder_f32_out_ ##layout;   break;\

}

static av_cold int find_reorder_func(AlsaData *s, int codec_id, int64_t layout, int out)

{

    int format;

    /* reordering input is not currently supported */

    if (!out)

        return AVERROR(ENOSYS);

    /* reordering is not needed for QUAD or 2_2 layout */

    if (layout == AV_CH_LAYOUT_QUAD || layout == AV_CH_LAYOUT_2_2)

        return 0;

    switch (codec_id) {

    case CODEC_ID_PCM_S8:

    case CODEC_ID_PCM_U8:

    case CODEC_ID_PCM_ALAW:

    case CODEC_ID_PCM_MULAW: format = FORMAT_I8;  break;

    case CODEC_ID_PCM_S16LE:

    case CODEC_ID_PCM_S16BE:

    case CODEC_ID_PCM_U16LE:

    case CODEC_ID_PCM_U16BE: format = FORMAT_I16; break;

    case CODEC_ID_PCM_S32LE:

    case CODEC_ID_PCM_S32BE:

    case CODEC_ID_PCM_U32LE:

    case CODEC_ID_PCM_U32BE: format = FORMAT_I32; break;

    case CODEC_ID_PCM_F32LE:

    case CODEC_ID_PCM_F32BE: format = FORMAT_F32; break;

    default:                 return AVERROR(ENOSYS);

    }

    if      (layout == AV_CH_LAYOUT_5POINT0_BACK || layout == AV_CH_LAYOUT_5POINT0)

        PICK_REORDER(50)

    else if (layout == AV_CH_LAYOUT_5POINT1_BACK || layout == AV_CH_LAYOUT_5POINT1)

        PICK_REORDER(51)

    else if (layout == AV_CH_LAYOUT_7POINT1)

        PICK_REORDER(71)

    return s->reorder_func ? 0 : AVERROR(ENOSYS);

}


static inline void RENAME(rgb24ToY)(uint8_t *dst, uint8_t *src, int width)

{

	int i;

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

	{

		int r= src[i*3+0];

		int g= src[i*3+1];

		int b= src[i*3+2];

		dst[i]= ((RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1)) )>>RGB2YUV_SHIFT);

	}

}


static void dcr_write_pob (void *opaque, int dcrn, uint32_t val)

{

    ppc4xx_pob_t *pob;

    pob = opaque;

    switch (dcrn) {

    case POB0_BEAR:

        /* Read only */

        break;

    case POB0_BESR0:

    case POB0_BESR1:

        /* Write-clear */

        pob->besr[dcrn - POB0_BESR0] &= ~val;

        break;

    }

}


static inline void yuv2yuvXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

				    uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)

{

	//FIXME Optimize (just quickly writen not opti..)

	int i;

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

	{

		int val=1<<18;

		int j;

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

			val += lumSrc[j][i] * lumFilter[j];

		dest[i]= av_clip_uint8(val>>19);

	}

	if(uDest != NULL)

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

		{

			int u=1<<18;

			int v=1<<18;

			int j;

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

			{

				u += chrSrc[j][i] * chrFilter[j];

				v += chrSrc[j][i + 2048] * chrFilter[j];

			}

			uDest[i]= av_clip_uint8(u>>19);

			vDest[i]= av_clip_uint8(v>>19);

		}

}


static int mjpeg_decode_com(MJpegDecodeContext *s)

{

    int i;

    UINT8 *cbuf;

    /* XXX: verify len field validity */

    unsigned int len = get_bits(&s->gb, 16)-2;

    cbuf = av_malloc(len+1);

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

	cbuf[i] = get_bits(&s->gb, 8);

    if (cbuf[i-1] == '\n')

	cbuf[i-1] = 0;

    else

	cbuf[i] = 0;

    printf("mjpeg comment: '%s'\n", cbuf);

    /* buggy avid, it puts EOI only at every 10th frame */

    if (!strcmp(cbuf, "AVID"))

    {

	s->buggy_avid = 1;

//	if (s->first_picture)

//	    printf("mjpeg: workarounding buggy AVID\n");

    }

    av_free(cbuf);

    return 0;

}