int av_grab(AVFormatContext *s)

{

    UINT8 audio_buf[AUDIO_FIFO_SIZE];

    UINT8 audio_buf1[AUDIO_FIFO_SIZE];

    UINT8 audio_out[AUDIO_FIFO_SIZE];

    UINT8 video_buffer[1024*1024];

    char buf[256];

    short *samples;

    URLContext *audio_handle = NULL, *video_handle = NULL;

    int ret;

    AVCodecContext *enc, *first_video_enc = NULL;

    int frame_size, frame_bytes;

    int use_audio, use_video;

    int frame_rate, sample_rate, channels;

    int width, height, frame_number, i, pix_fmt = 0;

    AVOutputStream *ost_table[s->nb_streams], *ost;

    UINT8 *picture_in_buf = NULL, *picture_420p = NULL;

    int audio_fifo_size = 0, picture_size = 0;

    INT64 time_start;

    /* init output stream info */

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

        ost_table[i] = NULL;

    /* output stream init */

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

        ost = av_mallocz(sizeof(AVOutputStream));

        if (!ost)

            goto fail;

        ost->index = i;

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

        ost_table[i] = ost;

    }

    use_audio = 0;

    use_video = 0;

    frame_rate = 0;

    sample_rate = 0;

    frame_size = 0;

    channels = 1;

    width = 0;

    height = 0;

    frame_number = 0;

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

        AVCodec *codec;

        ost = ost_table[i];

        enc = &ost->st->codec;

        codec = avcodec_find_encoder(enc->codec_id);

        if (!codec) {

            fprintf(stderr, "Unknown codec\n");

            return -1;

        }

        if (avcodec_open(enc, codec) < 0) {

            fprintf(stderr, "Incorrect encode parameters\n");

            return -1;

        }

        switch(enc->codec_type) {

        case CODEC_TYPE_AUDIO:

            use_audio = 1;

            if (enc->sample_rate > sample_rate)

                sample_rate = enc->sample_rate;

            if (enc->frame_size > frame_size)

                frame_size = enc->frame_size;

            if (enc->channels > channels)

                channels = enc->channels;

            break;

        case CODEC_TYPE_VIDEO:

            if (!first_video_enc)

                first_video_enc = enc;

            use_video = 1;

            if (enc->frame_rate > frame_rate)

                frame_rate = enc->frame_rate;

            if (enc->width > width)

                width = enc->width;

            if (enc->height > height)

                height = enc->height;

            break;

        }

    }

    /* audio */

    samples = NULL;

    if (use_audio) {

        snprintf(buf, sizeof(buf), "audio:%d,%d", sample_rate, channels);

        ret = url_open(&audio_handle, buf, URL_RDONLY);

        if (ret < 0) {

            fprintf(stderr, "Could not open audio device: disabling audio capture\n");

            use_audio = 0;

        } else {

            URLFormat f;

            /* read back exact grab parameters */

            if (url_getformat(audio_handle, &f) < 0) {

                fprintf(stderr, "could not read back video grab parameters\n");

                goto fail;

            }

            sample_rate = f.sample_rate;

            channels = f.channels;

            audio_fifo_size = ((AUDIO_FIFO_SIZE / 2) / audio_handle->packet_size) *

                audio_handle->packet_size;

            fprintf(stderr, "Audio sampling: %d Hz, %s\n",

                    sample_rate, channels == 2 ? "stereo" : "mono");

        }

    }

    /* video */

    if (use_video) {

        snprintf(buf, sizeof(buf), "video:%d,%d,%f",

                 width, height, (float)frame_rate / FRAME_RATE_BASE);

        ret = url_open(&video_handle, buf, URL_RDONLY);

        if (ret < 0) {

            fprintf(stderr,"Could not init video 4 linux capture: disabling video capture\n");

            use_video = 0;

        } else {

            URLFormat f;

            const char *pix_fmt_str;

            /* read back exact grab parameters */

            if (url_getformat(video_handle, &f) < 0) {

                fprintf(stderr, "could not read back video grab parameters\n");

                goto fail;

            }

            width = f.width;

            height = f.height;

            pix_fmt = f.pix_fmt;

            switch(pix_fmt) {

            case PIX_FMT_YUV420P:

                pix_fmt_str = "420P";

                break;

            case PIX_FMT_YUV422:

                pix_fmt_str = "422";

                break;

            case PIX_FMT_RGB24:

                pix_fmt_str = "RGB24";

                break;

            case PIX_FMT_BGR24:

                pix_fmt_str = "BGR24";

                break;

            default:

                pix_fmt_str = "???";

                break;

            }

            picture_size = video_handle->packet_size;

            picture_in_buf = malloc(picture_size);

            if (!picture_in_buf)

                goto fail;

            /* allocate a temporary picture if not grabbing in 420P format */

            if (pix_fmt != PIX_FMT_YUV420P) {

                picture_420p = malloc((width * height * 3) / 2);

            }

            fprintf(stderr, "Video sampling: %dx%d, %s format, %0.2f fps\n",

                    width, height, pix_fmt_str, (float)frame_rate / FRAME_RATE_BASE);

        }

    }

    if (!use_video && !use_audio) {

        fprintf(stderr,"Could not open grab devices : exiting\n");

        exit(1);

    }

    /* init built in conversion functions */

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

        ost = ost_table[i];

        enc = &ost->st->codec;

        switch(enc->codec_type) {

        case CODEC_TYPE_AUDIO:

            ost->audio_resample = 0;

            if ((enc->channels != channels ||

                 enc->sample_rate != sample_rate)) {

                ost->audio_resample = 1;

                ost->resample = audio_resample_init(enc->channels, channels,

                                                    enc->sample_rate, sample_rate);

            }

            if (fifo_init(&ost->fifo, (2 * audio_fifo_size * enc->sample_rate *

                                       enc->channels) / sample_rate))

                goto fail;

            break;

        case CODEC_TYPE_VIDEO:

            ost->video_resample = 0;

            if (enc->width != width ||

                enc->height != height) {

                UINT8 *buf;

                ost->video_resample = 1;

                buf = malloc((enc->width * enc->height * 3) / 2);

                if (!buf)

                    goto fail;

                ost->pict_tmp.data[0] = buf;

                ost->pict_tmp.data[1] = buf + enc->width * height;

                ost->pict_tmp.data[2] = ost->pict_tmp.data[1] + (enc->width * height) / 4;

                ost->pict_tmp.linesize[0] = enc->width;

                ost->pict_tmp.linesize[1] = enc->width / 2;

                ost->pict_tmp.linesize[2] = enc->width / 2;

                ost->img_resample_ctx = img_resample_init(

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

                                  width, height);

            }

        }

    }

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

    s->format->write_header(s);

    time_start = gettime();

    term_init();

    for(;;) {

        /* if 'q' pressed, exits */

        if (read_key() == 'q')

            break;

        /* read & compress audio frames */

        if (use_audio) {

            int ret, nb_samples, nb_samples_out;

            UINT8 *buftmp;

            for(;;) {

                ret = url_read(audio_handle, audio_buf, audio_fifo_size);

                if (ret <= 0)

                    break;

                /* fill each codec fifo by doing the right sample

                   rate conversion. This is not optimal because we

                   do too much work, but it is easy to do */

                nb_samples = ret / (channels * 2);

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

                    ost = ost_table[i];

                    enc = &ost->st->codec;

                    if (enc->codec_type == CODEC_TYPE_AUDIO) {

                        /* rate & stereo convertion */

                        if (!ost->audio_resample) {

                            buftmp = audio_buf;

                            nb_samples_out = nb_samples;

                        } else {

                            buftmp = audio_buf1;

                            nb_samples_out = audio_resample(ost->resample,

                                                            (short *)buftmp, (short *)audio_buf,

                                                            nb_samples);

                        }

                        fifo_write(&ost->fifo, buftmp, nb_samples_out * enc->channels * 2,

                                   &ost->fifo.wptr);

                    }

                }

                /* compress as many frame as possible with each audio codec */

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

                    ost = ost_table[i];

                    enc = &ost->st->codec;

                    if (enc->codec_type == CODEC_TYPE_AUDIO) {

                        frame_bytes = enc->frame_size * 2 * enc->channels;

                        while (fifo_read(&ost->fifo, audio_buf,

                                         frame_bytes, &ost->fifo.rptr) == 0) {

                            ret = avcodec_encode_audio(enc,

                                                       audio_out, sizeof(audio_out),

                                                       (short *)audio_buf);

                            s->format->write_packet(s, ost->index, audio_out, ret);

                        }

                    }

                }

            }

        }

        if (use_video) {

            AVPicture *picture1, *picture2, *picture;

            AVPicture picture_tmp0, picture_tmp1;

            ret = url_read(video_handle, picture_in_buf, picture_size);

            if (ret < 0)

                break;

            picture2 = &picture_tmp0;

            avpicture_fill(picture2, picture_in_buf, pix_fmt, width, height);

            if (pix_fmt != PIX_FMT_YUV420P) {

                picture = &picture_tmp1;

                avpicture_fill(picture, picture_420p,

                               PIX_FMT_YUV420P, width, height);

                img_convert(picture, PIX_FMT_YUV420P,

                            picture2, pix_fmt,

                            width, height);

            } else {

                picture = picture2;

            }

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

                ost = ost_table[i];

                enc = &ost->st->codec;

                if (enc->codec_type == CODEC_TYPE_VIDEO) {

                    int n1, n2, nb;

                    /* feed each codec with its requested frame rate */

                    n1 = ((INT64)frame_number * enc->frame_rate) / frame_rate;

                    n2 = (((INT64)frame_number + 1) * enc->frame_rate) / frame_rate;

                    nb = n2 - n1;

                    if (nb > 0) {

                        /* resize the picture if needed */

                        if (ost->video_resample) {

                            picture1 = &ost->pict_tmp;

                            img_resample(ost->img_resample_ctx,

                                         picture1, picture);

                        } else {

                            picture1 = picture;

                        }

                        ret = avcodec_encode_video(enc, video_buffer,

                                                   sizeof(video_buffer),

                                                   picture1);

                        s->format->write_packet(s, ost->index, video_buffer, ret);

                    }

                }

            }

            frame_number++;

        }

        /* write report */

        {

            char buf[1024];

            INT64 total_size;

            float ti, bitrate;

            static float last_ti;

            INT64 ti1;

            total_size = url_ftell(&s->pb);

            ti1 = gettime() - time_start;

            /* check elapsed time */

            if (recording_time && ti1 >= recording_time)

                break;

            ti = ti1 / 1000000.0;

            if (ti < 0.1)

                ti = 0.1;

            /* dispaly twice per second */

            if ((ti - last_ti) >= 0.5) {

                last_ti = ti;

                bitrate = (int)((total_size * 8) / ti / 1000.0);

                buf[0] = '\0';

                if (use_video) {

                    sprintf(buf + strlen(buf), "frame=%5d fps=%4.1f q=%2d ",

                            frame_number, (float)frame_number / ti, first_video_enc->quality);

                }

                sprintf(buf + strlen(buf), "size=%8LdkB time=%0.1f bitrate=%6.1fkbits/s",

                        total_size / 1024, ti, bitrate);

                fprintf(stderr, "%s    \r", buf);

                fflush(stderr);

            }

        }

    }

    term_exit();

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

        ost = ost_table[i];

        enc = &ost->st->codec;

        avcodec_close(enc);

    }

    s->format->write_trailer(s);

    if (audio_handle)

        url_close(audio_handle);

    if (video_handle)

        url_close(video_handle);

    /* write report */

    {

        float ti, bitrate;

        INT64 total_size;

        total_size = url_ftell(&s->pb);

        ti = (gettime() - time_start) / 1000000.0;

        if (ti < 0.1)

            ti = 0.1;

        bitrate = (int)((total_size * 8) / ti / 1000.0);

        fprintf(stderr, "\033[K\nTotal time = %0.1f s, %Ld KBytes, %0.1f kbits/s\n",

                ti, total_size / 1024, bitrate);

        if (use_video) {

            fprintf(stderr, "Total frames = %d\n", frame_number);

        }

    }

    ret = 0;

 fail1:

    if (picture_in_buf)

        free(picture_in_buf);

    if (picture_420p)

        free(picture_420p);

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

        ost = ost_table[i];

        if (ost) {

            if (ost->fifo.buffer)

                fifo_free(&ost->fifo);

            if (ost->pict_tmp.data[0])

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

            if (ost->video_resample)

                img_resample_close(ost->img_resample_ctx);

            if (ost->audio_resample)

                audio_resample_close(ost->resample);

            free(ost);

        }

    }

    return ret;

 fail:

    ret = -ENOMEM;

    goto fail1;

}


