static int transcode(AVFormatContext **output_files,

                     int nb_output_files,

                     AVFormatContext **input_files,

                     int nb_input_files,

                     AVStreamMap *stream_maps, int nb_stream_maps)

{

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

    AVFormatContext *is, *os;

    AVCodecContext *codec, *icodec;

    AVOutputStream *ost, **ost_table = NULL;

    AVInputStream *ist, **ist_table = NULL;

    AVInputFile *file_table;

    char error[1024];

    int key;

    int want_sdp = 1;

    uint8_t no_packet[MAX_FILES]={0};

    int no_packet_count=0;

    int nb_frame_threshold[AVMEDIA_TYPE_NB]={0};

    int nb_streams[AVMEDIA_TYPE_NB]={0};

    file_table= 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 (rate_emu) {

                ist->start = av_gettime();

            }

        }

    }

    /* output stream init */

    nb_ostreams = 0;

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

        os = output_files[i];

        if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) {

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

            fprintf(stderr, "Output file #%d does not contain any stream\n", i);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        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");

        ret = AVERROR(EINVAL);

        goto fail;

    }

    /* 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);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        fi = stream_maps[i].sync_file_index;

        si = stream_maps[i].sync_stream_index;

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

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

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

            ret = AVERROR(EINVAL);

            goto fail;

        }

    }

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

    if (!ost_table)

        goto fail;

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

        os = output_files[k];

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

            nb_streams[os->streams[i]->codec->codec_type]++;

        }

    }

    for(step=1<<30; step; step>>=1){

        int found_streams[AVMEDIA_TYPE_NB]={0};

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

            nb_frame_threshold[j] += step;

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

            int skip=0;

            ist = ist_table[j];

            if(opt_programid){

                int pi,si;

                AVFormatContext *f= input_files[ ist->file_index ];

                skip=1;

                for(pi=0; pi<f->nb_programs; pi++){

                    AVProgram *p= f->programs[pi];

                    if(p->id == opt_programid)

                        for(si=0; si<p->nb_stream_indexes; si++){

                            if(f->streams[ p->stream_index[si] ] == ist->st)

                                skip=0;

                        }

                }

            }

            if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip

                && nb_frame_threshold[ist->st->codec->codec_type] <= ist->st->codec_info_nb_frames){

                found_streams[ist->st->codec->codec_type]++;

            }

        }

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

            if(found_streams[j] < nb_streams[j])

                nb_frame_threshold[j] -= step;

    }

    n = 0;

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

        os = output_files[k];

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

            int found;

            ost = ost_table[n] = output_streams_for_file[k][i];

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

            if (nb_stream_maps > 0) {

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

                    stream_maps[n].stream_index;

                /* Sanity check that the stream types match */

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

                    int i= ost->file_index;

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

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

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

                        ost->file_index, ost->index);

                    ffmpeg_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++) {

                    int skip=0;

                    ist = ist_table[j];

                    if(opt_programid){

                        int pi,si;

                        AVFormatContext *f= input_files[ ist->file_index ];

                        skip=1;

                        for(pi=0; pi<f->nb_programs; pi++){

                            AVProgram *p= f->programs[pi];

                            if(p->id == opt_programid)

                                for(si=0; si<p->nb_stream_indexes; si++){

                                    if(f->streams[ p->stream_index[si] ] == ist->st)

                                        skip=0;

                                }

                        }

                    }

                    if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip &&

                        ist->st->codec->codec_type == ost->st->codec->codec_type &&

                        nb_frame_threshold[ist->st->codec->codec_type] <= ist->st->codec_info_nb_frames) {

                            ost->source_index = j;

                            found = 1;

                            break;

                    }

                }

                if (!found) {

                    if(! opt_programid) {

                        /* 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

                                && ist->st->discard != AVDISCARD_ALL) {

                                ost->source_index = j;

                                found = 1;

                            }

                        }

                    }

                    if (!found) {

                        int i= ost->file_index;

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

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

                                ost->file_index, ost->index);

                        ffmpeg_exit(1);

                    }

                }

            }

            ist = ist_table[ost->source_index];

            ist->discard = 0;

            ost->sync_ist = (nb_stream_maps > 0) ?

                ist_table[file_table[stream_maps[n].sync_file_index].ist_index +

                         stream_maps[n].sync_stream_index] : ist;

        }

    }

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

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

        ost = ost_table[i];

        os = output_files[ost->file_index];

        ist = ist_table[ost->source_index];

        codec = ost->st->codec;

        icodec = ist->st->codec;

        if (metadata_streams_autocopy)

            av_metadata_copy(&ost->st->metadata, ist->st->metadata,

                             AV_METADATA_DONT_OVERWRITE);

        ost->st->disposition = ist->st->disposition;

        codec->bits_per_raw_sample= icodec->bits_per_raw_sample;

        codec->chroma_sample_location = icodec->chroma_sample_location;

        if (ost->st->stream_copy) {

            uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;

            if (extra_size > INT_MAX)

                goto fail;

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

            codec->codec_id = icodec->codec_id;

            codec->codec_type = icodec->codec_type;

            if(!codec->codec_tag){

                if(   !os->oformat->codec_tag

                   || av_codec_get_id (os->oformat->codec_tag, icodec->codec_tag) == codec->codec_id

                   || av_codec_get_tag(os->oformat->codec_tag, icodec->codec_id) <= 0)

                    codec->codec_tag = icodec->codec_tag;

            }

            codec->bit_rate = icodec->bit_rate;

            codec->rc_max_rate    = icodec->rc_max_rate;

            codec->rc_buffer_size = icodec->rc_buffer_size;

            codec->extradata= av_mallocz(extra_size);

            if (!codec->extradata)

                goto fail;

            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);

            codec->extradata_size= icodec->extradata_size;

            if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){

                codec->time_base = icodec->time_base;

                codec->time_base.num *= icodec->ticks_per_frame;

                av_reduce(&codec->time_base.num, &codec->time_base.den,

                          codec->time_base.num, codec->time_base.den, INT_MAX);

            }else

                codec->time_base = ist->st->time_base;

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                if(audio_volume != 256) {

                    fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n");

                    ffmpeg_exit(1);

                }

                codec->channel_layout = icodec->channel_layout;

                codec->sample_rate = icodec->sample_rate;

                codec->channels = icodec->channels;

                codec->frame_size = icodec->frame_size;

                codec->audio_service_type = icodec->audio_service_type;

                codec->block_align= icodec->block_align;

                if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3)

                    codec->block_align= 0;

                if(codec->codec_id == CODEC_ID_AC3)

                    codec->block_align= 0;

                break;

            case AVMEDIA_TYPE_VIDEO:

                codec->pix_fmt = icodec->pix_fmt;

                codec->width = icodec->width;

                codec->height = icodec->height;

                codec->has_b_frames = icodec->has_b_frames;

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                codec->width = icodec->width;

                codec->height = icodec->height;

                break;

            default:

                abort();

            }

        } else {

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                ost->fifo= av_fifo_alloc(1024);

                if(!ost->fifo)

                    goto fail;

                ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);

                ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;

                icodec->request_channels = codec->channels;

                ist->decoding_needed = 1;

                ost->encoding_needed = 1;

                ost->resample_sample_fmt  = icodec->sample_fmt;

                ost->resample_sample_rate = icodec->sample_rate;

                ost->resample_channels    = icodec->channels;

                break;

            case AVMEDIA_TYPE_VIDEO:

                if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {

                    fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");

                    ffmpeg_exit(1);

                }

                ost->video_resample = (codec->width != icodec->width   ||

                                       codec->height != icodec->height ||

                        (codec->pix_fmt != icodec->pix_fmt));

                if (ost->video_resample) {

#if !CONFIG_AVFILTER

                    avcodec_get_frame_defaults(&ost->pict_tmp);

                    if(avpicture_alloc((AVPicture*)&ost->pict_tmp, codec->pix_fmt,

                                         codec->width, codec->height)) {

                        fprintf(stderr, "Cannot allocate temp picture, check pix fmt\n");

                        ffmpeg_exit(1);

                    }

                    sws_flags = av_get_int(sws_opts, "sws_flags", NULL);

                    ost->img_resample_ctx = sws_getContext(

                        icodec->width,

                        icodec->height,

                            icodec->pix_fmt,

                            codec->width,

                            codec->height,

                            codec->pix_fmt,

                            sws_flags, NULL, NULL, NULL);

                    if (ost->img_resample_ctx == NULL) {

                        fprintf(stderr, "Cannot get resampling context\n");

                        ffmpeg_exit(1);

                    }

                    ost->original_height = icodec->height;

                    ost->original_width  = icodec->width;

#endif

                    codec->bits_per_raw_sample= 0;

                }

                ost->resample_height = icodec->height;

                ost->resample_width  = icodec->width;

                ost->resample_pix_fmt= icodec->pix_fmt;

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

#if CONFIG_AVFILTER

                if (configure_filters(ist, ost)) {

                    fprintf(stderr, "Error opening filters!\n");

                    exit(1);

                }

#endif

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

                break;

            default:

                abort();

                break;

            }

            /* two pass mode */

            if (ost->encoding_needed &&

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

                char logfilename[1024];

                FILE *f;

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

                         pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,

                         i);

                if (codec->flags & CODEC_FLAG_PASS1) {

                    f = fopen(logfilename, "wb");

                    if (!f) {

                        fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));

                        ffmpeg_exit(1);

                    }

                    ost->logfile = f;

                } else {

                    char  *logbuffer;

                    size_t logbuffer_size;

                    if (read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {

                        fprintf(stderr, "Error reading log file '%s' for pass-2 encoding\n", logfilename);

                        ffmpeg_exit(1);

                    }

                    codec->stats_in = logbuffer;

                }

            }

        }

        if(codec->codec_type == AVMEDIA_TYPE_VIDEO){

            /* maximum video buffer size is 6-bytes per pixel, plus DPX header size */

            int size= codec->width * codec->height;

            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 1664);

        }

    }

    if (!bit_buffer)

        bit_buffer = av_malloc(bit_buffer_size);

    if (!bit_buffer) {

        fprintf(stderr, "Cannot allocate %d bytes output buffer\n",

                bit_buffer_size);

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    /* open each encoder */

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

        ost = ost_table[i];

        if (ost->encoding_needed) {

            AVCodec *codec = i < nb_output_codecs ? output_codecs[i] : NULL;

            AVCodecContext *dec = ist_table[ost->source_index]->st->codec;

            if (!codec)

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

            if (!codec) {

                snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d",

                         ost->st->codec->codec_id, ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            if (dec->subtitle_header) {

                ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);

                if (!ost->st->codec->subtitle_header) {

                    ret = AVERROR(ENOMEM);

                    goto dump_format;

                }

                memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);

                ost->st->codec->subtitle_header_size = dec->subtitle_header_size;

            }

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

                snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",

                        ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            extra_size += ost->st->codec->extradata_size;

        }

    }

    /* open each decoder */

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

        ist = ist_table[i];

        if (ist->decoding_needed) {

            AVCodec *codec = i < nb_input_codecs ? input_codecs[i] : NULL;

            if (!codec)

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

            if (!codec) {

                snprintf(error, sizeof(error), "Decoder (codec id %d) not found for input stream #%d.%d",

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

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

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

                snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d",

                        ist->file_index, ist->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            //if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)

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

        }

    }

    /* init pts */

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

        AVStream *st;

        ist = ist_table[i];

        st= ist->st;

        ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0;

        ist->next_pts = AV_NOPTS_VALUE;

        ist->is_start = 1;

    }

    /* set meta data information from input file if required */

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

        AVFormatContext *files[2];

        AVMetadata      **meta[2];

        int j;