static int64_t nfs_client_open(NFSClient *client, QDict *options,

                               int flags, Error **errp, int open_flags)

{

    int ret = -EINVAL;

    QemuOpts *opts = NULL;

    Error *local_err = NULL;

    struct stat st;

    char *file = NULL, *strp = NULL;

    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);

    qemu_opts_absorb_qdict(opts, options, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        ret = -EINVAL;

        goto fail;

    }

    client->path = g_strdup(qemu_opt_get(opts, "path"));

    if (!client->path) {

        ret = -EINVAL;

        error_setg(errp, "No path was specified");

        goto fail;

    }

    strp = strrchr(client->path, '/');

    if (strp == NULL) {

        error_setg(errp, "Invalid URL specified");

        goto fail;

    }

    file = g_strdup(strp);

    *strp = 0;

    /* Pop the config into our state object, Exit if invalid */

    client->server = nfs_config(options, errp);

    if (!client->server) {

        ret = -EINVAL;

        goto fail;

    }

    client->context = nfs_init_context();

    if (client->context == NULL) {

        error_setg(errp, "Failed to init NFS context");

        goto fail;

    }

    if (qemu_opt_get(opts, "uid")) {

        client->uid = qemu_opt_get_number(opts, "uid", 0);

        nfs_set_uid(client->context, client->uid);

    }

    if (qemu_opt_get(opts, "gid")) {

        client->gid = qemu_opt_get_number(opts, "gid", 0);

        nfs_set_gid(client->context, client->gid);

    }

    if (qemu_opt_get(opts, "tcp-syncnt")) {

        client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syncnt", 0);

        nfs_set_tcp_syncnt(client->context, client->tcp_syncnt);

    }

#ifdef LIBNFS_FEATURE_READAHEAD

    if (qemu_opt_get(opts, "readahead")) {

        if (open_flags & BDRV_O_NOCACHE) {

            error_setg(errp, "Cannot enable NFS readahead "

                             "if cache.direct = on");

            goto fail;

        }

        client->readahead = qemu_opt_get_number(opts, "readahead", 0);

        if (client->readahead > QEMU_NFS_MAX_READAHEAD_SIZE) {

            error_report("NFS Warning: Truncating NFS readahead "

                         "size to %d", QEMU_NFS_MAX_READAHEAD_SIZE);

            client->readahead = QEMU_NFS_MAX_READAHEAD_SIZE;

        }

        nfs_set_readahead(client->context, client->readahead);

#ifdef LIBNFS_FEATURE_PAGECACHE

        nfs_set_pagecache_ttl(client->context, 0);

#endif

        client->cache_used = true;

    }

#endif

#ifdef LIBNFS_FEATURE_PAGECACHE

    if (qemu_opt_get(opts, "pagecache")) {

        if (open_flags & BDRV_O_NOCACHE) {

            error_setg(errp, "Cannot enable NFS pagecache "

                             "if cache.direct = on");

            goto fail;

        }

        client->pagecache = qemu_opt_get_number(opts, "pagecache", 0);

        if (client->pagecache > QEMU_NFS_MAX_PAGECACHE_SIZE) {

            error_report("NFS Warning: Truncating NFS pagecache "

                         "size to %d pages", QEMU_NFS_MAX_PAGECACHE_SIZE);

            client->pagecache = QEMU_NFS_MAX_PAGECACHE_SIZE;

        }

        nfs_set_pagecache(client->context, client->pagecache);

        nfs_set_pagecache_ttl(client->context, 0);

        client->cache_used = true;

    }

#endif

#ifdef LIBNFS_FEATURE_DEBUG

    if (qemu_opt_get(opts, "debug")) {

        client->debug = qemu_opt_get_number(opts, "debug", 0);

        /* limit the maximum debug level to avoid potential flooding

         * of our log files. */

        if (client->debug > QEMU_NFS_MAX_DEBUG_LEVEL) {

            error_report("NFS Warning: Limiting NFS debug level "

                         "to %d", QEMU_NFS_MAX_DEBUG_LEVEL);

            client->debug = QEMU_NFS_MAX_DEBUG_LEVEL;

        }

        nfs_set_debug(client->context, client->debug);

    }

#endif

    ret = nfs_mount(client->context, client->server->host, client->path);

    if (ret < 0) {

        error_setg(errp, "Failed to mount nfs share: %s",

                   nfs_get_error(client->context));

        goto fail;

    }

    if (flags & O_CREAT) {

        ret = nfs_creat(client->context, file, 0600, &client->fh);

        if (ret < 0) {

            error_setg(errp, "Failed to create file: %s",

                       nfs_get_error(client->context));

            goto fail;

        }

    } else {

        ret = nfs_open(client->context, file, flags, &client->fh);

        if (ret < 0) {

            error_setg(errp, "Failed to open file : %s",

                       nfs_get_error(client->context));

            goto fail;

        }

    }

    ret = nfs_fstat(client->context, client->fh, &st);

    if (ret < 0) {

        error_setg(errp, "Failed to fstat file: %s",

                   nfs_get_error(client->context));

        goto fail;

    }

    ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);

    client->st_blocks = st.st_blocks;

    client->has_zero_init = S_ISREG(st.st_mode);

    *strp = '/';

    goto out;

fail:

    nfs_client_close(client);

out:

    qemu_opts_del(opts);

    g_free(file);

    return ret;

}


void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band,

                               IVITile *tile, int32_t mv_scale)

{

    int             x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type;

    int             offs, mb_offset, row_offset;

    IVIMbInfo       *mb, *ref_mb;

    const int16_t   *src;

    int16_t         *dst;

    void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch,

                             int mc_type);

    offs       = tile->ypos * band->pitch + tile->xpos;

    mb         = tile->mbs;

    ref_mb     = tile->ref_mbs;

    row_offset = band->mb_size * band->pitch;

    need_mc    = 0; /* reset the mc tracking flag */

    for (y = tile->ypos; y < (tile->ypos + tile->height); y += band->mb_size) {

        mb_offset = offs;

        for (x = tile->xpos; x < (tile->xpos + tile->width); x += band->mb_size) {

            mb->xpos     = x;

            mb->ypos     = y;

            mb->buf_offs = mb_offset;

            mb->type = 1; /* set the macroblocks type = INTER */

            mb->cbp  = 0; /* all blocks are empty */

            if (!band->qdelta_present && !band->plane && !band->band_num) {

                mb->q_delta = band->glob_quant;

                mb->mv_x    = 0;

                mb->mv_y    = 0;

            }

            if (band->inherit_qdelta && ref_mb)

                mb->q_delta = ref_mb->q_delta;

            if (band->inherit_mv) {

                /* motion vector inheritance */

                if (mv_scale) {

                    mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);

                    mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);

                } else {

                    mb->mv_x = ref_mb->mv_x;

                    mb->mv_y = ref_mb->mv_y;

                }

                need_mc |= mb->mv_x || mb->mv_y; /* tracking non-zero motion vectors */

            }

            mb++;

            if (ref_mb)

                ref_mb++;

            mb_offset += band->mb_size;

        } // for x

        offs += row_offset;

    } // for y

    if (band->inherit_mv && need_mc) { /* apply motion compensation if there is at least one non-zero motion vector */

        num_blocks = (band->mb_size != band->blk_size) ? 4 : 1; /* number of blocks per mb */

        mc_no_delta_func = (band->blk_size == 8) ? ff_ivi_mc_8x8_no_delta

                                                 : ff_ivi_mc_4x4_no_delta;

        for (mbn = 0, mb = tile->mbs; mbn < tile->num_MBs; mb++, mbn++) {

            mv_x = mb->mv_x;

            mv_y = mb->mv_y;

            if (!band->is_halfpel) {

                mc_type = 0; /* we have only fullpel vectors */

            } else {

                mc_type = ((mv_y & 1) << 1) | (mv_x & 1);

                mv_x >>= 1;

                mv_y >>= 1; /* convert halfpel vectors into fullpel ones */

            }

            for (blk = 0; blk < num_blocks; blk++) {

                /* adjust block position in the buffer according with its number */

                offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch);

                mc_no_delta_func(band->buf + offs,

                                 band->ref_buf + offs + mv_y * band->pitch + mv_x,

                                 band->pitch, mc_type);

            }

        }

    } else {

        /* copy data from the reference tile into the current one */

        src = band->ref_buf + tile->ypos * band->pitch + tile->xpos;

        dst = band->buf     + tile->ypos * band->pitch + tile->xpos;

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

            memcpy(dst, src, tile->width*sizeof(band->buf[0]));

            src += band->pitch;

            dst += band->pitch;

        }

    }

}


static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){

    int y_size = s->b8_stride * (2 * s->mb_height + 1);

    int c_size = s->mb_stride * (s->mb_height + 1);

    int yc_size = y_size + 2 * c_size;

    int i;

    // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)

    FF_ALLOCZ_OR_GOTO(s->avctx, s->allocated_edge_emu_buffer, (s->width+64)*2*21*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance

    s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;

     //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer()

    FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad,  (s->width+64)*4*16*2*sizeof(uint8_t), fail)

    s->me.temp=         s->me.scratchpad;

    s->rd_scratchpad=   s->me.scratchpad;

    s->b_scratchpad=    s->me.scratchpad;

    s->obmc_scratchpad= s->me.scratchpad + 16;

    if (s->encoding) {

        FF_ALLOCZ_OR_GOTO(s->avctx, s->me.map      , ME_MAP_SIZE*sizeof(uint32_t), fail)

        FF_ALLOCZ_OR_GOTO(s->avctx, s->me.score_map, ME_MAP_SIZE*sizeof(uint32_t), fail)

        if(s->avctx->noise_reduction){

            FF_ALLOCZ_OR_GOTO(s->avctx, s->dct_error_sum, 2 * 64 * sizeof(int), fail)

        }

    }

    FF_ALLOCZ_OR_GOTO(s->avctx, s->blocks, 64*12*2 * sizeof(DCTELEM), fail)

    s->block= s->blocks[0];

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

        s->pblocks[i] = &s->block[i];

    }

    if (s->out_format == FMT_H263) {

        /* ac values */

        FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base, yc_size * sizeof(int16_t) * 16, fail);

        s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;

        s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;

        s->ac_val[2] = s->ac_val[1] + c_size;

    }

    return 0;

fail:

    return -1; //free() through MPV_common_end()

}