#define METADATA_CHECK_INDEX(index, nb_elems, desc)\

        if ((index) < 0 || (index) >= (nb_elems)) {\

            snprintf(error, sizeof(error), "Invalid %s index %d while processing metadata maps\n",\

                     (desc), (index));\

            ret = AVERROR(EINVAL);\

            goto dump_format;\

        }

        int out_file_index = meta_data_maps[i][0].file;

        int in_file_index = meta_data_maps[i][1].file;

        if (in_file_index < 0 || out_file_index < 0)

            continue;

        METADATA_CHECK_INDEX(out_file_index, nb_output_files, "output file")

        METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file")

        files[0] = output_files[out_file_index];

        files[1] = input_files[in_file_index];

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

            AVMetaDataMap *map = &meta_data_maps[i][j];

            switch (map->type) {

            case 'g':

                meta[j] = &files[j]->metadata;

                break;

            case 's':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream")

                meta[j] = &files[j]->streams[map->index]->metadata;

                break;

            case 'c':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter")

                meta[j] = &files[j]->chapters[map->index]->metadata;

                break;

            case 'p':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program")

                meta[j] = &files[j]->programs[map->index]->metadata;

                break;

            }

        }

        av_metadata_copy(meta[0], *meta[1], AV_METADATA_DONT_OVERWRITE);

    }

    /* copy global metadata by default */

    if (metadata_global_autocopy) {

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

            av_metadata_copy(&output_files[i]->metadata, input_files[0]->metadata,

                             AV_METADATA_DONT_OVERWRITE);

    }

    /* copy chapters according to chapter maps */

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

        int infile  = chapter_maps[i].in_file;

        int outfile = chapter_maps[i].out_file;

        if (infile < 0 || outfile < 0)

            continue;

        if (infile >= nb_input_files) {

            snprintf(error, sizeof(error), "Invalid input file index %d in chapter mapping.\n", infile);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        if (outfile >= nb_output_files) {

            snprintf(error, sizeof(error), "Invalid output file index %d in chapter mapping.\n",outfile);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        copy_chapters(infile, outfile);

    }

    /* copy chapters from the first input file that has them*/

    if (!nb_chapter_maps)

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

            if (!input_files[i]->nb_chapters)

                continue;

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

                if ((ret = copy_chapters(i, j)) < 0)

                    goto dump_format;

            break;

        }

    /* open files and write file headers */

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

        os = output_files[i];

        if (av_write_header(os) < 0) {

            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        if (strcmp(output_files[i]->oformat->name, "rtp")) {

            want_sdp = 0;

        }

    }

 dump_format:

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

       of stream copy */

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

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

    }

    /* dump the stream mapping */

    if (verbose >= 0) {

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

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

            ost = ost_table[i];

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

                    ist_table[ost->source_index]->file_index,

                    ist_table[ost->source_index]->index,

                    ost->file_index,

                    ost->index);

            if (ost->sync_ist != ist_table[ost->source_index])

                fprintf(stderr, " [sync #%d.%d]",

                        ost->sync_ist->file_index,

                        ost->sync_ist->index);

            fprintf(stderr, "\n");

        }

    }

    if (ret) {

        fprintf(stderr, "%s\n", error);

        goto fail;

    }

    if (want_sdp) {

        print_sdp(output_files, nb_output_files);

    }

    if (!using_stdin) {

        if(verbose >= 0)

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

        url_set_interrupt_cb(decode_interrupt_cb);

    }

    term_init();

    timer_start = av_gettime();

    for(; received_sigterm == 0;) {

        int file_index, ist_index;

        AVPacket pkt;

        double ipts_min;

        double opts_min;

    redo:

        ipts_min= 1e100;

        opts_min= 1e100;

        /* if 'q' pressed, exits */

        if (!using_stdin) {

            if (q_pressed)

                break;

            /* 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;

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

            double ipts, opts;

            ost = ost_table[i];

            os = output_files[ost->file_index];

            ist = ist_table[ost->source_index];

            if(ist->is_past_recording_time || no_packet[ist->file_index])

                continue;

                opts = ost->st->pts.val * av_q2d(ost->st->time_base);

            ipts = (double)ist->pts;

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

                if(ipts < ipts_min) {

                    ipts_min = ipts;

                    if(input_sync ) file_index = ist->file_index;

                }

                if(opts < opts_min) {

                    opts_min = opts;

                    if(!input_sync) file_index = ist->file_index;

                }

            }

            if(ost->frame_number >= max_frames[ost->st->codec->codec_type]){

                file_index= -1;

                break;

            }

        }

        /* if none, if is finished */

        if (file_index < 0) {

            if(no_packet_count){

                no_packet_count=0;

                memset(no_packet, 0, sizeof(no_packet));

                usleep(10000);

                continue;

            }

            break;

        }

        /* finish if limit size exhausted */

        if (limit_filesize != 0 && limit_filesize <= avio_tell(output_files[0]->pb))

            break;

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

        is = input_files[file_index];

        ret= av_read_frame(is, &pkt);

        if(ret == AVERROR(EAGAIN)){

            no_packet[file_index]=1;

            no_packet_count++;

            continue;

        }

        if (ret < 0) {

            file_table[file_index].eof_reached = 1;

            if (opt_shortest)

                break;

            else

                continue;

        }

        no_packet_count=0;

        memset(no_packet, 0, sizeof(no_packet));

        if (do_pkt_dump) {

            av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,

                             is->streams[pkt.stream_index]);

        }

        /* 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;

        if (pkt.dts != AV_NOPTS_VALUE)

            pkt.dts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);

        if (pkt.pts != AV_NOPTS_VALUE)

            pkt.pts += av_rescale_q(input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ist->st->time_base);

        if (pkt.stream_index < nb_input_files_ts_scale[file_index]

            && input_files_ts_scale[file_index][pkt.stream_index]){

            if(pkt.pts != AV_NOPTS_VALUE)

                pkt.pts *= input_files_ts_scale[file_index][pkt.stream_index];

            if(pkt.dts != AV_NOPTS_VALUE)

                pkt.dts *= input_files_ts_scale[file_index][pkt.stream_index];

        }

//        fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files_ts_offset[ist->file_index], ist->st->codec->codec_type);

        if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE

            && (is->iformat->flags & AVFMT_TS_DISCONT)) {

            int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);

            int64_t delta= pkt_dts - ist->next_pts;

            if((FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE || pkt_dts+1<ist->pts)&& !copy_ts){

                input_files_ts_offset[ist->file_index]-= delta;

                if (verbose > 2)

                    fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files_ts_offset[ist->file_index]);

                pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

                if(pkt.pts != AV_NOPTS_VALUE)

                    pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

            }

        }

        /* finish if recording time exhausted */

        if (recording_time != INT64_MAX &&

            av_compare_ts(pkt.pts, ist->st->time_base, recording_time + start_time, (AVRational){1, 1000000}) >= 0) {

            ist->is_past_recording_time = 1;

            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) {

            if (verbose >= 0)

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

                        ist->file_index, ist->index);

            if (exit_on_error)

                ffmpeg_exit(1);

            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();

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

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

        os = output_files[i];

        av_write_trailer(os);

    }

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

    print_report(output_files, ost_table, nb_ostreams, 1);

    /* 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);

        }

#if CONFIG_AVFILTER

        avfilter_graph_free(&ost->graph);

#endif

    }

    /* 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;

 fail:

    av_freep(&bit_buffer);

    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->st->stream_copy)

                    av_freep(&ost->st->codec->extradata);

                if (ost->logfile) {

                    fclose(ost->logfile);

                    ost->logfile = NULL;

                }

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

                                             initialized but set to zero */

                av_freep(&ost->st->codec->subtitle_header);

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

                av_free(ost->forced_kf_pts);

                if (ost->video_resample)

                    sws_freeContext(ost->img_resample_ctx);

                if (ost->resample)

                    audio_resample_close(ost->resample);

                if (ost->reformat_ctx)

                    av_audio_convert_free(ost->reformat_ctx);

                av_free(ost);

            }

        }

        av_free(ost_table);

    }

    return ret;

}