static int msrle_decode_frame(AVCodecContext *avctx,
                              void *data, int *got_frame,
                              AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    MsrleContext *s = avctx->priv_data;
    int istride = FFALIGN(avctx->width*avctx->bits_per_coded_sample, 32) / 8;
    int ret;
    s->buf = buf;
    s->size = buf_size;
    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
        return ret;
    if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) {
        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
        if (pal) {
            s->frame->palette_has_changed = 1;
            memcpy(s->pal, pal, AVPALETTE_SIZE);
        }
        /* make the palette available */
        memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
    }
    /* FIXME how to correctly detect RLE ??? */
    if (avctx->height * istride == avpkt->size) { /* assume uncompressed */
        int linesize = av_image_get_linesize(avctx->pix_fmt, avctx->width, 0);
        uint8_t *ptr = s->frame->data[0];
        uint8_t *buf = avpkt->data + (avctx->height-1)*istride;
        int i, j;
        for (i = 0; i < avctx->height; i++) {
            if (avctx->bits_per_coded_sample == 4) {
                for (j = 0; j < avctx->width - 1; j += 2) {
                    ptr[j+0] = buf[j>>1] >> 4;
                    ptr[j+1] = buf[j>>1] & 0xF;
                }
                if (avctx->width & 1)
                    ptr[j+0] = buf[j>>1] >> 4;
            } else {
                memcpy(ptr, buf, linesize);
            }
            buf -= istride;
            ptr += s->frame->linesize[0];
        }
    } else {
        bytestream2_init(&s->gb, buf, buf_size);
        ff_msrle_decode(avctx, (AVPicture*)s->frame, avctx->bits_per_coded_sample, &s->gb);
    }
    if ((ret = av_frame_ref(data, s->frame)) < 0)
        return ret;
    *got_frame      = 1;
    /* report that the buffer was completely consumed */
    return buf_size;
}


static int doTest(uint8_t *ref[3], int refStride[3], int w, int h, int srcFormat, int dstFormat,

                  int srcW, int srcH, int dstW, int dstH, int flags){

    uint8_t *src[3];

    uint8_t *dst[3];

    uint8_t *out[3];

    int srcStride[3], dstStride[3];

    int i;

    uint64_t ssdY, ssdU, ssdV;

    struct SwsContext *srcContext, *dstContext, *outContext;

    int res;

    res = 0;

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

        // avoid stride % bpp != 0

        if (srcFormat==PIX_FMT_RGB24 || srcFormat==PIX_FMT_BGR24)

            srcStride[i]= srcW*3;

        else

            srcStride[i]= srcW*4;

        if (dstFormat==PIX_FMT_RGB24 || dstFormat==PIX_FMT_BGR24)

            dstStride[i]= dstW*3;

        else

            dstStride[i]= dstW*4;

        src[i]= (uint8_t*) malloc(srcStride[i]*srcH);

        dst[i]= (uint8_t*) malloc(dstStride[i]*dstH);

        out[i]= (uint8_t*) malloc(refStride[i]*h);

        if (!src[i] || !dst[i] || !out[i]) {

            perror("Malloc");

            res = -1;

            goto end;

        }

    }

    dstContext = outContext = NULL;

    srcContext= sws_getContext(w, h, PIX_FMT_YUV420P, srcW, srcH, srcFormat, flags, NULL, NULL, NULL);

    if (!srcContext) {

        fprintf(stderr, "Failed to get %s ---> %s\n",

                sws_format_name(PIX_FMT_YUV420P),

                sws_format_name(srcFormat));

        res = -1;

        goto end;

    }

    dstContext= sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, NULL, NULL, NULL);

    if (!dstContext) {

        fprintf(stderr, "Failed to get %s ---> %s\n",

                sws_format_name(srcFormat),

                sws_format_name(dstFormat));

        res = -1;

        goto end;

    }

    outContext= sws_getContext(dstW, dstH, dstFormat, w, h, PIX_FMT_YUV420P, flags, NULL, NULL, NULL);

    if (!outContext) {

        fprintf(stderr, "Failed to get %s ---> %s\n",

                sws_format_name(dstFormat),

                sws_format_name(PIX_FMT_YUV420P));

        res = -1;

        goto end;

    }

//    printf("test %X %X %X -> %X %X %X\n", (int)ref[0], (int)ref[1], (int)ref[2],

//        (int)src[0], (int)src[1], (int)src[2]);

    sws_scale(srcContext, ref, refStride, 0, h   , src, srcStride);

    sws_scale(dstContext, src, srcStride, 0, srcH, dst, dstStride);

    sws_scale(outContext, dst, dstStride, 0, dstH, out, refStride);

    ssdY= getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);

    ssdU= getSSD(ref[1], out[1], refStride[1], refStride[1], (w+1)>>1, (h+1)>>1);

    ssdV= getSSD(ref[2], out[2], refStride[2], refStride[2], (w+1)>>1, (h+1)>>1);

    if (srcFormat == PIX_FMT_GRAY8 || dstFormat==PIX_FMT_GRAY8) ssdU=ssdV=0; //FIXME check that output is really gray

    ssdY/= w*h;

    ssdU/= w*h/4;

    ssdV/= w*h/4;

    printf(" %s %dx%d -> %s %4dx%4d flags=%2d SSD=%5lld,%5lld,%5lld\n",

           sws_format_name(srcFormat), srcW, srcH,

           sws_format_name(dstFormat), dstW, dstH,

           flags, ssdY, ssdU, ssdV);

    fflush(stdout);

    end:

    sws_freeContext(srcContext);

    sws_freeContext(dstContext);

    sws_freeContext(outContext);

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

        free(src[i]);

        free(dst[i]);

        free(out[i]);

    }

    return res;

}


static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)

{

    int ret;

    struct addrinfo *res;

    char port_str[16];

    struct rdma_cm_event *cm_event;

    char ip[40] = "unknown";

    struct addrinfo *e;

    if (rdma->host == NULL || !strcmp(rdma->host, "")) {

        ERROR(errp, "RDMA hostname has not been set");

        return -1;

    }

    /* create CM channel */

    rdma->channel = rdma_create_event_channel();

    if (!rdma->channel) {

        ERROR(errp, "could not create CM channel");

        return -1;

    }

    /* create CM id */

    ret = rdma_create_id(rdma->channel, &rdma->cm_id, NULL, RDMA_PS_TCP);

    if (ret) {

        ERROR(errp, "could not create channel id");

        goto err_resolve_create_id;

    }

    snprintf(port_str, 16, "%d", rdma->port);

    port_str[15] = '\0';

    ret = getaddrinfo(rdma->host, port_str, NULL, &res);

    if (ret < 0) {

        ERROR(errp, "could not getaddrinfo address %s", rdma->host);

        goto err_resolve_get_addr;

    }

    for (e = res; e != NULL; e = e->ai_next) {

        inet_ntop(e->ai_family,

            &((struct sockaddr_in *) e->ai_addr)->sin_addr, ip, sizeof ip);

        DPRINTF("Trying %s => %s\n", rdma->host, ip);

        /* resolve the first address */

        ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_addr,

                RDMA_RESOLVE_TIMEOUT_MS);

        if (!ret) {

            goto route;

        }

    }

    ERROR(errp, "could not resolve address %s", rdma->host);

    goto err_resolve_get_addr;

route:

    qemu_rdma_dump_gid("source_resolve_addr", rdma->cm_id);

    ret = rdma_get_cm_event(rdma->channel, &cm_event);

    if (ret) {

        ERROR(errp, "could not perform event_addr_resolved");

        goto err_resolve_get_addr;

    }

    if (cm_event->event != RDMA_CM_EVENT_ADDR_RESOLVED) {

        ERROR(errp, "result not equal to event_addr_resolved %s",

                rdma_event_str(cm_event->event));

        perror("rdma_resolve_addr");

        goto err_resolve_get_addr;

    }

    rdma_ack_cm_event(cm_event);

    /* resolve route */

    ret = rdma_resolve_route(rdma->cm_id, RDMA_RESOLVE_TIMEOUT_MS);

    if (ret) {

        ERROR(errp, "could not resolve rdma route");

        goto err_resolve_get_addr;

    }

    ret = rdma_get_cm_event(rdma->channel, &cm_event);

    if (ret) {

        ERROR(errp, "could not perform event_route_resolved");

        goto err_resolve_get_addr;

    }

    if (cm_event->event != RDMA_CM_EVENT_ROUTE_RESOLVED) {

        ERROR(errp, "result not equal to event_route_resolved: %s",

                        rdma_event_str(cm_event->event));

        rdma_ack_cm_event(cm_event);

        goto err_resolve_get_addr;

    }

    rdma_ack_cm_event(cm_event);

    rdma->verbs = rdma->cm_id->verbs;

    qemu_rdma_dump_id("source_resolve_host", rdma->cm_id->verbs);

    qemu_rdma_dump_gid("source_resolve_host", rdma->cm_id);

    return 0;

err_resolve_get_addr:

    rdma_destroy_id(rdma->cm_id);

    rdma->cm_id = NULL;

err_resolve_create_id:

    rdma_destroy_event_channel(rdma->channel);

    rdma->channel = NULL;

    return -1;

}


static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,

                                                const char *model,

                                                const char *name,

                                                int fd, int is_connected,

                                                const char *mcast,

                                                Error **errp)