static int xan_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    XanContext *s = avctx->priv_data;

    int ftype;

    int ret;

    s->pic.reference = 1;

    s->pic.buffer_hints = FF_BUFFER_HINTS_VALID |

                          FF_BUFFER_HINTS_PRESERVE |

                          FF_BUFFER_HINTS_REUSABLE;

    if ((ret = avctx->reget_buffer(avctx, &s->pic))) {

        av_log(s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");

        return ret;

    }

    ftype = AV_RL32(avpkt->data);

    switch (ftype) {

    case 0:

        ret = xan_decode_frame_type0(avctx, avpkt);

        break;

    case 1:

        ret = xan_decode_frame_type1(avctx, avpkt);

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype);

        return -1;

    }

    if (ret)

        return ret;

    *data_size = sizeof(AVFrame);

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

    return avpkt->size;

}


static void decode_rowskip(uint8_t* plane, int width, int height, int stride, VC9Context *v){

    int x, y;

    GetBitContext *gb = &v->s.gb;

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

        if (!get_bits(gb, 1)) //rowskip

            memset(plane, 0, width);

        else

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

                plane[x] = get_bits(gb, 1);

        plane += stride;

    }

}


vu_queue_notify(VuDev *dev, VuVirtq *vq)

{

    if (unlikely(dev->broken)) {

        return;

    }

    if (!vring_notify(dev, vq)) {

        DPRINT("skipped notify...\n");

        return;

    }

    if (eventfd_write(vq->call_fd, 1) < 0) {

        vu_panic(dev, "Error writing eventfd: %s", strerror(errno));

    }

}


int ff_rv34_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    RV34DecContext *r = avctx->priv_data;

    MpegEncContext *s = &r->s;

    AVFrame *pict = data;

    SliceInfo si;

    int i;

    int slice_count;

    const uint8_t *slices_hdr = NULL;

    int last = 0;

    /* no supplementary picture */

    if (buf_size == 0) {

        /* special case for last picture */

        if (s->low_delay==0 && s->next_picture_ptr) {

            *pict = *(AVFrame*)s->next_picture_ptr;

            s->next_picture_ptr = NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    if(!avctx->slice_count){

        slice_count = (*buf++) + 1;

        slices_hdr = buf + 4;

        buf += 8 * slice_count;

    }else

        slice_count = avctx->slice_count;

    //parse first slice header to check whether this frame can be decoded

    if(get_slice_offset(avctx, slices_hdr, 0) > buf_size){

        av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");

        return -1;

    }

    init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8);

    if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){

        av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");

        return -1;

    }

    if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && si.type == AV_PICTURE_TYPE_B)

        return -1;

    if(   (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)

       || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)

       ||  avctx->skip_frame >= AVDISCARD_ALL)

        return buf_size;

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

        int offset = get_slice_offset(avctx, slices_hdr, i);

        int size;

        if(i+1 == slice_count)

            size = buf_size - offset;

        else

            size = get_slice_offset(avctx, slices_hdr, i+1) - offset;

        if(offset > buf_size){

            av_log(avctx, AV_LOG_ERROR, "Slice offset is greater than frame size\n");

            break;

        }

        r->si.end = s->mb_width * s->mb_height;

        if(i+1 < slice_count){

            init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);

            if(r->parse_slice_header(r, &r->s.gb, &si) < 0){

                if(i+2 < slice_count)

                    size = get_slice_offset(avctx, slices_hdr, i+2) - offset;

                else

                    size = buf_size - offset;

            }else

                r->si.end = si.start;

        }

        last = rv34_decode_slice(r, r->si.end, buf + offset, size);

        s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;

        if(last)

            break;

    }

    if(last && s->current_picture_ptr){

        if(r->loop_filter)

            r->loop_filter(r, s->mb_height - 1);

        ff_er_frame_end(s);

        MPV_frame_end(s);

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

            *pict = *(AVFrame*)s->current_picture_ptr;

        } else if (s->last_picture_ptr != NULL) {

            *pict = *(AVFrame*)s->last_picture_ptr;

        }

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

            *data_size = sizeof(AVFrame);

            ff_print_debug_info(s, pict);

        }

        s->current_picture_ptr = NULL; //so we can detect if frame_end wasnt called (find some nicer solution...)

    }

    return buf_size;

}


static int qemu_chr_open_win_stdio(QemuOpts *opts, CharDriverState **_chr)

{

    CharDriverState   *chr;

    WinStdioCharState *stdio;

    DWORD              dwMode;

    int                is_console = 0;

    if (stdio_nb_clients >= STDIO_MAX_CLIENTS

        || ((display_type != DT_NOGRAPHIC) && (stdio_nb_clients != 0))) {

        return -EIO;

    }

    chr   = g_malloc0(sizeof(CharDriverState));

    stdio = g_malloc0(sizeof(WinStdioCharState));

    stdio->hStdIn = GetStdHandle(STD_INPUT_HANDLE);

    if (stdio->hStdIn == INVALID_HANDLE_VALUE) {

        fprintf(stderr, "cannot open stdio: invalid handle\n");

        exit(1);

    }

    is_console = GetConsoleMode(stdio->hStdIn, &dwMode) != 0;

    chr->opaque    = stdio;

    chr->chr_write = win_stdio_write;

    chr->chr_close = win_stdio_close;

    if (stdio_nb_clients == 0) {

        if (is_console) {

            if (qemu_add_wait_object(stdio->hStdIn,

                                     win_stdio_wait_func, chr)) {

                fprintf(stderr, "qemu_add_wait_object: failed\n");

            }

        } else {

            DWORD   dwId;

            stdio->hInputReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

            stdio->hInputDoneEvent  = CreateEvent(NULL, FALSE, FALSE, NULL);

            stdio->hInputThread     = CreateThread(NULL, 0, win_stdio_thread,

                                            chr, 0, &dwId);

            if (stdio->hInputThread == INVALID_HANDLE_VALUE

                || stdio->hInputReadyEvent == INVALID_HANDLE_VALUE

                || stdio->hInputDoneEvent == INVALID_HANDLE_VALUE) {

                fprintf(stderr, "cannot create stdio thread or event\n");

                exit(1);

            }

            if (qemu_add_wait_object(stdio->hInputReadyEvent,

                                     win_stdio_thread_wait_func, chr)) {

                fprintf(stderr, "qemu_add_wait_object: failed\n");

            }

        }

    }

    dwMode |= ENABLE_LINE_INPUT;

    stdio_clients[stdio_nb_clients++] = chr;

    if (stdio_nb_clients == 1 && is_console) {

        /* set the terminal in raw mode */

        /* ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS */

        dwMode |= ENABLE_PROCESSED_INPUT;

    }

    SetConsoleMode(stdio->hStdIn, dwMode);

    chr->chr_set_echo = qemu_chr_set_echo_win_stdio;

    qemu_chr_fe_set_echo(chr, false);

    *_chr = chr;

    return 0;

}


int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[],

                          int srcStride[], int srcSliceY, int srcSliceH,

                          uint8_t *dst[], int dstStride[])

{

    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);

    int nb_components = desc->nb_components;

    int plane, x, y;

    int plane_count = isGray(c->srcFormat) ? 1 : 3;

    int sixteen_bits = desc->comp[0].depth_minus1 >= 8;

    unsigned off    = 1<<desc->comp[0].depth_minus1;

    unsigned shift  = desc->comp[0].depth_minus1 + 1;

    unsigned max    = (1<<shift) - 1;

    av_assert0(plane_count == nb_components - 1);

    if (desc->flags & AV_PIX_FMT_FLAG_PLANAR) {

        for (plane = 0; plane < plane_count; plane++) {

            int w = plane ? c->chrSrcW : c->srcW;

            int y_subsample = plane ? desc->log2_chroma_h: 0;

            for (y = srcSliceY >> y_subsample; y < FF_CEIL_RSHIFT(srcSliceH, y_subsample); y++) {

                if (sixteen_bits) {

                    const uint16_t *s = src[plane      ] + srcStride[plane] * y;

                    const uint16_t *a = src[plane_count] + srcStride[plane_count] * y;

                          uint16_t *d = dst[plane      ] + dstStride[plane] * y;

                    unsigned target = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 1<<desc->comp[0].depth_minus1 : 0;

                    if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {

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

                            unsigned u = s[x]*a[x] + target*(max-a[x]) + off;

                            d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);

                        }

                    } else {

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

                            unsigned aswap =av_bswap16(a[x]);

                            unsigned u = av_bswap16(s[x])*aswap + target*(max-aswap) + off;

                            d[x] = av_clip((u + (u >> shift)) >> shift, 0, max);

                        }

                    }

                } else {

                    const uint8_t *s = src[plane      ] + srcStride[plane] * y;

                    const uint8_t *a = src[plane_count] + srcStride[plane_count] * y;

                          uint8_t *d = dst[plane      ] + dstStride[plane] * y;

                    unsigned target = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 128 : 0;

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

                        unsigned u = s[x]*a[x] + target*(255-a[x]) + 128;

                        d[x] = (257*u) >> 16;

                    }

                }

            }

        }

    } else {

        int alpha_pos = desc->comp[plane_count].offset_plus1 - 1;

        int w = c->srcW;

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

            if (sixteen_bits) {

                const uint16_t *s = src[0] + srcStride[0] * y + 2*!alpha_pos;

                const uint16_t *a = src[0] + srcStride[0] * y + alpha_pos;

                        uint16_t *d = dst[0] + dstStride[0] * y;

                if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) {

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

                        for (plane = 0; plane < plane_count; plane++) {

                            unsigned target = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 1<<desc->comp[0].depth_minus1 : 0;

                            int x_index = (plane_count + 1) * x;

                            unsigned u = s[x_index + plane]*a[x_index] + target*(max-a[x_index]) + off;

                            d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);

                        }

                    }

                } else {

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

                        for (plane = 0; plane < plane_count; plane++) {

                            unsigned target = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 1<<desc->comp[0].depth_minus1 : 0;

                            int x_index = (plane_count + 1) * x;

                            unsigned aswap =av_bswap16(a[x_index]);

                            unsigned u = av_bswap16(s[x_index + plane])*aswap + target*(max-aswap) + off;

                            d[plane_count*x + plane] = av_clip((u + (u >> shift)) >> shift, 0, max);

                        }

                    }

                }

            } else {

                const uint8_t *s = src[0] + srcStride[0] * y + !alpha_pos;

                const uint8_t *a = src[0] + srcStride[0] * y + alpha_pos;

                      uint8_t *d = dst[0] + dstStride[0] * y;

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

                    for (plane = 0; plane < plane_count; plane++) {

                        unsigned target = plane && !(desc->flags & AV_PIX_FMT_FLAG_RGB) ? 128 : 0;

                        int x_index = (plane_count + 1) * x;

                        unsigned u = s[x_index + plane]*a[x_index] + target*(255-a[x_index]) + 128;

                        d[plane_count*x + plane] = (257*u) >> 16;

                    }

                }

            }

        }

    }

    return 0;

}