{

    struct sockaddr_in saddr;

    int newfd;

    NetClientState *nc;

    NetSocketState *s;

    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it

     * Because this may be "shared" socket from a "master" process, datagrams would be recv()

     * by ONLY ONE process: we must "clone" this dgram socket --jjo

     */

    if (is_connected && mcast != NULL) {

            if (parse_host_port(&saddr, mcast, errp) < 0) {

                goto err;

            }

            /* must be bound */

            if (saddr.sin_addr.s_addr == 0) {

                error_setg(errp, "can't setup multicast destination address");

                goto err;

            }

            /* clone dgram socket */

            newfd = net_socket_mcast_create(&saddr, NULL, errp);

            if (newfd < 0) {

                goto err;

            }

            /* clone newfd to fd, close newfd */

            dup2(newfd, fd);

            close(newfd);

    }

    nc = qemu_new_net_client(&net_dgram_socket_info, peer, model, name);

    s = DO_UPCAST(NetSocketState, nc, nc);

    s->fd = fd;

    s->listen_fd = -1;

    s->send_fn = net_socket_send_dgram;

    net_socket_rs_init(&s->rs, net_socket_rs_finalize, false);

    net_socket_read_poll(s, true);

    /* mcast: save bound address as dst */

    if (is_connected) {

        s->dgram_dst = saddr;

        snprintf(nc->info_str, sizeof(nc->info_str),

                 "socket: fd=%d (cloned mcast=%s:%d)",

                 fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

    } else {

        snprintf(nc->info_str, sizeof(nc->info_str),

                 "socket: fd=%d", fd);

    }

    return s;

err:

    closesocket(fd);

    return NULL;

}


static void FUNCC(pred4x4_horizontal)(uint8_t *_src, const uint8_t *topright, int _stride){

    pixel *src = (pixel*)_src;

    int stride = _stride/sizeof(pixel);

    ((pixel4*)(src+0*stride))[0]= PIXEL_SPLAT_X4(src[-1+0*stride]);

    ((pixel4*)(src+1*stride))[0]= PIXEL_SPLAT_X4(src[-1+1*stride]);

    ((pixel4*)(src+2*stride))[0]= PIXEL_SPLAT_X4(src[-1+2*stride]);

    ((pixel4*)(src+3*stride))[0]= PIXEL_SPLAT_X4(src[-1+3*stride]);

}


static void ehci_trace_itd(EHCIState *s, target_phys_addr_t addr, EHCIitd *itd)

{

    trace_usb_ehci_itd(addr, itd->next);

}


AVCodecParserContext *av_parser_init(int codec_id)

{

    AVCodecParserContext *s;

    AVCodecParser *parser;

    int ret;

    if(codec_id == CODEC_ID_NONE)

        return NULL;

    for(parser = av_first_parser; parser != NULL; parser = parser->next) {

        if (parser->codec_ids[0] == codec_id ||

            parser->codec_ids[1] == codec_id ||

            parser->codec_ids[2] == codec_id ||

            parser->codec_ids[3] == codec_id ||

            parser->codec_ids[4] == codec_id)

            goto found;

    }

    return NULL;

 found:

    s = av_mallocz(sizeof(AVCodecParserContext));

    if (!s)

        return NULL;

    s->parser = parser;

    if (parser->priv_data_size) {

        s->priv_data = av_mallocz(parser->priv_data_size);

        if (!s->priv_data) {

            av_free(s);

            return NULL;

        }

    }

    if (parser->parser_init) {

        ret = parser->parser_init(s);

        if (ret != 0) {

            av_free(s->priv_data);

            av_free(s);

            return NULL;

        }

    }

    s->fetch_timestamp=1;

    s->pict_type = FF_I_TYPE;

    s->key_frame = -1;

    s->convergence_duration = 0;

    s->dts_sync_point       = INT_MIN;

    s->dts_ref_dts_delta    = INT_MIN;

    s->pts_dts_delta        = INT_MIN;

    return s;

}


int migrate_use_xbzrle(void)

{

    MigrationState *s;

    s = migrate_get_current();

    return s->enabled_capabilities[MIGRATION_CAPABILITY_XBZRLE];

}


static void xen_hvm_change_state_handler(void *opaque, int running,

                                         RunState rstate)

{

    if (running) {

        xen_main_loop_prepare((XenIOState *)opaque);

    }

}


static int parse_vlan(DeviceState *dev, Property *prop, const char *str)

{

    VLANState **ptr = qdev_get_prop_ptr(dev, prop);

    int id;

    if (sscanf(str, "%d", &id) != 1)

        return -EINVAL;

    *ptr = qemu_find_vlan(id, 1);

    if (*ptr == NULL)

        return -ENOENT;

    return 0;

}


static int qtrle_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    QtrleContext *s = avctx->priv_data;

    int header, start_line;

    int stream_ptr, height, row_ptr;

    int has_palette = 0;

    s->buf = buf;

    s->size = buf_size;

    s->frame.reference = 1;

    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |

                            FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;

    if (avctx->reget_buffer(avctx, &s->frame)) {

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

        return -1;

    }

    /* check if this frame is even supposed to change */

    if (s->size < 8)

        goto done;

    /* start after the chunk size */

    stream_ptr = 4;

    /* fetch the header */

    header = AV_RB16(&s->buf[stream_ptr]);

    stream_ptr += 2;

    /* if a header is present, fetch additional decoding parameters */

    if (header & 0x0008) {

        if(s->size < 14)

            goto done;

        start_line = AV_RB16(&s->buf[stream_ptr]);

        stream_ptr += 4;

        height = AV_RB16(&s->buf[stream_ptr]);

        stream_ptr += 4;

    } else {

        start_line = 0;

        height = s->avctx->height;

    }

    row_ptr = s->frame.linesize[0] * start_line;

    switch (avctx->bits_per_coded_sample) {

    case 1:

    case 33:

        qtrle_decode_1bpp(s, stream_ptr, row_ptr, height);

        break;

    case 2:

    case 34:

        qtrle_decode_2n4bpp(s, stream_ptr, row_ptr, height, 2);

        has_palette = 1;

        break;

    case 4:

    case 36:

        qtrle_decode_2n4bpp(s, stream_ptr, row_ptr, height, 4);

        has_palette = 1;

        break;

    case 8:

    case 40:

        qtrle_decode_8bpp(s, stream_ptr, row_ptr, height);

        has_palette = 1;

        break;

    case 16:

        qtrle_decode_16bpp(s, stream_ptr, row_ptr, height);

        break;

    case 24:

        qtrle_decode_24bpp(s, stream_ptr, row_ptr, height);

        break;

    case 32:

        qtrle_decode_32bpp(s, stream_ptr, row_ptr, height);

        break;

    default:

        av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",

            avctx->bits_per_coded_sample);

        break;

    }

    if(has_palette) {

        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

        if (pal) {

            s->frame.palette_has_changed = 1;

            memcpy(s->pal, pal, AVPALETTE_SIZE);

        }

        /* make the palette available on the way out */

        memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);

    }

done:

    *data_size = sizeof(AVFrame);

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

    /* always report that the buffer was completely consumed */

    return buf_size;

}


static void cabac_init_decoder(HEVCContext *s)

{

    GetBitContext *gb = &s->HEVClc->gb;

    skip_bits(gb, 1);

    align_get_bits(gb);

    ff_init_cabac_decoder(&s->HEVClc->cc,

                          gb->buffer + get_bits_count(gb) / 8,

                          (get_bits_left(gb) + 7) / 8);

}


static void swap_sample_fmts_on_filter(AVFilterContext *filter)

{

    AVFilterLink *link = NULL;

    int format, bps;

    int i, j;

    for (i = 0; i < filter->nb_inputs; i++) {

        link = filter->inputs[i];

        if (link->type == AVMEDIA_TYPE_AUDIO &&

            link->out_formats->format_count == 1)

            break;

    }

    if (i == filter->nb_inputs)

        return;

    format = link->out_formats->formats[0];

    bps    = av_get_bytes_per_sample(format);

    for (i = 0; i < filter->nb_outputs; i++) {

        AVFilterLink *outlink = filter->outputs[i];

        int best_idx, best_score = INT_MIN;

        if (outlink->type != AVMEDIA_TYPE_AUDIO ||

            outlink->in_formats->format_count < 2)

            continue;

        for (j = 0; j < outlink->in_formats->format_count; j++) {

            int out_format = outlink->in_formats->formats[j];

            int out_bps    = av_get_bytes_per_sample(out_format);

            int score;

            if (av_get_packed_sample_fmt(out_format) == format ||

                av_get_planar_sample_fmt(out_format) == format) {

                best_idx   = j;

                break;

            }

            /* for s32 and float prefer double to prevent loss of information */

            if (bps == 4 && out_bps == 8) {

                best_idx = j;

                break;

            }

            /* prefer closest higher or equal bps */

            score = -abs(out_bps - bps);

            if (out_bps >= bps)

                score += INT_MAX/2;

            if (score > best_score) {

                best_score = score;

                best_idx   = j;

            }

        }

        FFSWAP(int, outlink->in_formats->formats[0],

               outlink->in_formats->formats[best_idx]);

    }

}


int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,

                           BlockDriverState *base, const char *backing_file_str)

{

    BlockDriverState *intermediate;

    BlockDriverState *base_bs = NULL;

    BlockDriverState *new_top_bs = NULL;

    BlkIntermediateStates *intermediate_state, *next;

    int ret = -EIO;

    QSIMPLEQ_HEAD(states_to_delete, BlkIntermediateStates) states_to_delete;

    QSIMPLEQ_INIT(&states_to_delete);

    if (!top->drv || !base->drv) {

        goto exit;

    }

    new_top_bs = bdrv_find_overlay(active, top);

    if (new_top_bs == NULL) {

        /* we could not find the image above 'top', this is an error */

        goto exit;

    }

    /* special case of new_top_bs->backing_hd already pointing to base - nothing

     * to do, no intermediate images */

    if (new_top_bs->backing_hd == base) {

        ret = 0;

        goto exit;

    }

    intermediate = top;

    /* now we will go down through the list, and add each BDS we find

     * into our deletion queue, until we hit the 'base'

     */

    while (intermediate) {

        intermediate_state = g_malloc0(sizeof(BlkIntermediateStates));

        intermediate_state->bs = intermediate;

        QSIMPLEQ_INSERT_TAIL(&states_to_delete, intermediate_state, entry);

        if (intermediate->backing_hd == base) {

            base_bs = intermediate->backing_hd;

            break;

        }

        intermediate = intermediate->backing_hd;

    }

    if (base_bs == NULL) {

        /* something went wrong, we did not end at the base. safely

         * unravel everything, and exit with error */

        goto exit;

    }

    /* success - we can delete the intermediate states, and link top->base */

    backing_file_str = backing_file_str ? backing_file_str : base_bs->filename;

    ret = bdrv_change_backing_file(new_top_bs, backing_file_str,

                                   base_bs->drv ? base_bs->drv->format_name : "");

    if (ret) {

        goto exit;

    }

    bdrv_set_backing_hd(new_top_bs, base_bs);

    QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) {

        /* so that bdrv_close() does not recursively close the chain */

        bdrv_set_backing_hd(intermediate_state->bs, NULL);

        bdrv_unref(intermediate_state->bs);

    }

    ret = 0;

exit:

    QSIMPLEQ_FOREACH_SAFE(intermediate_state, &states_to_delete, entry, next) {

        g_free(intermediate_state);

    }

    return ret;

}


static int smacker_decode_bigtree(BitstreamContext *bc, HuffContext *hc,

                                  DBCtx *ctx)

{

    if (hc->current + 1 >= hc->length) {

        av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n");

        return AVERROR_INVALIDDATA;

    }

    if (!bitstream_read_bit(bc)) { // Leaf

        int val, i1, i2;

        i1 = ctx->v1->table ? bitstream_read_vlc(bc, ctx->v1->table, SMKTREE_BITS, 3) : 0;

        i2 = ctx->v2->table ? bitstream_read_vlc(bc, ctx->v2->table, SMKTREE_BITS, 3) : 0;

        if (i1 < 0 || i2 < 0)

            return AVERROR_INVALIDDATA;

        val = ctx->recode1[i1] | (ctx->recode2[i2] << 8);

        if(val == ctx->escapes[0]) {

            ctx->last[0] = hc->current;

            val = 0;

        } else if(val == ctx->escapes[1]) {

            ctx->last[1] = hc->current;

            val = 0;

        } else if(val == ctx->escapes[2]) {

            ctx->last[2] = hc->current;

            val = 0;

        }

        hc->values[hc->current++] = val;

        return 1;

    } else { //Node

        int r = 0, r_new, t;

        t = hc->current++;

        r = smacker_decode_bigtree(bc, hc, ctx);

        if(r < 0)

            return r;

        hc->values[t] = SMK_NODE | r;

        r++;

        r_new = smacker_decode_bigtree(bc, hc, ctx);

        if (r_new < 0)

            return r_new;

        return r + r_new;

    }

}


static av_cold int qtrle_encode_end(AVCodecContext *avctx)

{

    QtrleEncContext *s = avctx->priv_data;

    av_frame_free(&avctx->coded_frame);

    avpicture_free(&s->previous_frame);

    av_free(s->rlecode_table);

    av_free(s->length_table);

    av_free(s->skip_table);

    return 0;

}


static av_cold int pcx_encode_init(AVCodecContext *avctx)

{

    avctx->coded_frame = av_frame_alloc();

    if (!avctx->coded_frame)

        return AVERROR(ENOMEM);

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    return 0;

}


static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,

                          IVITile *tile, AVCodecContext *avctx)