int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)

{

    AVStream *st;

    int tag;

    if (fc->nb_streams < 1)

        return 0;

    st = fc->streams[fc->nb_streams-1];

    avio_rb32(pb); /* version + flags */

    ff_mp4_read_descr(fc, pb, &tag);

    if (tag == MP4ESDescrTag) {

        ff_mp4_parse_es_descr(pb, NULL);

    } else

        avio_rb16(pb); /* ID */

    ff_mp4_read_descr(fc, pb, &tag);

    if (tag == MP4DecConfigDescrTag)

        ff_mp4_read_dec_config_descr(fc, st, pb);

    return 0;

}


void ff_atrac_iqmf(float *inlo, float *inhi, unsigned int nIn, float *pOut, float *delayBuf, float *temp)

{

    int   i, j;

    float   *p1, *p3;

    memcpy(temp, delayBuf, 46*sizeof(float));

    p3 = temp + 46;

    /* loop1 */

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

        p3[2*i+0] = inlo[i  ] + inhi[i  ];

        p3[2*i+1] = inlo[i  ] - inhi[i  ];

        p3[2*i+2] = inlo[i+1] + inhi[i+1];

        p3[2*i+3] = inlo[i+1] - inhi[i+1];

    }

    /* loop2 */

    p1 = temp;

    for (j = nIn; j != 0; j--) {

        float s1 = 0.0;

        float s2 = 0.0;

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

            s1 += p1[i] * qmf_window[i];

            s2 += p1[i+1] * qmf_window[i+1];

        }

        pOut[0] = s2;

        pOut[1] = s1;

        p1 += 2;

        pOut += 2;

    }

    /* Update the delay buffer. */

    memcpy(delayBuf, temp + nIn*2, 46*sizeof(float));

}


static void uc32_cpu_initfn(Object *obj)

{

    CPUState *cs = CPU(obj);

    UniCore32CPU *cpu = UNICORE32_CPU(obj);

    CPUUniCore32State *env = &cpu->env;

    static bool inited;

    cs->env_ptr = env;

    cpu_exec_init(cs, &error_abort);

#ifdef CONFIG_USER_ONLY

    env->uncached_asr = ASR_MODE_USER;

    env->regs[31] = 0;

#else

    env->uncached_asr = ASR_MODE_PRIV;

    env->regs[31] = 0x03000000;

#endif

    tlb_flush(cs, 1);

    if (tcg_enabled() && !inited) {

        inited = true;

        uc32_translate_init();

    }

}


static int read_rle_sgi(unsigned char* out_buf, const uint8_t *in_buf,

                        const uint8_t *in_end, SgiState* s)

{

    uint8_t *dest_row;

    unsigned int len = s->height * s->depth * 4;

    const uint8_t *start_table = in_buf;

    unsigned int y, z;

    unsigned int start_offset;

    /* size of  RLE offset and length tables */

    if(len * 2  > in_end - in_buf) {

        return AVERROR_INVALIDDATA;

    }

    in_buf -= SGI_HEADER_SIZE;

    for (z = 0; z < s->depth; z++) {

        dest_row = out_buf;

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

            dest_row -= s->linesize;

            start_offset = bytestream_get_be32(&start_table);

            if(start_offset > in_end - in_buf) {

                return AVERROR_INVALIDDATA;

            }

            if (expand_rle_row(in_buf + start_offset, in_end, dest_row + z,

                dest_row + FFABS(s->linesize), s->depth) != s->width)

                return AVERROR_INVALIDDATA;

        }

    }

    return 0;

}


static inline void RENAME(rgb15to16)(const uint8_t *src,uint8_t *dst,long src_size)

{

  register const uint8_t* s=src;

  register uint8_t* d=dst;

  register const uint8_t *end;

  const uint8_t *mm_end;

  end = s + src_size;

#ifdef HAVE_MMX

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

  __asm __volatile("movq	%0, %%mm4"::"m"(mask15s));

  mm_end = end - 15;

  while(s<mm_end)

  {

	__asm __volatile(

		PREFETCH"	32%1\n\t"

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

		"movq	8%1, %%mm2\n\t"

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

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

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

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

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

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

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

		MOVNTQ"	%%mm2, 8%0"

		:"=m"(*d)

		:"m"(*s)

		);

	d+=16;

	s+=16;

  }

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

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

#endif

    mm_end = end - 3;

    while(s < mm_end)

    {

	register unsigned x= *((uint32_t *)s);

	*((uint32_t *)d) = (x&0x7FFF7FFF) + (x&0x7FE07FE0);

	d+=4;

	s+=4;

    }

    if(s < end)

    {

	register unsigned short x= *((uint16_t *)s);

	*((uint16_t *)d) = (x&0x7FFF) + (x&0x7FE0);

    }

}


int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options)

{

    AVFormatContext *s = *ps;

    int ret = 0;

    AVFormatParameters ap = { 0 };

    AVDictionary *tmp = NULL;

    if (!s && !(s = avformat_alloc_context()))

        return AVERROR(ENOMEM);

    if (fmt)

        s->iformat = fmt;

    if (options)

        av_dict_copy(&tmp, *options, 0);

    if ((ret = av_opt_set_dict(s, &tmp)) < 0)

        goto fail;

    if ((ret = init_input(s, filename)) < 0)

        goto fail;

    /* check filename in case an image number is expected */

    if (s->iformat->flags & AVFMT_NEEDNUMBER) {

        if (!av_filename_number_test(filename)) {

            ret = AVERROR(EINVAL);

            goto fail;

        }

    }

    s->duration = s->start_time = AV_NOPTS_VALUE;

    av_strlcpy(s->filename, filename, sizeof(s->filename));

    /* allocate private data */

    if (s->iformat->priv_data_size > 0) {

        if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) {

            ret = AVERROR(ENOMEM);

            goto fail;

        }

        if (s->iformat->priv_class) {

            *(const AVClass**)s->priv_data = s->iformat->priv_class;

            av_opt_set_defaults(s->priv_data);

            if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)

                goto fail;

        }

    }

    /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */

    if (s->pb)

        ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);

    if (s->iformat->read_header)

        if ((ret = s->iformat->read_header(s, &ap)) < 0)

            goto fail;

    if (s->pb && !s->data_offset)

        s->data_offset = avio_tell(s->pb);

    s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;

    if (options) {

        av_dict_free(options);

        *options = tmp;

    }

    *ps = s;

    return 0;

fail:

    av_dict_free(&tmp);

    if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))

        avio_close(s->pb);

    avformat_free_context(s);

    *ps = NULL;

    return ret;

}


void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,

                 ThreadFrame *ref, const VP56mv *mv,

                 int x_off, int y_off, int block_w, int block_h,

                 int width, int height, int linesize,

                 vp8_mc_func mc_func[3][3])

{

    uint8_t *src = ref->f->data[0];

    if (AV_RN32A(mv)) {

        int mx = (mv->x << 1)&7, mx_idx = subpel_idx[0][mx];

        int my = (mv->y << 1)&7, my_idx = subpel_idx[0][my];

        x_off += mv->x >> 2;

        y_off += mv->y >> 2;

        // edge emulation

        ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 4, 0);

        src += y_off * linesize + x_off;

        if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||

            y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {

            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,

                                     block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],

                                     x_off - mx_idx, y_off - my_idx, width, height);

            src = td->edge_emu_buffer + mx_idx + linesize * my_idx;

        }

        mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);

    } else {

        ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0);

        mc_func[0][0](dst, linesize, src + y_off * linesize + x_off, linesize, block_h, 0, 0);

    }

}


static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset,

                                 uint32_t value)

{

    SyborgVirtIOProxy *s = opaque;

    VirtIODevice *vdev = s->vdev;

    DPRINTF("writel 0x%x = 0x%x\n", (int)offset, value);

    if (offset >= SYBORG_VIRTIO_CONFIG) {

        return virtio_config_writel(vdev, offset - SYBORG_VIRTIO_CONFIG,

                                    value);

    }

    switch (offset >> 2) {

    case SYBORG_VIRTIO_GUEST_FEATURES:

        if (vdev->set_features)

            vdev->set_features(vdev, value);

        vdev->guest_features = value;

        break;

    case SYBORG_VIRTIO_QUEUE_BASE:

        if (value == 0)

            virtio_reset(vdev);

        else

            virtio_queue_set_addr(vdev, vdev->queue_sel, value);

        break;

    case SYBORG_VIRTIO_QUEUE_SEL:

        if (value < VIRTIO_PCI_QUEUE_MAX)

            vdev->queue_sel = value;

        break;

    case SYBORG_VIRTIO_QUEUE_NOTIFY:

        virtio_queue_notify(vdev, value);

        break;

    case SYBORG_VIRTIO_STATUS:

        virtio_set_status(vdev, value & 0xFF);

        if (vdev->status == 0)

            virtio_reset(vdev);

        break;

    case SYBORG_VIRTIO_INT_ENABLE:

        s->int_enable = value;

        virtio_update_irq(vdev);

        break;

    case SYBORG_VIRTIO_INT_STATUS:

        vdev->isr &= ~value;

        virtio_update_irq(vdev);

        break;

    default:

        BADF("Bad write offset 0x%x\n", (int)offset);

        break;

    }

}


bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,

                                                            uint64_t timeout)

{

    do {

        clock_step(100);

        if (bus->get_config_isr_status(d)) {

            break; /* It has ended */

        }

    } while (--timeout);

    return timeout != 0;

}


void serial_exit_core(SerialState *s)
{
    qemu_chr_fe_deinit(&s->chr);
    qemu_unregister_reset(serial_reset, s);
}


int ff_nvdec_frame_params(AVCodecContext *avctx,

                          AVBufferRef *hw_frames_ctx,

                          int dpb_size)

{

    AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;

    const AVPixFmtDescriptor *sw_desc;

    int cuvid_codec_type, cuvid_chroma_format;

    sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);

    if (!sw_desc)

        return AVERROR_BUG;

    cuvid_codec_type = map_avcodec_id(avctx->codec_id);

    if (cuvid_codec_type < 0) {

        av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n");

        return AVERROR_BUG;

    }

    cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt);

    if (cuvid_chroma_format < 0) {

        av_log(avctx, AV_LOG_VERBOSE, "Unsupported chroma format\n");

        return AVERROR(EINVAL);

    }

    if (avctx->thread_type & FF_THREAD_FRAME)

        dpb_size += avctx->thread_count;

    frames_ctx->format            = AV_PIX_FMT_CUDA;

    frames_ctx->width             = avctx->coded_width;

    frames_ctx->height            = avctx->coded_height;

    frames_ctx->sw_format         = sw_desc->comp[0].depth > 8 ?

                                    AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;

    frames_ctx->initial_pool_size = dpb_size;

    return 0;

}


static const char *ass_split_section(ASSSplitContext *ctx, const char *buf)

{

    const ASSSection *section = &ass_sections[ctx->current_section];

    int *number = &ctx->field_number[ctx->current_section];

    int *order = ctx->field_order[ctx->current_section];

    int *tmp, i, len;

    while (buf && *buf) {

        if (buf[0] == '[') {

            ctx->current_section = -1;

            break;

        }

        if (buf[0] == ';' || (buf[0] == '!' && buf[1] == ':')) {

            /* skip comments */

        } else if (section->format_header && !order) {

            len = strlen(section->format_header);

            if (strncmp(buf, section->format_header, len) || buf[len] != ':')

                return NULL;

            buf += len + 1;

            while (!is_eol(*buf)) {

                buf = skip_space(buf);

                len = strcspn(buf, ", \r\n");

                if (!(tmp = av_realloc(order, (*number + 1) * sizeof(*order))))

                    return NULL;

                order = tmp;

                order[*number] = -1;

                for (i=0; section->fields[i].name; i++)

                    if (!strncmp(buf, section->fields[i].name, len)) {

                        order[*number] = i;

                        break;

                    }

                (*number)++;

                buf = skip_space(buf + len + (buf[len] == ','));

            }

            ctx->field_order[ctx->current_section] = order;

        } else if (section->fields_header) {

            len = strlen(section->fields_header);

            if (!strncmp(buf, section->fields_header, len) && buf[len] == ':') {

                uint8_t *ptr, *struct_ptr = realloc_section_array(ctx);

                if (!struct_ptr)  return NULL;

                buf += len + 1;

                for (i=0; !is_eol(*buf) && i < *number; i++) {

                    int last = i == *number - 1;

                    buf = skip_space(buf);

                    len = strcspn(buf, last ? "\r\n" : ",\r\n");

                    if (order[i] >= 0) {

                        ASSFieldType type = section->fields[order[i]].type;

                        ptr = struct_ptr + section->fields[order[i]].offset;

                        convert_func[type](ptr, buf, len);

                    }

                    buf = skip_space(buf + len + !last);

                }

            }

        } else {

            len = strcspn(buf, ":\r\n");

            if (buf[len] == ':') {

                for (i=0; section->fields[i].name; i++)

                    if (!strncmp(buf, section->fields[i].name, len)) {

                        ASSFieldType type = section->fields[i].type;

                        uint8_t *ptr = (uint8_t *)&ctx->ass + section->offset;

                        ptr += section->fields[i].offset;

                        buf = skip_space(buf + len + 1);

                        convert_func[type](ptr, buf, strcspn(buf, "\r\n"));

                        break;

                    }

            }

        }

        buf += strcspn(buf, "\n");

        buf += !!*buf;

    }

    return buf;

}


void ff_put_h264_qpel16_mc10_msa(uint8_t *dst, const uint8_t *src,

                                 ptrdiff_t stride)

{

    avc_luma_hz_qrt_16w_msa(src - 2, stride, dst, stride, 16, 0);

}


static void do_memory_save(Monitor *mon, const QDict *qdict, QObject **ret_data)

{

    FILE *f;

    uint32_t size = qdict_get_int(qdict, "size");

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

    target_long addr = qdict_get_int(qdict, "val");

    uint32_t l;

    CPUState *env;

    uint8_t buf[1024];

    env = mon_get_cpu();

    if (!env)

        return;

    f = fopen(filename, "wb");

    if (!f) {

        monitor_printf(mon, "could not open '%s'\n", filename);

        return;

    }

    while (size != 0) {

        l = sizeof(buf);

        if (l > size)

            l = size;

        cpu_memory_rw_debug(env, addr, buf, l, 0);

        fwrite(buf, 1, l, f);

        addr += l;

        size -= l;

    }

    fclose(f);

}


static uint32_t virtio_read_config(PCIDevice *pci_dev,

                                   uint32_t address, int len)

{

    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);

    struct virtio_pci_cfg_cap *cfg;

    if (proxy->config_cap &&

        ranges_overlap(address, len, proxy->config_cap + offsetof(struct virtio_pci_cfg_cap,

                                                                  pci_cfg_data),

                       sizeof cfg->pci_cfg_data)) {

        uint32_t off;

        uint32_t len;

        cfg = (void *)(proxy->pci_dev.config + proxy->config_cap);

        off = le32_to_cpu(cfg->cap.offset);

        len = le32_to_cpu(cfg->cap.length);

        if (len <= sizeof cfg->pci_cfg_data) {

            virtio_address_space_read(&proxy->modern_as, off,

                                      cfg->pci_cfg_data, len);

        }

    }

    return pci_default_read_config(pci_dev, address, len);

}


static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,

                                            hwaddr base,

                                            qemu_irq txirq, qemu_irq rxirq,

                                            qemu_irq *dma, omap_clk clk)

{

    struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)

            g_malloc0(sizeof(struct omap_mcbsp_s));

    s->txirq = txirq;

    s->rxirq = rxirq;

    s->txdrq = dma[0];

    s->rxdrq = dma[1];

    s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);

    s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);

    omap_mcbsp_reset(s);

    memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);

    memory_region_add_subregion(system_memory, base, &s->iomem);

    return s;

}