{

    int         x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb,

                mv_scale, mb_type_bits;

    IVIMbInfo   *mb, *ref_mb;

    int         row_offset = band->mb_size * band->pitch;

    mb     = tile->mbs;

    ref_mb = tile->ref_mbs;

    offs   = tile->ypos * band->pitch + tile->xpos;

    blks_per_mb  = band->mb_size   != band->blk_size  ? 4 : 1;

    mb_type_bits = ctx->frame_type == FRAMETYPE_BIDIR ? 2 : 1;

    /* scale factor for motion vectors */

    mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);

    mv_x = mv_y = 0;

    for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) {

        mb_offset = offs;

        for (x = tile->xpos; x < tile->xpos + tile->width; x += band->mb_size) {

            mb->xpos     = x;

            mb->ypos     = y;

            mb->buf_offs = mb_offset;

            if (get_bits1(&ctx->gb)) {

                if (ctx->frame_type == FRAMETYPE_INTRA) {

                    av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n");

                    return AVERROR_INVALIDDATA;

                }

                mb->type = 1; /* empty macroblocks are always INTER */

                mb->cbp  = 0; /* all blocks are empty */

                mb->q_delta = 0;

                if (!band->plane && !band->band_num && ctx->in_q) {

                    mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                           IVI_VLC_BITS, 1);

                    mb->q_delta = IVI_TOSIGNED(mb->q_delta);

                }

                mb->mv_x = mb->mv_y = 0; /* no motion vector coded */

                if (band->inherit_mv) {

                    /* motion vector inheritance */

                    if (mv_scale) {

                        mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);

                        mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);

                    } else {

                        mb->mv_x = ref_mb->mv_x;

                        mb->mv_y = ref_mb->mv_y;

                    }

                }

            } else {

                if (band->inherit_mv) {

                    mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */

                } else if (ctx->frame_type == FRAMETYPE_INTRA) {

                    mb->type = 0; /* mb_type is always INTRA for intra-frames */

                } else {

                    mb->type = get_bits(&ctx->gb, mb_type_bits);

                }

                mb->cbp = get_bits(&ctx->gb, blks_per_mb);

                mb->q_delta = 0;

                if (band->inherit_qdelta) {

                    if (ref_mb) mb->q_delta = ref_mb->q_delta;

                } else if (mb->cbp || (!band->plane && !band->band_num &&

                           ctx->in_q)) {

                    mb->q_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                           IVI_VLC_BITS, 1);

                    mb->q_delta = IVI_TOSIGNED(mb->q_delta);

                }

                if (!mb->type) {

                    mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */

                } else {

                    if (band->inherit_mv) {

                        /* motion vector inheritance */

                        if (mv_scale) {

                            mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale);

                            mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale);

                        } else {

                            mb->mv_x = ref_mb->mv_x;

                            mb->mv_y = ref_mb->mv_y;

                        }

                    } else {

                        /* decode motion vector deltas */

                        mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                            IVI_VLC_BITS, 1);

                        mv_y += IVI_TOSIGNED(mv_delta);

                        mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table,

                                            IVI_VLC_BITS, 1);

                        mv_x += IVI_TOSIGNED(mv_delta);

                        mb->mv_x = mv_x;

                        mb->mv_y = mv_y;

                    }

                }

            }

            mb++;

            if (ref_mb)

                ref_mb++;

            mb_offset += band->mb_size;

        }

        offs += row_offset;

    }

    align_get_bits(&ctx->gb);

    return 0;

}


static void hevc_parser_close(AVCodecParserContext *s)

{

    HEVCParserContext *ctx = s->priv_data;

    int i;

#if ADVANCED_PARSER

    HEVCContext  *h  = &ctx->h;

    for (i = 0; i < FF_ARRAY_ELEMS(h->ps.vps_list); i++)

        av_buffer_unref(&h->ps.vps_list[i]);

    for (i = 0; i < FF_ARRAY_ELEMS(h->ps.sps_list); i++)

        av_buffer_unref(&h->ps.sps_list[i]);

    for (i = 0; i < FF_ARRAY_ELEMS(h->ps.pps_list); i++)

        av_buffer_unref(&h->ps.pps_list[i]);

    h->ps.sps = NULL;

    av_freep(&h->HEVClc);

#endif

    for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.vps_list); i++)

        av_buffer_unref(&ctx->ps.vps_list[i]);

    for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.sps_list); i++)

        av_buffer_unref(&ctx->ps.sps_list[i]);

    for (i = 0; i < FF_ARRAY_ELEMS(ctx->ps.pps_list); i++)

        av_buffer_unref(&ctx->ps.pps_list[i]);

    ctx->ps.sps = NULL;

    ff_h2645_packet_uninit(&ctx->pkt);

    av_freep(&ctx->pc.buffer);

}


static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt)

{

    MvContext *mv = avctx->priv_data;

    AVIOContext *pb = avctx->pb;

    AVStream *st = avctx->streams[mv->stream_index];

    const AVIndexEntry *index;

    int frame = mv->frame[mv->stream_index];

    int ret;

    uint64_t pos;

    if (frame < st->nb_index_entries) {

        index = &st->index_entries[frame];

        pos   = avio_tell(pb);

        if (index->pos > pos)

            avio_skip(pb, index->pos - pos);

        else if (index->pos < pos) {

            if (!pb->seekable)

                return AVERROR(EIO);

            ret = avio_seek(pb, index->pos, SEEK_SET);

            if (ret < 0)

                return ret;

        }

        ret = av_get_packet(pb, pkt, index->size);

        if (ret < 0)

            return ret;

        pkt->stream_index = mv->stream_index;

        pkt->pts          = index->timestamp;

        pkt->flags       |= AV_PKT_FLAG_KEY;

        mv->frame[mv->stream_index]++;

        mv->eof_count = 0;

    } else {

        mv->eof_count++;

        if (mv->eof_count >= avctx->nb_streams)

            return AVERROR_EOF;

        // avoid returning 0 without a packet

        return AVERROR(EAGAIN);

    }

    mv->stream_index++;

    if (mv->stream_index >= avctx->nb_streams)

        mv->stream_index = 0;

    return 0;

}


static av_cold int prores_encode_close(AVCodecContext *avctx)

{

    ProresContext* ctx = avctx->priv_data;

    av_freep(&avctx->coded_frame);

    av_free(ctx->fill_y);

    av_free(ctx->fill_u);

    av_free(ctx->fill_v);

    return 0;

}


int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd,

                              AVIOContext *avio)

{

    int len, need_keyframe, missing_packets;

    AVIOContext *pb;

    uint8_t *buf;

    int64_t now;

    uint16_t first_missing, missing_mask;

    if (!fd && !avio)

        return -1;

    need_keyframe = s->handler && s->handler->need_keyframe &&

                    s->handler->need_keyframe(s->dynamic_protocol_context);

    missing_packets = find_missing_packets(s, &first_missing, &missing_mask);

    if (!need_keyframe && !missing_packets)

        return 0;

    /* Send new feedback if enough time has elapsed since the last

     * feedback packet. */

    now = av_gettime();

    if (s->last_feedback_time &&

        (now - s->last_feedback_time) < MIN_FEEDBACK_INTERVAL)

        return 0;

    s->last_feedback_time = now;

    if (!fd)

        pb = avio;

    else if (avio_open_dyn_buf(&pb) < 0)

        return -1;

    if (need_keyframe) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); /* PLI */

        avio_w8(pb, RTCP_PSFB);

        avio_wb16(pb, 2); /* length in words - 1 */

        // our own SSRC: we use the server's SSRC + 1 to avoid conflicts

        avio_wb32(pb, s->ssrc + 1);

        avio_wb32(pb, s->ssrc); // server SSRC

    }

    if (missing_packets) {

        avio_w8(pb, (RTP_VERSION << 6) | 1); /* NACK */

        avio_w8(pb, RTCP_RTPFB);

        avio_wb16(pb, 3); /* length in words - 1 */

        avio_wb32(pb, s->ssrc + 1);

        avio_wb32(pb, s->ssrc); // server SSRC

        avio_wb16(pb, first_missing);

        avio_wb16(pb, missing_mask);

    }

    avio_flush(pb);

    if (!fd)

        return 0;

    len = avio_close_dyn_buf(pb, &buf);

    if (len > 0 && buf) {

        ffurl_write(fd, buf, len);

        av_free(buf);

    }

    return 0;

}


static struct pathelem *add_entry(struct pathelem *root, const char *name)

{

    root->num_entries++;

    root = realloc(root, sizeof(*root)

                   + sizeof(root->entries[0])*root->num_entries);

    root->entries[root->num_entries-1] = new_entry(root->pathname, root, name);

    root->entries[root->num_entries-1]

        = add_dir_maybe(root->entries[root->num_entries-1]);

    return root;

}


yuv2rgb_2_c_template(SwsContext *c, const int16_t *buf[2],
                     const int16_t *ubuf[2], const int16_t *vbuf[2],
                     const int16_t *abuf[2], uint8_t *dest, int dstW,
                     int yalpha, int uvalpha, int y,
                     enum PixelFormat target, int hasAlpha)
{
    const int16_t *buf0  = buf[0],  *buf1  = buf[1],
                  *ubuf0 = ubuf[0], *ubuf1 = ubuf[1],
                  *vbuf0 = vbuf[0], *vbuf1 = vbuf[1],
                  *abuf0 = hasAlpha ? abuf[0] : NULL,
                  *abuf1 = hasAlpha ? abuf[1] : NULL;
    int  yalpha1 = 4095 - yalpha;
    int uvalpha1 = 4095 - uvalpha;
    int i;
    for (i = 0; i < (dstW >> 1); i++) {
        int Y1 = (buf0[i * 2]     * yalpha1  + buf1[i * 2]     * yalpha)  >> 19;
        int Y2 = (buf0[i * 2 + 1] * yalpha1  + buf1[i * 2 + 1] * yalpha)  >> 19;
        int U  = (ubuf0[i]        * uvalpha1 + ubuf1[i]        * uvalpha) >> 19;
        int V  = (vbuf0[i]        * uvalpha1 + vbuf1[i]        * uvalpha) >> 19;
        int A1, A2;
        const void *r =  c->table_rV[V],
                   *g = (c->table_gU[U] + c->table_gV[V]),
                   *b =  c->table_bU[U];
        if (hasAlpha) {
            A1 = (abuf0[i * 2    ] * yalpha1 + abuf1[i * 2    ] * yalpha) >> 19;
            A2 = (abuf0[i * 2 + 1] * yalpha1 + abuf1[i * 2 + 1] * yalpha) >> 19;
        }
        yuv2rgb_write(dest, i, Y1, Y2, hasAlpha ? A1 : 0, hasAlpha ? A2 : 0,
                      r, g, b, y, target, hasAlpha);
    }
}


static void nbd_recv_coroutines_enter_all(NbdClientSession *s)

{

    int i;

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

        if (s->recv_coroutine[i]) {

            qemu_coroutine_enter(s->recv_coroutine[i], NULL);

        }

    }

}


static void dequantization_int(int x, int y, Jpeg2000Cblk *cblk,

                               Jpeg2000Component *comp,

                               Jpeg2000T1Context *t1, Jpeg2000Band *band)

{

    int i, j, idx;

    int32_t *datap =

        (int32_t *) &comp->data[(comp->coord[0][1] - comp->coord[0][0]) * y + x];

    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j)

        for (i = 0; i < (cblk->coord[0][1] - cblk->coord[0][0]); ++i) {

            idx        = (comp->coord[0][1] - comp->coord[0][0]) * j + i;

            datap[idx] =

                ((int32_t)(t1->data[j][i]) * band->i_stepsize + (1 << 15)) >> 16;

        }

}


static void ehci_queues_rip_device(EHCIState *ehci, USBDevice *dev)

{

    EHCIQueue *q, *tmp;

    QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {

        if (q->packet.owner == NULL ||

            q->packet.owner->dev != dev) {

            continue;

        }

        ehci_free_queue(q);

    }

}


static int vfio_add_std_cap(VFIODevice *vdev, uint8_t pos)

{

    PCIDevice *pdev = &vdev->pdev;

    uint8_t cap_id, next, size;

    int ret;

    cap_id = pdev->config[pos];

    next = pdev->config[pos + 1];

    /*

     * If it becomes important to configure capabilities to their actual

     * size, use this as the default when it's something we don't recognize.

     * Since QEMU doesn't actually handle many of the config accesses,

     * exact size doesn't seem worthwhile.

     */

    size = vfio_std_cap_max_size(pdev, pos);

    /*

     * pci_add_capability always inserts the new capability at the head

     * of the chain.  Therefore to end up with a chain that matches the

     * physical device, we insert from the end by making this recursive.

     * This is also why we pre-caclulate size above as cached config space

     * will be changed as we unwind the stack.

     */

    if (next) {

        ret = vfio_add_std_cap(vdev, next);

        if (ret) {

            return ret;

        }

    } else {

        pdev->config[PCI_CAPABILITY_LIST] = 0; /* Begin the rebuild */

    }

    switch (cap_id) {

    case PCI_CAP_ID_MSI:

        ret = vfio_setup_msi(vdev, pos);

        break;

    case PCI_CAP_ID_MSIX:

        ret = vfio_setup_msix(vdev, pos);

        break;

    default:

        ret = pci_add_capability(pdev, cap_id, pos, size);

        break;

    }

    if (ret < 0) {

        error_report("vfio: %04x:%02x:%02x.%x Error adding PCI capability "

                     "0x%x[0x%x]@0x%x: %d", vdev->host.domain,

                     vdev->host.bus, vdev->host.slot, vdev->host.function,

                     cap_id, size, pos, ret);

        return ret;

    }

    return 0;

}


void ff_xvmc_decode_mb(MpegEncContext *s)

{

    XvMCMacroBlock *mv_block;

    struct xvmc_pix_fmt *render;

    int i, cbp, blocks_per_mb;

    const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;

    if (s->encoding) {

        av_log(s->avctx, AV_LOG_ERROR, "XVMC doesn't support encoding!!!\n");

        return;

    }

    // from ff_mpv_decode_mb(), update DC predictors for P macroblocks

    if (!s->mb_intra) {

        s->last_dc[0] =

        s->last_dc[1] =

        s->last_dc[2] =  128 << s->intra_dc_precision;

    }

    // MC doesn't skip blocks

    s->mb_skipped = 0;

    // Do I need to export quant when I could not perform postprocessing?

    // Anyway, it doesn't hurt.

    s->current_picture.qscale_table[mb_xy] = s->qscale;

    // start of XVMC-specific code

    render = (struct xvmc_pix_fmt*)s->current_picture.f->data[2];

    assert(render);

    assert(render->xvmc_id == AV_XVMC_ID);

    assert(render->mv_blocks);

    // take the next free macroblock

    mv_block = &render->mv_blocks[render->start_mv_blocks_num +

                                  render->filled_mv_blocks_num];

    mv_block->x        = s->mb_x;

    mv_block->y        = s->mb_y;

    mv_block->dct_type = s->interlaced_dct; // XVMC_DCT_TYPE_FRAME/FIELD;

    if (s->mb_intra) {

        mv_block->macroblock_type = XVMC_MB_TYPE_INTRA; // no MC, all done

    } else {

        mv_block->macroblock_type = XVMC_MB_TYPE_PATTERN;

        if (s->mv_dir & MV_DIR_FORWARD) {

            mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD;

            // PMV[n][dir][xy] = mv[dir][n][xy]

            mv_block->PMV[0][0][0] = s->mv[0][0][0];

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

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

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

        }

        if (s->mv_dir & MV_DIR_BACKWARD) {

            mv_block->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD;

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

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

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

            mv_block->PMV[1][1][1] = s->mv[1][1][1];

        }

        switch(s->mv_type) {

            case  MV_TYPE_16X16:

                mv_block->motion_type = XVMC_PREDICTION_FRAME;

                break;

            case  MV_TYPE_16X8:

                mv_block->motion_type = XVMC_PREDICTION_16x8;

                break;

            case  MV_TYPE_FIELD:

                mv_block->motion_type = XVMC_PREDICTION_FIELD;

                if (s->picture_structure == PICT_FRAME) {

                    mv_block->PMV[0][0][1] <<= 1;

                    mv_block->PMV[1][0][1] <<= 1;

                    mv_block->PMV[0][1][1] <<= 1;

                    mv_block->PMV[1][1][1] <<= 1;

                }

                break;

            case  MV_TYPE_DMV:

                mv_block->motion_type = XVMC_PREDICTION_DUAL_PRIME;

                if (s->picture_structure == PICT_FRAME) {

                    mv_block->PMV[0][0][0] = s->mv[0][0][0];      // top from top

                    mv_block->PMV[0][0][1] = s->mv[0][0][1] << 1;

                    mv_block->PMV[0][1][0] = s->mv[0][0][0];      // bottom from bottom

                    mv_block->PMV[0][1][1] = s->mv[0][0][1] << 1;

                    mv_block->PMV[1][0][0] = s->mv[0][2][0];      // dmv00, top from bottom

                    mv_block->PMV[1][0][1] = s->mv[0][2][1] << 1; // dmv01

                    mv_block->PMV[1][1][0] = s->mv[0][3][0];      // dmv10, bottom from top

                    mv_block->PMV[1][1][1] = s->mv[0][3][1] << 1; // dmv11

                } else {

                    mv_block->PMV[0][1][0] = s->mv[0][2][0];      // dmv00

                    mv_block->PMV[0][1][1] = s->mv[0][2][1];      // dmv01

                }

                break;

            default:

                assert(0);

        }

        mv_block->motion_vertical_field_select = 0;

        // set correct field references

        if (s->mv_type == MV_TYPE_FIELD || s->mv_type == MV_TYPE_16X8) {

            mv_block->motion_vertical_field_select |= s->field_select[0][0];

            mv_block->motion_vertical_field_select |= s->field_select[1][0] << 1;

            mv_block->motion_vertical_field_select |= s->field_select[0][1] << 2;

            mv_block->motion_vertical_field_select |= s->field_select[1][1] << 3;

        }

    } // !intra

    // time to handle data blocks

    mv_block->index = render->next_free_data_block_num;

    blocks_per_mb = 6;

    if (s->chroma_format >= 2) {

        blocks_per_mb = 4 + (1 << s->chroma_format);

    }

    // calculate cbp

    cbp = 0;

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

        cbp += cbp;

        if (s->block_last_index[i] >= 0)

            cbp++;

    }

    if (s->avctx->flags & AV_CODEC_FLAG_GRAY) {

        if (s->mb_intra) {                                   // intra frames are always full chroma blocks

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

                memset(s->pblocks[i], 0, sizeof(*s->pblocks[i]));  // so we need to clear them

                if (!render->unsigned_intra)

                    *s->pblocks[i][0] = 1 << 10;

            }

        } else {

            cbp &= 0xf << (blocks_per_mb - 4);

            blocks_per_mb = 4;                               // luminance blocks only

        }

    }

    mv_block->coded_block_pattern = cbp;

    if (cbp == 0)

        mv_block->macroblock_type &= ~XVMC_MB_TYPE_PATTERN;

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

        if (s->block_last_index[i] >= 0) {

            // I do not have unsigned_intra MOCO to test, hope it is OK.

            if (s->mb_intra && (render->idct || !render->unsigned_intra))

                *s->pblocks[i][0] -= 1 << 10;

            if (!render->idct) {

                s->idsp.idct(*s->pblocks[i]);

                /* It is unclear if MC hardware requires pixel diff values to be

                 * in the range [-255;255]. TODO: Clipping if such hardware is

                 * ever found. As of now it would only be an unnecessary

                 * slowdown. */

            }

            // copy blocks only if the codec doesn't support pblocks reordering

            if (s->avctx->xvmc_acceleration == 1) {

                memcpy(&render->data_blocks[render->next_free_data_block_num*64],

                       s->pblocks[i], sizeof(*s->pblocks[i]));

            }

            render->next_free_data_block_num++;

        }

    }

    render->filled_mv_blocks_num++;

    assert(render->filled_mv_blocks_num     <= render->allocated_mv_blocks);

    assert(render->next_free_data_block_num <= render->allocated_data_blocks);

    /* The above conditions should not be able to fail as long as this function

     * is used and the following 'if ()' automatically calls a callback to free

     * blocks. */

    if (render->filled_mv_blocks_num == render->allocated_mv_blocks)

        ff_mpeg_draw_horiz_band(s, 0, 0);

}


static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)

{

    MOVStreamContext *sc;

    int i, edit_count, version;

    if (c->fc->nb_streams < 1 || c->ignore_editlist)

        return 0;

    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;

    version = avio_r8(pb); /* version */

    avio_rb24(pb); /* flags */

    edit_count = avio_rb32(pb); /* entries */

    if (!edit_count)

        return 0;

    if (sc->elst_data)

        av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");

    av_free(sc->elst_data);

    sc->elst_count = 0;

    sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));

    if (!sc->elst_data)

        return AVERROR(ENOMEM);

    av_log(c->fc, AV_LOG_TRACE, "track[%u].edit_count = %i\n", c->fc->nb_streams - 1, edit_count);

    for (i = 0; i < edit_count && !pb->eof_reached; i++) {

        MOVElst *e = &sc->elst_data[i];

        if (version == 1) {

            e->duration = avio_rb64(pb);

            e->time     = avio_rb64(pb);

        } else {

            e->duration = avio_rb32(pb); /* segment duration */

            e->time     = (int32_t)avio_rb32(pb); /* media time */

        }

        e->rate = avio_rb32(pb) / 65536.0;

        av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",

               e->duration, e->time, e->rate);

        if (e->time < 0 && e->time != -1 &&

            c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) {

            av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list media time=%"PRId64"\n",

                   c->fc->nb_streams-1, i, e->time);

            return AVERROR_INVALIDDATA;

        }

    }

    sc->elst_count = i;

    return 0;

}


static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,

                        AVPacket *avpkt)

{

    KmvcContext *const ctx = avctx->priv_data;

    AVFrame *frame = data;

    uint8_t *out, *src;

    int i, ret;

    int header;

    int blocksize;

    const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);

    bytestream2_init(&ctx->g, avpkt->data, avpkt->size);

    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)

        return ret;

    header = bytestream2_get_byte(&ctx->g);

    /* blocksize 127 is really palette change event */

    if (bytestream2_peek_byte(&ctx->g) == 127) {

        bytestream2_skip(&ctx->g, 3);

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

            ctx->pal[i + (header & 0x81)] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);

            bytestream2_skip(&ctx->g, 1);

        }

        bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR);

    }

    if (header & KMVC_KEYFRAME) {

        frame->key_frame = 1;

        frame->pict_type = AV_PICTURE_TYPE_I;

    } else {

        frame->key_frame = 0;

        frame->pict_type = AV_PICTURE_TYPE_P;

    }

    if (header & KMVC_PALETTE) {

        frame->palette_has_changed = 1;

        // palette starts from index 1 and has 127 entries

        for (i = 1; i <= ctx->palsize; i++) {

            ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);

        }

    }

    if (pal) {

        frame->palette_has_changed = 1;

        memcpy(ctx->pal, pal, AVPALETTE_SIZE);

    }

    if (ctx->setpal) {

        ctx->setpal = 0;

        frame->palette_has_changed = 1;

    }

    /* make the palette available on the way out */

    memcpy(frame->data[1], ctx->pal, 1024);

    blocksize = bytestream2_get_byte(&ctx->g);

    if (blocksize != 8 && blocksize != 127) {

        av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize);

        return AVERROR_INVALIDDATA;

    }

    memset(ctx->cur, 0, 320 * 200);

    switch (header & KMVC_METHOD) {

    case 0:

    case 1: // used in palette changed event

        memcpy(ctx->cur, ctx->prev, 320 * 200);

        break;

    case 3:

        kmvc_decode_intra_8x8(ctx, avctx->width, avctx->height);

        break;

    case 4:

        kmvc_decode_inter_8x8(ctx, avctx->width, avctx->height);

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);

        return AVERROR_INVALIDDATA;

    }

    out = frame->data[0];

    src = ctx->cur;

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

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

        src += 320;

        out += frame->linesize[0];

    }

    /* flip buffers */

    if (ctx->cur == ctx->frm0) {

        ctx->cur = ctx->frm1;

        ctx->prev = ctx->frm0;

    } else {

        ctx->cur = ctx->frm0;

        ctx->prev = ctx->frm1;

    }

    *got_frame = 1;

    /* always report that the buffer was completely consumed */

    return avpkt->size;

}