FWCfgState *pc_memory_init(MachineState *machine,
                           MemoryRegion *system_memory,
                           ram_addr_t below_4g_mem_size,
                           ram_addr_t above_4g_mem_size,
                           MemoryRegion *rom_memory,
                           MemoryRegion **ram_memory,
                           PcGuestInfo *guest_info)
{
    int linux_boot, i;
    MemoryRegion *ram, *option_rom_mr;
    MemoryRegion *ram_below_4g, *ram_above_4g;
    FWCfgState *fw_cfg;
    PCMachineState *pcms = PC_MACHINE(machine);
    assert(machine->ram_size == below_4g_mem_size + above_4g_mem_size);
    linux_boot = (machine->kernel_filename != NULL);
    /* Allocate RAM.  We allocate it as a single memory region and use
     * aliases to address portions of it, mostly for backwards compatibility
     * with older qemus that used qemu_ram_alloc().
     */
    ram = g_malloc(sizeof(*ram));
    memory_region_allocate_system_memory(ram, NULL, "pc.ram",
                                         machine->ram_size);
    *ram_memory = ram;
    ram_below_4g = g_malloc(sizeof(*ram_below_4g));
    memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", ram,
                             0, below_4g_mem_size);
    memory_region_add_subregion(system_memory, 0, ram_below_4g);
    e820_add_entry(0, below_4g_mem_size, E820_RAM);
    if (above_4g_mem_size > 0) {
        ram_above_4g = g_malloc(sizeof(*ram_above_4g));
        memory_region_init_alias(ram_above_4g, NULL, "ram-above-4g", ram,
                                 below_4g_mem_size, above_4g_mem_size);
        memory_region_add_subregion(system_memory, 0x100000000ULL,
                                    ram_above_4g);
        e820_add_entry(0x100000000ULL, above_4g_mem_size, E820_RAM);
    if (!guest_info->has_reserved_memory &&
        (machine->ram_slots ||
         (machine->maxram_size > machine->ram_size))) {
        MachineClass *mc = MACHINE_GET_CLASS(machine);
        error_report("\"-memory 'slots|maxmem'\" is not supported by: %s",
                     mc->name);
    /* initialize hotplug memory address space */
    if (guest_info->has_reserved_memory &&
        (machine->ram_size < machine->maxram_size)) {
        ram_addr_t hotplug_mem_size =
            machine->maxram_size - machine->ram_size;
        if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
            error_report("unsupported amount of memory slots: %"PRIu64,
                         machine->ram_slots);
        pcms->hotplug_memory_base =
            ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
        if (pcms->enforce_aligned_dimm) {
            /* size hotplug region assuming 1G page max alignment per slot */
            hotplug_mem_size += (1ULL << 30) * machine->ram_slots;
        if ((pcms->hotplug_memory_base + hotplug_mem_size) <
            hotplug_mem_size) {
            error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT,
                         machine->maxram_size);
        memory_region_init(&pcms->hotplug_memory, OBJECT(pcms),
                           "hotplug-memory", hotplug_mem_size);
        memory_region_add_subregion(system_memory, pcms->hotplug_memory_base,
                                    &pcms->hotplug_memory);
    /* Initialize PC system firmware */
    pc_system_firmware_init(rom_memory, guest_info->isapc_ram_fw);
    option_rom_mr = g_malloc(sizeof(*option_rom_mr));
    memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE,
                           &error_abort);
    vmstate_register_ram_global(option_rom_mr);
    memory_region_add_subregion_overlap(rom_memory,
                                        PC_ROM_MIN_VGA,
                                        option_rom_mr,
                                        1);
    fw_cfg = bochs_bios_init();
    rom_set_fw(fw_cfg);
    if (guest_info->has_reserved_memory && pcms->hotplug_memory_base) {
        uint64_t *val = g_malloc(sizeof(*val));
        *val = cpu_to_le64(ROUND_UP(pcms->hotplug_memory_base, 0x1ULL << 30));
        fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
    if (linux_boot) {
        load_linux(fw_cfg, machine->kernel_filename, machine->initrd_filename,
                   machine->kernel_cmdline, below_4g_mem_size);
    for (i = 0; i < nb_option_roms; i++) {
        rom_add_option(option_rom[i].name, option_rom[i].bootindex);
    guest_info->fw_cfg = fw_cfg;
    return fw_cfg;


static MegasasCmd *megasas_next_frame(MegasasState *s,

    hwaddr frame)

{

    MegasasCmd *cmd = NULL;

    int num = 0, index;

    cmd = megasas_lookup_frame(s, frame);

    if (cmd) {

        trace_megasas_qf_found(cmd->index, cmd->pa);

        return cmd;

    }

    index = s->reply_queue_head;

    num = 0;

    while (num < s->fw_cmds) {

        if (!s->frames[index].pa) {

            cmd = &s->frames[index];

            break;

        }

        index = megasas_next_index(s, index, s->fw_cmds);

        num++;

    }

    if (!cmd) {

        trace_megasas_qf_failed(frame);

    }

    trace_megasas_qf_new(index, cmd);

    return cmd;

}


static int mpegts_audio_write(void *opaque, uint8_t *buf, int size)

{

    MpegTSWriteStream *ts_st = (MpegTSWriteStream *)opaque;

    if (ts_st->adata_pos + size > ts_st->adata_size)

        return AVERROR(EIO);

    memcpy(ts_st->adata + ts_st->adata_pos, buf, size);

    ts_st->adata_pos += size;

    return 0;

}


AVFormatContext *avformat_alloc_context(void)

{

    AVFormatContext *ic;

    ic = av_malloc(sizeof(AVFormatContext));

    if (!ic) return ic;

    avformat_get_context_defaults(ic);

    ic->internal = av_mallocz(sizeof(*ic->internal));

    if (!ic->internal) {

        avformat_free_context(ic);

        return NULL;

    }

    return ic;

}


void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)

{

    CPUSH4State *env = cs->env_ptr;

    DisasContext ctx;

    target_ulong pc_start;

    int num_insns;

    int max_insns;

    pc_start = tb->pc;

    ctx.pc = pc_start;

    ctx.tbflags = (uint32_t)tb->flags;

    ctx.envflags = tb->flags & TB_FLAG_ENVFLAGS_MASK;

    ctx.bstate = BS_NONE;

    ctx.memidx = (ctx.tbflags & (1u << SR_MD)) == 0 ? 1 : 0;

    /* We don't know if the delayed pc came from a dynamic or static branch,

       so assume it is a dynamic branch.  */

    ctx.delayed_pc = -1; /* use delayed pc from env pointer */

    ctx.tb = tb;

    ctx.singlestep_enabled = cs->singlestep_enabled;

    ctx.features = env->features;

    ctx.has_movcal = (ctx.tbflags & TB_FLAG_PENDING_MOVCA);

    ctx.gbank = ((ctx.tbflags & (1 << SR_MD)) &&

                 (ctx.tbflags & (1 << SR_RB))) * 0x10;

    ctx.fbank = ctx.tbflags & FPSCR_FR ? 0x10 : 0;

    max_insns = tb->cflags & CF_COUNT_MASK;

    if (max_insns == 0) {

        max_insns = CF_COUNT_MASK;

    }

    max_insns = MIN(max_insns, TCG_MAX_INSNS);

    /* Since the ISA is fixed-width, we can bound by the number

       of instructions remaining on the page.  */

    num_insns = -(ctx.pc | TARGET_PAGE_MASK) / 2;

    max_insns = MIN(max_insns, num_insns);

    /* Single stepping means just that.  */

    if (ctx.singlestep_enabled || singlestep) {

        max_insns = 1;

    }

    gen_tb_start(tb);

    num_insns = 0;

#ifdef CONFIG_USER_ONLY

    if (ctx.tbflags & GUSA_MASK) {

        num_insns = decode_gusa(&ctx, env, &max_insns);

    }

#endif

    while (ctx.bstate == BS_NONE

           && num_insns < max_insns

           && !tcg_op_buf_full()) {

        tcg_gen_insn_start(ctx.pc, ctx.envflags);

        num_insns++;

        if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {

            /* We have hit a breakpoint - make sure PC is up-to-date */

            gen_save_cpu_state(&ctx, true);

            gen_helper_debug(cpu_env);

            ctx.bstate = BS_EXCP;

            /* The address covered by the breakpoint must be included in

               [tb->pc, tb->pc + tb->size) in order to for it to be

               properly cleared -- thus we increment the PC here so that

               the logic setting tb->size below does the right thing.  */

            ctx.pc += 2;

            break;

        }

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

            gen_io_start();

        }

        ctx.opcode = cpu_lduw_code(env, ctx.pc);

	decode_opc(&ctx);

	ctx.pc += 2;

    }

    if (tb->cflags & CF_LAST_IO) {

        gen_io_end();

    }

    if (ctx.tbflags & GUSA_EXCLUSIVE) {

        /* Ending the region of exclusivity.  Clear the bits.  */

        ctx.envflags &= ~GUSA_MASK;

    }

    if (cs->singlestep_enabled) {

        gen_save_cpu_state(&ctx, true);

        gen_helper_debug(cpu_env);

    } else {

	switch (ctx.bstate) {

        case BS_STOP:

            gen_save_cpu_state(&ctx, true);

            tcg_gen_exit_tb(0);

            break;

        case BS_NONE:

            gen_save_cpu_state(&ctx, false);

            gen_goto_tb(&ctx, 0, ctx.pc);

            break;

        case BS_EXCP:

            /* fall through */

        case BS_BRANCH:

        default:

            break;

	}

    }

    gen_tb_end(tb, num_insns);

    tb->size = ctx.pc - pc_start;

    tb->icount = num_insns;

#ifdef DEBUG_DISAS

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)

        && qemu_log_in_addr_range(pc_start)) {

        qemu_log_lock();

	qemu_log("IN:\n");	/* , lookup_symbol(pc_start)); */

        log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);

	qemu_log("\n");

        qemu_log_unlock();

    }

#endif

}


static void sh_serial_ioport_write(void *opaque, uint32_t offs, uint32_t val)

{

    sh_serial_state *s = opaque;

    unsigned char ch;

#ifdef DEBUG_SERIAL

    printf("sh_serial: write offs=0x%02x val=0x%02x\n",

	   offs, val);

#endif

    switch(offs) {

    case 0x00: /* SMR */

        s->smr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0x7b : 0xff);

        return;

    case 0x04: /* BRR */

        s->brr = val;

	return;

    case 0x08: /* SCR */

        /* TODO : For SH7751, SCIF mask should be 0xfb. */

        s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfa : 0xff);

        if (!(val & (1 << 5)))

            s->flags |= SH_SERIAL_FLAG_TEND;

        if ((s->feat & SH_SERIAL_FEAT_SCIF) && s->txi) {

	    qemu_set_irq(s->txi, val & (1 << 7));

        }

        if (!(val & (1 << 6))) {

	    qemu_set_irq(s->rxi, 0);

        }

        return;

    case 0x0c: /* FTDR / TDR */

        if (s->chr) {

            ch = val;

            qemu_chr_write(s->chr, &ch, 1);

	}

	s->dr = val;

	s->flags &= ~SH_SERIAL_FLAG_TDE;

        return;

#if 0

    case 0x14: /* FRDR / RDR */

        ret = 0;

        break;

#endif

    }

    if (s->feat & SH_SERIAL_FEAT_SCIF) {

        switch(offs) {

        case 0x10: /* FSR */

            if (!(val & (1 << 6)))

                s->flags &= ~SH_SERIAL_FLAG_TEND;

            if (!(val & (1 << 5)))

                s->flags &= ~SH_SERIAL_FLAG_TDE;

            if (!(val & (1 << 4)))

                s->flags &= ~SH_SERIAL_FLAG_BRK;

            if (!(val & (1 << 1)))

                s->flags &= ~SH_SERIAL_FLAG_RDF;

            if (!(val & (1 << 0)))

                s->flags &= ~SH_SERIAL_FLAG_DR;

            if (!(val & (1 << 1)) || !(val & (1 << 0))) {

                if (s->rxi) {

                    qemu_set_irq(s->rxi, 0);

                }

            }

            return;

        case 0x18: /* FCR */

            s->fcr = val;

            switch ((val >> 6) & 3) {

            case 0:

                s->rtrg = 1;

                break;

            case 1:

                s->rtrg = 4;

                break;

            case 2:

                s->rtrg = 8;

                break;

            case 3:

                s->rtrg = 14;

                break;

            }

            if (val & (1 << 1)) {

                sh_serial_clear_fifo(s);

                s->sr &= ~(1 << 1);

            }

            return;

        case 0x20: /* SPTR */

            s->sptr = val & 0xf3;

            return;

        case 0x24: /* LSR */

            return;

        }

    }

    else {

#if 0

        switch(offs) {

        case 0x0c:

            ret = s->dr;

            break;

        case 0x10:

            ret = 0;

            break;

        case 0x1c:

            ret = s->sptr;

            break;

        }

#endif

    }

    fprintf(stderr, "sh_serial: unsupported write to 0x%02x\n", offs);

    assert(0);

}


int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,

                                             uint8_t *buf, int buf_size,

                                             const short *samples)