static int test_vector_fmul(AVFloatDSPContext *fdsp, AVFloatDSPContext *cdsp,

                            const float *v1, const float *v2)

{

    LOCAL_ALIGNED(32, float, cdst, [LEN]);

    LOCAL_ALIGNED(32, float, odst, [LEN]);

    int ret;

    cdsp->vector_fmul(cdst, v1, v2, LEN);

    fdsp->vector_fmul(odst, v1, v2, LEN);

    if (ret = compare_floats(cdst, odst, LEN, FLT_EPSILON))

        av_log(NULL, AV_LOG_ERROR, "vector_fmul failed\n");

    return ret;

}


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

                            int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size, n_slices = 0, i, ret;

    VC1Context *v = avctx->priv_data;

    MpegEncContext *s = &v->s;

    AVFrame *pict = data;

    uint8_t *buf2 = NULL;

    const uint8_t *buf_start = buf;

    int mb_height, n_slices1;

    struct {

        uint8_t *buf;

        GetBitContext gb;

        int mby_start;

    } *slices = NULL, *tmp;

    /* no supplementary picture */

    if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) {

        /* special case for last picture */

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

            if ((ret = av_frame_ref(pict, s->next_picture_ptr->f)) < 0)

                return ret;

            s->next_picture_ptr = NULL;

            *got_frame = 1;

        }

        return 0;

    }

    //for advanced profile we may need to parse and unescape data

    if (avctx->codec_id == AV_CODEC_ID_VC1 || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {

        int buf_size2 = 0;

        buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);

        if (IS_MARKER(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */

            const uint8_t *start, *end, *next;

            int size;

            next = buf;

            for (start = buf, end = buf + buf_size; next < end; start = next) {

                next = find_next_marker(start + 4, end);

                size = next - start - 4;

                if (size <= 0) continue;

                switch (AV_RB32(start)) {

                case VC1_CODE_FRAME:

                    if (avctx->hwaccel)

                        buf_start = start;

                    buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);

                    break;

                case VC1_CODE_FIELD: {

                    int buf_size3;

                    tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));

                    if (!tmp)

                        goto err;

                    slices = tmp;

                    slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);

                    if (!slices[n_slices].buf)

                        goto err;

                    buf_size3 = vc1_unescape_buffer(start + 4, size,

                                                    slices[n_slices].buf);

                    init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,

                                  buf_size3 << 3);

                    /* assuming that the field marker is at the exact middle,

                       hope it's correct */

                    slices[n_slices].mby_start = s->mb_height >> 1;

                    n_slices1 = n_slices - 1; // index of the last slice of the first field

                    n_slices++;

                    break;

                }

                case VC1_CODE_ENTRYPOINT: /* it should be before frame data */

                    buf_size2 = vc1_unescape_buffer(start + 4, size, buf2);

                    init_get_bits(&s->gb, buf2, buf_size2 * 8);

                    ff_vc1_decode_entry_point(avctx, v, &s->gb);

                    break;

                case VC1_CODE_SLICE: {

                    int buf_size3;

                    tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));

                    if (!tmp)

                        goto err;

                    slices = tmp;

                    slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);

                    if (!slices[n_slices].buf)

                        goto err;

                    buf_size3 = vc1_unescape_buffer(start + 4, size,

                                                    slices[n_slices].buf);

                    init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,

                                  buf_size3 << 3);

                    slices[n_slices].mby_start = get_bits(&slices[n_slices].gb, 9);

                    n_slices++;

                    break;

                }

                }

            }

        } else if (v->interlace && ((buf[0] & 0xC0) == 0xC0)) { /* WVC1 interlaced stores both fields divided by marker */

            const uint8_t *divider;

            int buf_size3;

            divider = find_next_marker(buf, buf + buf_size);

            if ((divider == (buf + buf_size)) || AV_RB32(divider) != VC1_CODE_FIELD) {

                av_log(avctx, AV_LOG_ERROR, "Error in WVC1 interlaced frame\n");

                goto err;

            } else { // found field marker, unescape second field

                tmp = av_realloc(slices, sizeof(*slices) * (n_slices+1));

                if (!tmp)

                    goto err;

                slices = tmp;

                slices[n_slices].buf = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);

                if (!slices[n_slices].buf)

                    goto err;

                buf_size3 = vc1_unescape_buffer(divider + 4, buf + buf_size - divider - 4, slices[n_slices].buf);

                init_get_bits(&slices[n_slices].gb, slices[n_slices].buf,

                              buf_size3 << 3);

                slices[n_slices].mby_start = s->mb_height >> 1;

                n_slices1 = n_slices - 1;

                n_slices++;

            }

            buf_size2 = vc1_unescape_buffer(buf, divider - buf, buf2);

        } else {

            buf_size2 = vc1_unescape_buffer(buf, buf_size, buf2);

        }

        init_get_bits(&s->gb, buf2, buf_size2*8);

    } else

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

    if (v->res_sprite) {

        v->new_sprite  = !get_bits1(&s->gb);

        v->two_sprites =  get_bits1(&s->gb);

        /* res_sprite means a Windows Media Image stream, AV_CODEC_ID_*IMAGE means

           we're using the sprite compositor. These are intentionally kept separate

           so you can get the raw sprites by using the wmv3 decoder for WMVP or

           the vc1 one for WVP2 */

        if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {

            if (v->new_sprite) {

                // switch AVCodecContext parameters to those of the sprites

                avctx->width  = avctx->coded_width  = v->sprite_width;

                avctx->height = avctx->coded_height = v->sprite_height;

            } else {

                goto image;

            }

        }

    }

    if (s->context_initialized &&

        (s->width  != avctx->coded_width ||

         s->height != avctx->coded_height)) {

        ff_vc1_decode_end(avctx);

    }

    if (!s->context_initialized) {

        if (ff_msmpeg4_decode_init(avctx) < 0)

            goto err;

        if (ff_vc1_decode_init_alloc_tables(v) < 0) {

            ff_mpv_common_end(s);

            goto err;

        }

        s->low_delay = !avctx->has_b_frames || v->res_sprite;

        if (v->profile == PROFILE_ADVANCED) {

            s->h_edge_pos = avctx->coded_width;

            s->v_edge_pos = avctx->coded_height;

        }

    }

    // do parse frame header

    v->pic_header_flag = 0;

    v->first_pic_header_flag = 1;

    if (v->profile < PROFILE_ADVANCED) {

        if (ff_vc1_parse_frame_header(v, &s->gb) < 0) {

            goto err;

        }

    } else {

        if (ff_vc1_parse_frame_header_adv(v, &s->gb) < 0) {

            goto err;

        }

    }

    v->first_pic_header_flag = 0;

    if ((avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE)

        && s->pict_type != AV_PICTURE_TYPE_I) {

        av_log(v->s.avctx, AV_LOG_ERROR, "Sprite decoder: expected I-frame\n");

        goto err;

    }

    // for skipping the frame

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

    s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;

    /* skip B-frames if we don't have reference frames */

    if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->droppable)) {

        goto end;

    }

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

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

         avctx->skip_frame >= AVDISCARD_ALL) {

        goto end;

    }

    if (s->next_p_frame_damaged) {

        if (s->pict_type == AV_PICTURE_TYPE_B)

            goto end;

        else

            s->next_p_frame_damaged = 0;

    }

    if (ff_mpv_frame_start(s, avctx) < 0) {

        goto err;

    }

    // process pulldown flags

    s->current_picture_ptr->f->repeat_pict = 0;

    // Pulldown flags are only valid when 'broadcast' has been set.

    // So ticks_per_frame will be 2

    if (v->rff) {

        // repeat field

        s->current_picture_ptr->f->repeat_pict = 1;

    } else if (v->rptfrm) {

        // repeat frames

        s->current_picture_ptr->f->repeat_pict = v->rptfrm * 2;

    }

    s->me.qpel_put = s->qdsp.put_qpel_pixels_tab;

    s->me.qpel_avg = s->qdsp.avg_qpel_pixels_tab;

    if (avctx->hwaccel) {

        if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)

            goto err;

        if (avctx->hwaccel->decode_slice(avctx, buf_start, (buf + buf_size) - buf_start) < 0)

            goto err;

        if (avctx->hwaccel->end_frame(avctx) < 0)

            goto err;

    } else {

        int header_ret = 0;

        ff_mpeg_er_frame_start(s);

        v->bits = buf_size * 8;

        v->end_mb_x = s->mb_width;

        if (v->field_mode) {

            s->current_picture.f->linesize[0] <<= 1;

            s->current_picture.f->linesize[1] <<= 1;

            s->current_picture.f->linesize[2] <<= 1;

            s->linesize                      <<= 1;

            s->uvlinesize                    <<= 1;

        }

        mb_height = s->mb_height >> v->field_mode;

        if (!mb_height) {

            av_log(v->s.avctx, AV_LOG_ERROR, "Invalid mb_height.\n");

            goto err;

        }

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

            if (i > 0 &&  slices[i - 1].mby_start >= mb_height) {

                if (v->field_mode <= 0) {

                    av_log(v->s.avctx, AV_LOG_ERROR, "Slice %d starts beyond "

                           "picture boundary (%d >= %d)\n", i,

                           slices[i - 1].mby_start, mb_height);

                    continue;

                }

                v->second_field = 1;

                v->blocks_off   = s->mb_width  * s->mb_height << 1;

                v->mb_off       = s->mb_stride * s->mb_height >> 1;

            } else {

                v->second_field = 0;

                v->blocks_off   = 0;

                v->mb_off       = 0;

            }

            if (i) {

                v->pic_header_flag = 0;

                if (v->field_mode && i == n_slices1 + 2) {

                    if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {

                        av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n");

                        if (avctx->err_recognition & AV_EF_EXPLODE)

                            goto err;

                        continue;

                    }

                } else if (get_bits1(&s->gb)) {

                    v->pic_header_flag = 1;

                    if ((header_ret = ff_vc1_parse_frame_header_adv(v, &s->gb)) < 0) {

                        av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n");

                        if (avctx->err_recognition & AV_EF_EXPLODE)

                            goto err;

                        continue;

                    }

                }

            }

            if (header_ret < 0)

                continue;

            s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height);

            if (!v->field_mode || v->second_field)

                s->end_mb_y = (i == n_slices     ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);

            else

                s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height);

            ff_vc1_decode_blocks(v);

            if (i != n_slices)

                s->gb = slices[i].gb;

        }

        if (v->field_mode) {

            v->second_field = 0;

            s->current_picture.f->linesize[0] >>= 1;

            s->current_picture.f->linesize[1] >>= 1;

            s->current_picture.f->linesize[2] >>= 1;

            s->linesize                      >>= 1;

            s->uvlinesize                    >>= 1;

            if (v->s.pict_type != AV_PICTURE_TYPE_BI && v->s.pict_type != AV_PICTURE_TYPE_B) {

                FFSWAP(uint8_t *, v->mv_f_next[0], v->mv_f[0]);

                FFSWAP(uint8_t *, v->mv_f_next[1], v->mv_f[1]);

            }

        }

        av_dlog(s->avctx, "Consumed %i/%i bits\n",

                get_bits_count(&s->gb), s->gb.size_in_bits);