{

    AVPacket pkt;

    AVFrame frame0 = { 0 };

    AVFrame *frame;

    int ret, samples_size, got_packet;

    av_init_packet(&pkt);

    pkt.data = buf;

    pkt.size = buf_size;

    if (samples) {

        frame = &frame0;

        avcodec_get_frame_defaults(frame);

        if (avctx->frame_size) {

            frame->nb_samples = avctx->frame_size;

        } else {

            /* if frame_size is not set, the number of samples must be

             * calculated from the buffer size */

            int64_t nb_samples;

            if (!av_get_bits_per_sample(avctx->codec_id)) {

                av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not "

                                            "support this codec\n");

                return AVERROR(EINVAL);

            }

            nb_samples = (int64_t)buf_size * 8 /

                         (av_get_bits_per_sample(avctx->codec_id) *

                          avctx->channels);

            if (nb_samples >= INT_MAX)

                return AVERROR(EINVAL);

            frame->nb_samples = nb_samples;

        }

        /* it is assumed that the samples buffer is large enough based on the

         * relevant parameters */

        samples_size = av_samples_get_buffer_size(NULL, avctx->channels,

                                                  frame->nb_samples,

                                                  avctx->sample_fmt, 1);

        if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,

                                            avctx->sample_fmt,

                                            (const uint8_t *)samples,

                                            samples_size, 1)))

            return ret;

        /* fabricate frame pts from sample count.

         * this is needed because the avcodec_encode_audio() API does not have

         * a way for the user to provide pts */

        if (avctx->sample_rate && avctx->time_base.num)

            frame->pts = ff_samples_to_time_base(avctx,

                                                 avctx->internal->sample_count);

        else

            frame->pts = AV_NOPTS_VALUE;

        avctx->internal->sample_count += frame->nb_samples;

    } else {

        frame = NULL;

    }

    got_packet = 0;

    ret = avcodec_encode_audio2(avctx, &pkt, frame, &got_packet);

    if (!ret && got_packet && avctx->coded_frame) {

        avctx->coded_frame->pts       = pkt.pts;

        avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY);

    }

    /* free any side data since we cannot return it */

    ff_packet_free_side_data(&pkt);

    if (frame && frame->extended_data != frame->data)

        av_freep(&frame->extended_data);

    return ret ? ret : pkt.size;

}


static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,

                                int size, int64_t pos, uint64_t cluster_time,

                                uint64_t block_duration, int is_keyframe,

                                uint8_t *additional, uint64_t additional_id, int additional_size,

                                int64_t cluster_pos)

{

    uint64_t timecode = AV_NOPTS_VALUE;

    MatroskaTrack *track;

    int res = 0;

    AVStream *st;

    int16_t block_time;

    uint32_t *lace_size = NULL;

    int n, flags, laces = 0;

    uint64_t num;

    if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {

        av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");

        return n;

    }

    data += n;

    size -= n;

    track = matroska_find_track_by_num(matroska, num);

    if (!track || !track->stream) {

        av_log(matroska->ctx, AV_LOG_INFO,

               "Invalid stream %"PRIu64" or size %u\n", num, size);

        return AVERROR_INVALIDDATA;

    } else if (size <= 3)

        return 0;

    st = track->stream;

    if (st->discard >= AVDISCARD_ALL)

        return res;

    av_assert1(block_duration != AV_NOPTS_VALUE);

    block_time = AV_RB16(data);

    data += 2;

    flags = *data++;

    size -= 3;

    if (is_keyframe == -1)

        is_keyframe = flags & 0x80 ? AV_PKT_FLAG_KEY : 0;

    if (cluster_time != (uint64_t)-1

        && (block_time >= 0 || cluster_time >= -block_time)) {

        timecode = cluster_time + block_time;

        if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE

            && timecode < track->end_timecode)

            is_keyframe = 0;  /* overlapping subtitles are not key frame */

        if (is_keyframe)

            av_add_index_entry(st, cluster_pos, timecode, 0,0,AVINDEX_KEYFRAME);

    }

    if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {

        if (timecode < matroska->skip_to_timecode)

            return res;

        if (!st->skip_to_keyframe) {

            av_log(matroska->ctx, AV_LOG_ERROR, "File is broken, keyframes not correctly marked!\n");

            matroska->skip_to_keyframe = 0;

        }

        if (is_keyframe)

            matroska->skip_to_keyframe = 0;

    }

    res = matroska_parse_laces(matroska, &data, size, (flags & 0x06) >> 1,

                               &lace_size, &laces);

    if (res)

        goto end;

    if (!block_duration)

        block_duration = track->default_duration * laces / matroska->time_scale;

    if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time))

        track->end_timecode =

            FFMAX(track->end_timecode, timecode + block_duration);

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

        int64_t lace_duration = block_duration*(n+1) / laces - block_duration*n / laces;

        if (lace_size[n] > size) {

            av_log(matroska->ctx, AV_LOG_ERROR, "Invalid packet size\n");

            break;

        }

        if ((st->codec->codec_id == AV_CODEC_ID_RA_288 ||

             st->codec->codec_id == AV_CODEC_ID_COOK ||

             st->codec->codec_id == AV_CODEC_ID_SIPR ||

             st->codec->codec_id == AV_CODEC_ID_ATRAC3) &&

             st->codec->block_align && track->audio.sub_packet_size) {

            res = matroska_parse_rm_audio(matroska, track, st, data, size,

                                          timecode, pos);

            if (res)

                goto end;

        } else {

            res = matroska_parse_frame(matroska, track, st, data, lace_size[n],

                                      timecode, lace_duration,

                                      pos, !n? is_keyframe : 0,

                                      additional, additional_id, additional_size);

            if (res)

                goto end;

        }

        if (timecode != AV_NOPTS_VALUE)

            timecode = lace_duration ? timecode + lace_duration : AV_NOPTS_VALUE;

        data += lace_size[n];

        size -= lace_size[n];

    }

end:

    av_free(lace_size);

    return res;

}


static void test_hbitmap_iter_past(TestHBitmapData *data,

                                    const void *unused)

{

    hbitmap_test_init(data, L3, 0);

    hbitmap_test_set(data, 0, L3);

    hbitmap_test_check(data, L3);

}


int do_balloon(Monitor *mon, const QDict *params,

	       MonitorCompletion cb, void *opaque)

{

    int ret;

    if (kvm_enabled() && !kvm_has_sync_mmu()) {

        qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");

        return -1;

    }

    ret = qemu_balloon(qdict_get_int(params, "value"), cb, opaque);

    if (ret == 0) {

        qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");

        return -1;

    }

    cb(opaque, NULL);

    return 0;

}


static void gif_put_bits_rev(PutBitContext *s, int n, unsigned int value)

{

    unsigned int bit_buf;

    int bit_cnt;

    //    printf("put_bits=%d %x\n", n, value);

    assert(n == 32 || value < (1U << n));

    bit_buf = s->bit_buf;

    bit_cnt = 32 - s->bit_left; /* XXX:lazyness... was = s->bit_cnt; */

    //    printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf);

    /* XXX: optimize */

    if (n < (32-bit_cnt)) {

        bit_buf |= value << (bit_cnt);

        bit_cnt+=n;

    } else {

        bit_buf |= value << (bit_cnt);

        *s->buf_ptr = bit_buf & 0xff;

        s->buf_ptr[1] = (bit_buf >> 8) & 0xff;

        s->buf_ptr[2] = (bit_buf >> 16) & 0xff;

        s->buf_ptr[3] = (bit_buf >> 24) & 0xff;

        //printf("bitbuf = %08x\n", bit_buf);

        s->buf_ptr+=4;

        if (s->buf_ptr >= s->buf_end)

            puts("bit buffer overflow !!"); // should never happen ! who got rid of the callback ???

//            flush_buffer_rev(s);

        bit_cnt=bit_cnt + n - 32;

        if (bit_cnt == 0) {

            bit_buf = 0;

        } else {

            bit_buf = value >> (n - bit_cnt);

        }

    }

    s->bit_buf = bit_buf;

    s->bit_left = 32 - bit_cnt;

}


uint64_t qemu_get_be64(QEMUFile *f)

{

    uint64_t v;

    v = (uint64_t)qemu_get_be32(f) << 32;

    v |= qemu_get_be32(f);

    return v;

}


static int decode_b_mbs(VC9Context *v)

{

    MpegEncContext *s = &v->s;

    GetBitContext *gb = &v->s.gb;

    int current_mb = 0, i /* MB / B postion information */;

    int b_mv_type = BMV_TYPE_BACKWARD;

    int mquant, mqdiff; /* MB quant stuff */

    int ttmb; /* MacroBlock transform type */

    static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },

        offset_table[6] = { 0, 1, 3, 7, 15, 31 };

    int mb_has_coeffs = 1; /* last_flag */

    int dmv1_x, dmv1_y, dmv2_x, dmv2_y; /* Differential MV components */

    int k_x, k_y; /* Long MV fixed bitlength */

    int hpel_flag; /* Some MB properties */

    int index, index1; /* LUT indices */

    int val, sign; /* MVDATA temp values */

    /* Select proper long MV range */

    switch (v->mvrange)

    {

    case 1: k_x = 10; k_y = 9; break;

    case 2: k_x = 12; k_y = 10; break;

    case 3: k_x = 13; k_y = 11; break;

    default: /*case 0 too */ k_x = 9; k_y = 8; break;

    }

    hpel_flag = v->mv_mode & 1; //MV_PMODE is HPEL

    k_x -= hpel_flag;

    k_y -= hpel_flag;

    /* Select ttmb table depending on pq */

    if (v->pq < 5) v->ttmb_vlc = &vc9_ttmb_vlc[0];

    else if (v->pq < 13) v->ttmb_vlc = &vc9_ttmb_vlc[1];

    else v->ttmb_vlc = &vc9_ttmb_vlc[2];

    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 (v->direct_mb_plane.is_raw)

                v->direct_mb_plane.data[current_mb] = get_bits(gb, 1);

            if (v->skip_mb_plane.is_raw)

                v->skip_mb_plane.data[current_mb] = get_bits(gb, 1);

            if (!v->direct_mb_plane.data[current_mb])

            {

                if (v->skip_mb_plane.data[current_mb])

                {

                    b_mv_type = decode012(gb);

                    if (v->bfraction > 420 /*1/2*/ &&

                        b_mv_type < 3) b_mv_type = 1-b_mv_type;

                }

                else

                {

                    GET_MVDATA(dmv1_x, dmv1_y);

                    if (!s->mb_intra /* b_mv1 tells not intra */)

                    {

                        b_mv_type = decode012(gb);

                        if (v->bfraction > 420 /*1/2*/ &&

                            b_mv_type < 3) b_mv_type = 1-b_mv_type;

                    }

                }

            }

            if (!v->skip_mb_plane.data[current_mb])

            {

                if (mb_has_coeffs /* BMV1 == "last" */)

                {

                    GET_MQUANT();

                    if (s->mb_intra /* intra mb */)

                        s->ac_pred = get_bits(gb, 1);

                }

                else

                {

                    /* if bmv1 tells MVs are interpolated */

                    if (b_mv_type == BMV_TYPE_INTERPOLATED)

                    {

                        GET_MVDATA(dmv2_x, dmv2_y);

                    }

                    /* GET_MVDATA has reset some stuff */

                    if (mb_has_coeffs /* b_mv2 == "last" */)

                    {

                        if (s->mb_intra /* intra_mb */)

                            s->ac_pred = get_bits(gb, 1);

                        GET_MQUANT();

                    }

                }

            }

            //End1

            if (v->ttmbf)

                ttmb = get_vlc2(gb, v->ttmb_vlc->table,

                                   VC9_TTMB_VLC_BITS, 12);

            //End2

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

            {

                /* FIXME: process the block */

            }

            current_mb++;

        }

    }

    return 0;

}