//  if (get_bits_count(&s->gb) > buf_size * 8)

//      return -1;

        if (!v->field_mode)

            ff_er_frame_end(&s->er);

    }

    ff_mpv_frame_end(s);

    if (avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || avctx->codec_id == AV_CODEC_ID_VC1IMAGE) {

image:

        avctx->width  = avctx->coded_width  = v->output_width;

        avctx->height = avctx->coded_height = v->output_height;

        if (avctx->skip_frame >= AVDISCARD_NONREF)

            goto end;

#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER

        if (vc1_decode_sprites(v, &s->gb))

            goto err;

#endif

        if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0)

            goto err;

        *got_frame = 1;

    } else {

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

            if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)

                goto err;

            ff_print_debug_info(s, s->current_picture_ptr);

            *got_frame = 1;

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

            if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0)

                goto err;

            ff_print_debug_info(s, s->last_picture_ptr);

            *got_frame = 1;

        }

    }

end:

    av_free(buf2);

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

        av_free(slices[i].buf);

    av_free(slices);

    return buf_size;

err:

    av_free(buf2);

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

        av_free(slices[i].buf);

    av_free(slices);

    return -1;

}


static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m,

                                    int last_block, int bitexact)

{

    const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;

    unsigned int len;

    uint8_t *p, *p0;

    ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);

    len = ff_vorbiscomment_length(*m, vendor);

    p0 = av_malloc(len+4);

    if (!p0)

        return AVERROR(ENOMEM);

    p = p0;

    bytestream_put_byte(&p, last_block ? 0x84 : 0x04);

    bytestream_put_be24(&p, len);

    ff_vorbiscomment_write(&p, m, vendor);

    avio_write(pb, p0, len+4);

    av_freep(&p0);

    p = NULL;

    return 0;

}


static void modified_levinson_durbin(int *window, int window_entries,

        int *out, int out_entries, int channels, int *tap_quant)

{

    int i;

    int *state = av_calloc(window_entries, sizeof(*state));

    memcpy(state, window, 4* window_entries);

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

    {

        int step = (i+1)*channels, k, j;

        double xx = 0.0, xy = 0.0;

#if 1

        int *x_ptr = &(window[step]);

        int *state_ptr = &(state[0]);

        j = window_entries - step;

        for (;j>0;j--,x_ptr++,state_ptr++)

        {

            double x_value = *x_ptr;

            double state_value = *state_ptr;

            xx += state_value*state_value;

            xy += x_value*state_value;

        }

#else

        for (j = 0; j <= (window_entries - step); j++);

        {

            double stepval = window[step+j];

            double stateval = window[j];

//            xx += (double)window[j]*(double)window[j];

//            xy += (double)window[step+j]*(double)window[j];

            xx += stateval*stateval;

            xy += stepval*stateval;

        }

#endif

        if (xx == 0.0)

            k = 0;

        else

            k = (int)(floor(-xy/xx * (double)LATTICE_FACTOR / (double)(tap_quant[i]) + 0.5));

        if (k > (LATTICE_FACTOR/tap_quant[i]))

            k = LATTICE_FACTOR/tap_quant[i];

        if (-k > (LATTICE_FACTOR/tap_quant[i]))

            k = -(LATTICE_FACTOR/tap_quant[i]);

        out[i] = k;

        k *= tap_quant[i];

#if 1

        x_ptr = &(window[step]);

        state_ptr = &(state[0]);

        j = window_entries - step;

        for (;j>0;j--,x_ptr++,state_ptr++)

        {

            int x_value = *x_ptr;

            int state_value = *state_ptr;

            *x_ptr = x_value + shift_down(k*state_value,LATTICE_SHIFT);

            *state_ptr = state_value + shift_down(k*x_value, LATTICE_SHIFT);

        }

#else

        for (j=0; j <= (window_entries - step); j++)

        {

            int stepval = window[step+j];

            int stateval=state[j];

            window[step+j] += shift_down(k * stateval, LATTICE_SHIFT);

            state[j] += shift_down(k * stepval, LATTICE_SHIFT);

        }

#endif

    }

    av_free(state);

}


void av_url_split(char *proto, int proto_size,

                  char *authorization, int authorization_size,

                  char *hostname, int hostname_size,

                  int *port_ptr,

                  char *path, int path_size,

                  const char *url)

{

    const char *p, *ls, *ls2, *at, *col, *brk;

    if (port_ptr)               *port_ptr = -1;

    if (proto_size > 0)         proto[0] = 0;

    if (authorization_size > 0) authorization[0] = 0;

    if (hostname_size > 0)      hostname[0] = 0;

    if (path_size > 0)          path[0] = 0;

    /* parse protocol */

    if ((p = strchr(url, ':'))) {

        av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));

        p++; /* skip ':' */

        if (*p == '/') p++;

        if (*p == '/') p++;

    } else {

        /* no protocol means plain filename */

        av_strlcpy(path, url, path_size);

        return;

    }

    /* separate path from hostname */

    ls = strchr(p, '/');

    ls2 = strchr(p, '?');

    if(!ls)

        ls = ls2;

    else if (ls && ls2)

        ls = FFMIN(ls, ls2);

    if(ls)

        av_strlcpy(path, ls, path_size);

    else

        ls = &p[strlen(p)]; // XXX

    /* the rest is hostname, use that to parse auth/port */

    if (ls != p) {

        /* authorization (user[:pass]@hostname) */

        if ((at = strchr(p, '@')) && at < ls) {

            av_strlcpy(authorization, p,

                       FFMIN(authorization_size, at + 1 - p));

            p = at + 1; /* skip '@' */

        }

        if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {

            /* [host]:port */

            av_strlcpy(hostname, p + 1,

                       FFMIN(hostname_size, brk - p));

            if (brk[1] == ':' && port_ptr)

                *port_ptr = atoi(brk + 2);

        } else if ((col = strchr(p, ':')) && col < ls) {

            av_strlcpy(hostname, p,

                       FFMIN(col + 1 - p, hostname_size));

            if (port_ptr) *port_ptr = atoi(col + 1);

        } else

            av_strlcpy(hostname, p,

                       FFMIN(ls + 1 - p, hostname_size));

    }

}


static void ohci_bus_stop(OHCIState *ohci)

{

    trace_usb_ohci_stop(ohci->name);

    if (ohci->eof_timer) {

        timer_del(ohci->eof_timer);

        timer_free(ohci->eof_timer);

    }

    ohci->eof_timer = NULL;

}


static int avisynth_read_header(AVFormatContext *s)

{

  AVISynthContext *avs = s->priv_data;

  HRESULT res;

  AVIFILEINFO info;

  DWORD id;

  AVStream *st;

  AVISynthStream *stream;

  wchar_t filename_wchar[1024] = { 0 };

  char filename_char[1024] = { 0 };

  AVIFileInit();

  /* avisynth can't accept UTF-8 filename */

  MultiByteToWideChar(CP_UTF8, 0, s->filename, -1, filename_wchar, 1024);

  WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wchar, -1, filename_char, 1024, NULL, NULL);

  res = AVIFileOpen(&avs->file, filename_char, OF_READ|OF_SHARE_DENY_WRITE, NULL);

  if (res != S_OK)

    {

      av_log(s, AV_LOG_ERROR, "AVIFileOpen failed with error %ld", res);

      AVIFileExit();

      return -1;

    }

  res = AVIFileInfo(avs->file, &info, sizeof(info));

  if (res != S_OK)

    {

      av_log(s, AV_LOG_ERROR, "AVIFileInfo failed with error %ld", res);

      AVIFileExit();

      return -1;

    }

  avs->streams = av_mallocz(info.dwStreams * sizeof(AVISynthStream));

  for (id=0; id<info.dwStreams; id++)

    {

      stream = &avs->streams[id];

      stream->read = 0;

      if (AVIFileGetStream(avs->file, &stream->handle, 0, id) == S_OK)

        {

          if (AVIStreamInfo(stream->handle, &stream->info, sizeof(stream->info)) == S_OK)

            {

              if (stream->info.fccType == streamtypeAUDIO)

                {

                  WAVEFORMATEX wvfmt;

                  LONG struct_size = sizeof(WAVEFORMATEX);

                  if (AVIStreamReadFormat(stream->handle, 0, &wvfmt, &struct_size) != S_OK)

                    continue;

                  st = avformat_new_stream(s, NULL);

                  st->id = id;

                  st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

                  st->codec->block_align = wvfmt.nBlockAlign;

                  st->codec->channels = wvfmt.nChannels;

                  st->codec->sample_rate = wvfmt.nSamplesPerSec;

                  st->codec->bit_rate = wvfmt.nAvgBytesPerSec * 8;

                  st->codec->bits_per_coded_sample = wvfmt.wBitsPerSample;

                  stream->chunck_samples = wvfmt.nSamplesPerSec * (uint64_t)info.dwScale / (uint64_t)info.dwRate;

                  stream->chunck_size = stream->chunck_samples * wvfmt.nChannels * wvfmt.wBitsPerSample / 8;

                  st->codec->codec_tag = wvfmt.wFormatTag;

                  st->codec->codec_id = ff_wav_codec_get_id(wvfmt.wFormatTag, st->codec->bits_per_coded_sample);

                }

              else if (stream->info.fccType == streamtypeVIDEO)

                {

                  BITMAPINFO imgfmt;

                  LONG struct_size = sizeof(BITMAPINFO);

                  stream->chunck_size = stream->info.dwSampleSize;

                  stream->chunck_samples = 1;

                  if (AVIStreamReadFormat(stream->handle, 0, &imgfmt, &struct_size) != S_OK)

                    continue;

                  st = avformat_new_stream(s, NULL);

                  st->id = id;

                  st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

                  st->r_frame_rate.num = stream->info.dwRate;

                  st->r_frame_rate.den = stream->info.dwScale;

                  st->codec->width = imgfmt.bmiHeader.biWidth;

                  st->codec->height = imgfmt.bmiHeader.biHeight;

                  st->codec->bits_per_coded_sample = imgfmt.bmiHeader.biBitCount;

                  st->codec->bit_rate = (uint64_t)stream->info.dwSampleSize * (uint64_t)stream->info.dwRate * 8 / (uint64_t)stream->info.dwScale;

                  st->codec->codec_tag = imgfmt.bmiHeader.biCompression;

                  st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, imgfmt.bmiHeader.biCompression);

                  st->duration = stream->info.dwLength;

                }

              else

                {

                  AVIStreamRelease(stream->handle);

                  continue;

                }

              avs->nb_streams++;

              st->codec->stream_codec_tag = stream->info.fccHandler;

              avpriv_set_pts_info(st, 64, info.dwScale, info.dwRate);

              st->start_time = stream->info.dwStart;

            }

        }

    }

  return 0;

}


void ioinst_handle_rsch(S390CPU *cpu, uint64_t reg1)

{

    int cssid, ssid, schid, m;

    SubchDev *sch;

    int ret = -ENODEV;

    int cc;

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

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

        return;

    }

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

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

    if (sch && css_subch_visible(sch)) {

        ret = css_do_rsch(sch);

    }

    switch (ret) {

    case -ENODEV:

        cc = 3;

        break;

    case -EINVAL:

        cc = 2;

        break;

    case 0:

        cc = 0;

        break;

    default:

        cc = 1;

        break;

    }

    setcc(cpu, cc);

}