static int ehci_execute(EHCIQueue *q)

{

    USBPort *port;

    USBDevice *dev;

    int ret;

    int i;

    int endp;

    int devadr;

    if ( !(q->qh.token & QTD_TOKEN_ACTIVE)) {

        fprintf(stderr, "Attempting to execute inactive QH\n");

        return USB_RET_PROCERR;

    }

    q->tbytes = (q->qh.token & QTD_TOKEN_TBYTES_MASK) >> QTD_TOKEN_TBYTES_SH;

    if (q->tbytes > BUFF_SIZE) {

        fprintf(stderr, "Request for more bytes than allowed\n");

        return USB_RET_PROCERR;

    }

    q->pid = (q->qh.token & QTD_TOKEN_PID_MASK) >> QTD_TOKEN_PID_SH;

    switch(q->pid) {

        case 0: q->pid = USB_TOKEN_OUT; break;

        case 1: q->pid = USB_TOKEN_IN; break;

        case 2: q->pid = USB_TOKEN_SETUP; break;

        default: fprintf(stderr, "bad token\n"); break;

    }

    if ((q->tbytes && q->pid != USB_TOKEN_IN) &&

        (ehci_buffer_rw(q, q->tbytes, 0) != 0)) {

        return USB_RET_PROCERR;

    }

    endp = get_field(q->qh.epchar, QH_EPCHAR_EP);

    devadr = get_field(q->qh.epchar, QH_EPCHAR_DEVADDR);

    ret = USB_RET_NODEV;

    // TO-DO: associating device with ehci port

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

        port = &q->ehci->ports[i];

        dev = port->dev;

        if (!(q->ehci->portsc[i] &(PORTSC_CONNECT))) {

            DPRINTF("Port %d, no exec, not connected(%08X)\n",

                    i, q->ehci->portsc[i]);

            continue;

        }

        q->packet.pid = q->pid;

        q->packet.devaddr = devadr;

        q->packet.devep = endp;

        q->packet.data = q->buffer;

        q->packet.len = q->tbytes;

        ret = usb_handle_packet(dev, &q->packet);

        DPRINTF("submit: qh %x next %x qtd %x pid %x len %d (total %d) endp %x ret %d\n",

                q->qhaddr, q->qh.next, q->qtdaddr, q->pid,

                q->packet.len, q->tbytes, endp, ret);

        if (ret != USB_RET_NODEV) {

            break;

        }

    }

    if (ret > BUFF_SIZE) {

        fprintf(stderr, "ret from usb_handle_packet > BUFF_SIZE\n");

        return USB_RET_PROCERR;

    }

    return ret;

}


static void powerpc_set_compat(Object *obj, Visitor *v, const char *name,

                               void *opaque, Error **errp)

{

    Error *error = NULL;

    char *value = NULL;

    Property *prop = opaque;

    uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop);

    visit_type_str(v, name, &value, &error);

    if (error) {

        error_propagate(errp, error);

        return;

    }

    if (strcmp(value, "power6") == 0) {

        *max_compat = CPU_POWERPC_LOGICAL_2_05;

    } else if (strcmp(value, "power7") == 0) {

        *max_compat = CPU_POWERPC_LOGICAL_2_06;

    } else if (strcmp(value, "power8") == 0) {

        *max_compat = CPU_POWERPC_LOGICAL_2_07;

    } else {

        error_setg(errp, "Invalid compatibility mode \"%s\"", value);

    }

    g_free(value);

}


static bool write_header(FILE *fp)

{

    static const TraceRecord header = {

        .event = HEADER_EVENT_ID,

        .timestamp_ns = HEADER_MAGIC,

        .x1 = HEADER_VERSION,

    };

    return fwrite(&header, sizeof header, 1, fp) == 1;

}


static int encode_mode(CinepakEncContext *s, int h, AVPicture *scratch_pict, AVPicture *last_pict, strip_info *info, unsigned char *buf)

{

    int x, y, z, flags, bits, temp_size, header_ofs, ret = 0, mb_count = s->w * h / MB_AREA;

    int needs_extra_bit, should_write_temp;

    unsigned char temp[64]; //32/2 = 16 V4 blocks at 4 B each -> 64 B

    mb_info *mb;

    AVPicture sub_scratch, sub_last;

    //encode codebooks

////// MacOS vintage decoder compatibility dictates the presence of

////// the codebook chunk even when the codebook is empty - pretty dumb...

////// and also the certain order of the codebook chunks -- rl

    if(info->v4_size || !s->skip_empty_cb)

        ret += encode_codebook(s, info->v4_codebook, info->v4_size, 0x20, 0x24, buf + ret);

    if(info->v1_size || !s->skip_empty_cb)

        ret += encode_codebook(s, info->v1_codebook, info->v1_size, 0x22, 0x26, buf + ret);

    //update scratch picture

    for(z = y = 0; y < h; y += MB_SIZE) {

        for(x = 0; x < s->w; x += MB_SIZE, z++) {

            mb = &s->mb[z];

            get_sub_picture(s, x, y, scratch_pict, &sub_scratch);

            if(info->mode == MODE_MC && mb->best_encoding == ENC_SKIP) {

                get_sub_picture(s, x, y, last_pict, &sub_last);

                copy_mb(s, &sub_scratch, &sub_last);

            } else if(info->mode == MODE_V1_ONLY || mb->best_encoding == ENC_V1)

                decode_v1_vector(s, &sub_scratch, mb->v1_vector, info);

            else

                decode_v4_vector(s, &sub_scratch, mb->v4_vector, info);

        }

    }

    switch(info->mode) {

    case MODE_V1_ONLY:

        //av_log(s->avctx, AV_LOG_INFO, "mb_count = %i\n", mb_count);

        ret += write_chunk_header(buf + ret, 0x32, mb_count);

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

            buf[ret++] = s->mb[x].v1_vector;

        break;

    case MODE_V1_V4:

        //remember header position

        header_ofs = ret;

        ret += CHUNK_HEADER_SIZE;

        for(x = 0; x < mb_count; x += 32) {

            flags = 0;

            for(y = x; y < FFMIN(x+32, mb_count); y++)

                if(s->mb[y].best_encoding == ENC_V4)

                    flags |= 1 << (31 - y + x);

            AV_WB32(&buf[ret], flags);

            ret += 4;

            for(y = x; y < FFMIN(x+32, mb_count); y++) {

                mb = &s->mb[y];

                if(mb->best_encoding == ENC_V1)

                    buf[ret++] = mb->v1_vector;

                else

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

                        buf[ret++] = mb->v4_vector[z];

            }

        }

        write_chunk_header(buf + header_ofs, 0x30, ret - header_ofs - CHUNK_HEADER_SIZE);

        break;

    case MODE_MC:

        //remember header position

        header_ofs = ret;

        ret += CHUNK_HEADER_SIZE;

        flags = bits = temp_size = 0;

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

            mb = &s->mb[x];

            flags |= (mb->best_encoding != ENC_SKIP) << (31 - bits++);

            needs_extra_bit = 0;

            should_write_temp = 0;

            if(mb->best_encoding != ENC_SKIP) {

                if(bits < 32)

                    flags |= (mb->best_encoding == ENC_V4) << (31 - bits++);

                else

                    needs_extra_bit = 1;

            }

            if(bits == 32) {

                AV_WB32(&buf[ret], flags);

                ret += 4;

                flags = bits = 0;

                if(mb->best_encoding == ENC_SKIP || needs_extra_bit) {

                    memcpy(&buf[ret], temp, temp_size);

                    ret += temp_size;

                    temp_size = 0;

                } else

                    should_write_temp = 1;

            }

            if(needs_extra_bit) {

                flags = (mb->best_encoding == ENC_V4) << 31;

                bits = 1;

            }

            if(mb->best_encoding == ENC_V1)

                temp[temp_size++] = mb->v1_vector;

            else if(mb->best_encoding == ENC_V4)

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

                    temp[temp_size++] = mb->v4_vector[z];

            if(should_write_temp) {

                memcpy(&buf[ret], temp, temp_size);

                ret += temp_size;

                temp_size = 0;

            }

        }

        if(bits > 0) {

            AV_WB32(&buf[ret], flags);

            ret += 4;

            memcpy(&buf[ret], temp, temp_size);

            ret += temp_size;

        }

        write_chunk_header(buf + header_ofs, 0x31, ret - header_ofs - CHUNK_HEADER_SIZE);

        break;

    }

    return ret;

}