static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap)

{

    ASFContext *asf = s->priv_data;

    ff_asf_guid g;

    ByteIOContext *pb = s->pb;

    AVStream *st;

    ASFStream *asf_st;

    int size, i;

    int64_t gsize;

    AVRational dar[128];

    uint32_t bitrate[128];

    memset(dar, 0, sizeof(dar));

    memset(bitrate, 0, sizeof(bitrate));

    get_guid(pb, &g);

    if (guidcmp(&g, &ff_asf_header))

        return -1;

    get_le64(pb);

    get_le32(pb);

    get_byte(pb);

    get_byte(pb);

    memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));

    for(;;) {

        uint64_t gpos= url_ftell(pb);

        get_guid(pb, &g);

        gsize = get_le64(pb);

        dprintf(s, "%08"PRIx64": ", gpos);

        print_guid(&g);

        dprintf(s, "  size=0x%"PRIx64"\n", gsize);

        if (!guidcmp(&g, &ff_asf_data_header)) {

            asf->data_object_offset = url_ftell(pb);

            // if not streaming, gsize is not unlimited (how?), and there is enough space in the file..

            if (!(asf->hdr.flags & 0x01) && gsize >= 100) {

                asf->data_object_size = gsize - 24;

            } else {

                asf->data_object_size = (uint64_t)-1;

            }

            break;

        }

        if (gsize < 24)

            return -1;

        if (!guidcmp(&g, &ff_asf_file_header)) {

            get_guid(pb, &asf->hdr.guid);

            asf->hdr.file_size          = get_le64(pb);

            asf->hdr.create_time        = get_le64(pb);

            asf->nb_packets             = get_le64(pb);

            asf->hdr.play_time          = get_le64(pb);

            asf->hdr.send_time          = get_le64(pb);

            asf->hdr.preroll            = get_le32(pb);

            asf->hdr.ignore             = get_le32(pb);

            asf->hdr.flags              = get_le32(pb);

            asf->hdr.min_pktsize        = get_le32(pb);

            asf->hdr.max_pktsize        = get_le32(pb);

            asf->hdr.max_bitrate        = get_le32(pb);

            s->packet_size = asf->hdr.max_pktsize;

        } else if (!guidcmp(&g, &ff_asf_stream_header)) {

            enum AVMediaType type;

            int type_specific_size, sizeX;

            uint64_t total_size;

            unsigned int tag1;

            int64_t pos1, pos2, start_time;

            int test_for_ext_stream_audio, is_dvr_ms_audio=0;

            if (s->nb_streams == ASF_MAX_STREAMS) {

                av_log(s, AV_LOG_ERROR, "too many streams\n");

                return AVERROR(EINVAL);

            }

            pos1 = url_ftell(pb);

            st = av_new_stream(s, 0);

            if (!st)

                return AVERROR(ENOMEM);

            av_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */

            asf_st = av_mallocz(sizeof(ASFStream));

            if (!asf_st)

                return AVERROR(ENOMEM);

            st->priv_data = asf_st;

            start_time = asf->hdr.preroll;

            asf_st->stream_language_index = 128; // invalid stream index means no language info

            if(!(asf->hdr.flags & 0x01)) { // if we aren't streaming...

                st->duration = asf->hdr.play_time /

                    (10000000 / 1000) - start_time;

            }

            get_guid(pb, &g);

            test_for_ext_stream_audio = 0;

            if (!guidcmp(&g, &ff_asf_audio_stream)) {

                type = AVMEDIA_TYPE_AUDIO;

            } else if (!guidcmp(&g, &ff_asf_video_stream)) {

                type = AVMEDIA_TYPE_VIDEO;

            } else if (!guidcmp(&g, &ff_asf_command_stream)) {

                type = AVMEDIA_TYPE_DATA;

            } else if (!guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) {

                test_for_ext_stream_audio = 1;

                type = AVMEDIA_TYPE_UNKNOWN;

            } else {

                return -1;

            }

            get_guid(pb, &g);

            total_size = get_le64(pb);

            type_specific_size = get_le32(pb);

            get_le32(pb);

            st->id = get_le16(pb) & 0x7f; /* stream id */

            // mapping of asf ID to AV stream ID;

            asf->asfid2avid[st->id] = s->nb_streams - 1;

            get_le32(pb);

            if (test_for_ext_stream_audio) {

                get_guid(pb, &g);

                if (!guidcmp(&g, &ff_asf_ext_stream_audio_stream)) {

                    type = AVMEDIA_TYPE_AUDIO;

                    is_dvr_ms_audio=1;

                    get_guid(pb, &g);

                    get_le32(pb);

                    get_le32(pb);

                    get_le32(pb);

                    get_guid(pb, &g);

                    get_le32(pb);

                }

            }

            st->codec->codec_type = type;

            if (type == AVMEDIA_TYPE_AUDIO) {

                ff_get_wav_header(pb, st->codec, type_specific_size);

                if (is_dvr_ms_audio) {

                    // codec_id and codec_tag are unreliable in dvr_ms

                    // files. Set them later by probing stream.

                    st->codec->codec_id = CODEC_ID_PROBE;

                    st->codec->codec_tag = 0;

                }

                if (st->codec->codec_id == CODEC_ID_AAC) {

                    st->need_parsing = AVSTREAM_PARSE_NONE;

                } else {

                    st->need_parsing = AVSTREAM_PARSE_FULL;

                }

                /* We have to init the frame size at some point .... */

                pos2 = url_ftell(pb);

                if (gsize >= (pos2 + 8 - pos1 + 24)) {

                    asf_st->ds_span = get_byte(pb);

                    asf_st->ds_packet_size = get_le16(pb);

                    asf_st->ds_chunk_size = get_le16(pb);

                    get_le16(pb); //ds_data_size

                    get_byte(pb); //ds_silence_data

                }

                //printf("Descrambling: ps:%d cs:%d ds:%d s:%d  sd:%d\n",

                //       asf_st->ds_packet_size, asf_st->ds_chunk_size,

                //       asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data);

                if (asf_st->ds_span > 1) {

                    if (!asf_st->ds_chunk_size

                        || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)

                        || asf_st->ds_packet_size % asf_st->ds_chunk_size)

                        asf_st->ds_span = 0; // disable descrambling

                }

                switch (st->codec->codec_id) {

                case CODEC_ID_MP3:

                    st->codec->frame_size = MPA_FRAME_SIZE;

                    break;

                case CODEC_ID_PCM_S16LE:

                case CODEC_ID_PCM_S16BE:

                case CODEC_ID_PCM_U16LE:

                case CODEC_ID_PCM_U16BE:

                case CODEC_ID_PCM_S8:

                case CODEC_ID_PCM_U8:

                case CODEC_ID_PCM_ALAW:

                case CODEC_ID_PCM_MULAW:

                    st->codec->frame_size = 1;

                    break;

                default:

                    /* This is probably wrong, but it prevents a crash later */

                    st->codec->frame_size = 1;

                    break;

                }

            } else if (type == AVMEDIA_TYPE_VIDEO) {

                get_le32(pb);

                get_le32(pb);

                get_byte(pb);

                size = get_le16(pb); /* size */

                sizeX= get_le32(pb); /* size */

                st->codec->width = get_le32(pb);

                st->codec->height = get_le32(pb);

                /* not available for asf */

                get_le16(pb); /* panes */

                st->codec->bits_per_coded_sample = get_le16(pb); /* depth */

                tag1 = get_le32(pb);

                url_fskip(pb, 20);

//                av_log(s, AV_LOG_DEBUG, "size:%d tsize:%d sizeX:%d\n", size, total_size, sizeX);

                size= sizeX;

                if (size > 40) {

                    st->codec->extradata_size = size - 40;

                    st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);

                    get_buffer(pb, st->codec->extradata, st->codec->extradata_size);

                }

                /* Extract palette from extradata if bpp <= 8 */

                /* This code assumes that extradata contains only palette */

                /* This is true for all paletted codecs implemented in ffmpeg */

                if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {

                    st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));

#if HAVE_BIGENDIAN

                    for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)

                        st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]);

#else

                    memcpy(st->codec->palctrl->palette, st->codec->extradata,

                           FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));

#endif

                    st->codec->palctrl->palette_changed = 1;

                }

                st->codec->codec_tag = tag1;

                st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);

                if(tag1 == MKTAG('D', 'V', 'R', ' '))

                    st->need_parsing = AVSTREAM_PARSE_FULL;

                if(st->codec->codec_id == CODEC_ID_H264)

                    st->need_parsing = AVSTREAM_PARSE_FULL_ONCE;

            }

            pos2 = url_ftell(pb);

            url_fskip(pb, gsize - (pos2 - pos1 + 24));

        } else if (!guidcmp(&g, &ff_asf_comment_header)) {

            int len1, len2, len3, len4, len5;

            len1 = get_le16(pb);

            len2 = get_le16(pb);

            len3 = get_le16(pb);

            len4 = get_le16(pb);

            len5 = get_le16(pb);

            get_tag(s, "title"    , 0, len1);

            get_tag(s, "author"   , 0, len2);

            get_tag(s, "copyright", 0, len3);

            get_tag(s, "comment"  , 0, len4);

            url_fskip(pb, len5);

        } else if (!guidcmp(&g, &stream_bitrate_guid)) {

            int stream_count = get_le16(pb);

            int j;

//            av_log(s, AV_LOG_ERROR, "stream bitrate properties\n");

//            av_log(s, AV_LOG_ERROR, "streams %d\n", streams);

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

                int flags, bitrate, stream_id;

                flags= get_le16(pb);

                bitrate= get_le32(pb);

                stream_id= (flags & 0x7f);

//                av_log(s, AV_LOG_ERROR, "flags: 0x%x stream id %d, bitrate %d\n", flags, stream_id, bitrate);

                asf->stream_bitrates[stream_id]= bitrate;

            }

        } else if (!guidcmp(&g, &ff_asf_language_guid)) {

            int j;

            int stream_count = get_le16(pb);

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

                char lang[6];

                unsigned int lang_len = get_byte(pb);

                get_str16_nolen(pb, lang_len, lang, sizeof(lang));

                if (j < 128)

                    av_strlcpy(asf->stream_languages[j], lang, sizeof(*asf->stream_languages));

            }

        } else if (!guidcmp(&g, &ff_asf_extended_content_header)) {

            int desc_count, i;

            desc_count = get_le16(pb);

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

                    int name_len,value_type,value_len;

                    char name[1024];

                    name_len = get_le16(pb);

                    if (name_len%2)     // must be even, broken lavf versions wrote len-1

                        name_len += 1;

                    get_str16_nolen(pb, name_len, name, sizeof(name));

                    value_type = get_le16(pb);

                    value_len  = get_le16(pb);

                    if (!value_type && value_len%2)

                        value_len += 1;

                    get_tag(s, name, value_type, value_len);

            }

        } else if (!guidcmp(&g, &ff_asf_metadata_header)) {

            int n, stream_num, name_len, value_len, value_type, value_num;

            n = get_le16(pb);

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

                char name[1024];

                get_le16(pb); //lang_list_index

                stream_num= get_le16(pb);

                name_len=   get_le16(pb);

                value_type= get_le16(pb);

                value_len=  get_le32(pb);

                get_str16_nolen(pb, name_len, name, sizeof(name));

//av_log(s, AV_LOG_ERROR, "%d %d %d %d %d <%s>\n", i, stream_num, name_len, value_type, value_len, name);

                value_num= get_le16(pb);//we should use get_value() here but it does not work 2 is le16 here but le32 elsewhere

                url_fskip(pb, value_len - 2);

                if(stream_num<128){

                    if     (!strcmp(name, "AspectRatioX")) dar[stream_num].num= value_num;

                    else if(!strcmp(name, "AspectRatioY")) dar[stream_num].den= value_num;

                }

            }

        } else if (!guidcmp(&g, &ff_asf_ext_stream_header)) {

            int ext_len, payload_ext_ct, stream_ct;

            uint32_t ext_d, leak_rate, stream_num;

            unsigned int stream_languageid_index;

            get_le64(pb); // starttime

            get_le64(pb); // endtime

            leak_rate = get_le32(pb); // leak-datarate

            get_le32(pb); // bucket-datasize

            get_le32(pb); // init-bucket-fullness

            get_le32(pb); // alt-leak-datarate

            get_le32(pb); // alt-bucket-datasize

            get_le32(pb); // alt-init-bucket-fullness

            get_le32(pb); // max-object-size

            get_le32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved)

            stream_num = get_le16(pb); // stream-num

            stream_languageid_index = get_le16(pb); // stream-language-id-index

            if (stream_num < 128)

                asf->streams[stream_num].stream_language_index = stream_languageid_index;

            get_le64(pb); // avg frametime in 100ns units

            stream_ct = get_le16(pb); //stream-name-count

            payload_ext_ct = get_le16(pb); //payload-extension-system-count

            if (stream_num < 128)

                bitrate[stream_num] = leak_rate;

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

                get_le16(pb);

                ext_len = get_le16(pb);

                url_fseek(pb, ext_len, SEEK_CUR);

            }

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

                get_guid(pb, &g);

                ext_d=get_le16(pb);

                ext_len=get_le32(pb);

                url_fseek(pb, ext_len, SEEK_CUR);

            }

            // there could be a optional stream properties object to follow

            // if so the next iteration will pick it up

            continue;

        } else if (!guidcmp(&g, &ff_asf_head1_guid)) {

            int v1, v2;

            get_guid(pb, &g);

            v1 = get_le32(pb);

            v2 = get_le16(pb);

            continue;

        } else if (!guidcmp(&g, &ff_asf_marker_header)) {

            int i, count, name_len;

            char name[1024];

            get_le64(pb);            // reserved 16 bytes

            get_le64(pb);            // ...

            count = get_le32(pb);    // markers count

            get_le16(pb);            // reserved 2 bytes

            name_len = get_le16(pb); // name length

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

                get_byte(pb); // skip the name

            }

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

                int64_t pres_time;

                int name_len;

                get_le64(pb);             // offset, 8 bytes

                pres_time = get_le64(pb); // presentation time

                get_le16(pb);             // entry length

                get_le32(pb);             // send time

                get_le32(pb);             // flags

                name_len = get_le32(pb);  // name length

                get_str16_nolen(pb, name_len * 2, name, sizeof(name));

                ff_new_chapter(s, i, (AVRational){1, 10000000}, pres_time, AV_NOPTS_VALUE, name );

            }

#if 0

        } else if (!guidcmp(&g, &ff_asf_codec_comment_header)) {

            int len, v1, n, num;

            char str[256], *q;

            char tag[16];

            get_guid(pb, &g);

            print_guid(&g);

            n = get_le32(pb);

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

                num = get_le16(pb); /* stream number */

                get_str16(pb, str, sizeof(str));

                get_str16(pb, str, sizeof(str));

                len = get_le16(pb);

                q = tag;

                while (len > 0) {

                    v1 = get_byte(pb);

                    if ((q - tag) < sizeof(tag) - 1)

                        *q++ = v1;

                    len--;

                }

                *q = '\0';

            }

#endif

        } else if (url_feof(pb)) {

            return -1;

        } else {

            if (!s->keylen) {

                if (!guidcmp(&g, &ff_asf_content_encryption)) {

                    av_log(s, AV_LOG_WARNING, "DRM protected stream detected, decoding will likely fail!\n");

                } else if (!guidcmp(&g, &ff_asf_ext_content_encryption)) {

                    av_log(s, AV_LOG_WARNING, "Ext DRM protected stream detected, decoding will likely fail!\n");

                } else if (!guidcmp(&g, &ff_asf_digital_signature)) {

                    av_log(s, AV_LOG_WARNING, "Digital signature detected, decoding will likely fail!\n");

                }

            }

        }

        if(url_ftell(pb) != gpos + gsize)

            av_log(s, AV_LOG_DEBUG, "gpos mismatch our pos=%"PRIu64", end=%"PRIu64"\n", url_ftell(pb)-gpos, gsize);

        url_fseek(pb, gpos + gsize, SEEK_SET);

    }

    get_guid(pb, &g);

    get_le64(pb);

    get_byte(pb);

    get_byte(pb);

    if (url_feof(pb))

        return -1;

    asf->data_offset = url_ftell(pb);

    asf->packet_size_left = 0;

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

        int stream_num= asf->asfid2avid[i];

        if(stream_num>=0){

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

            if (!st->codec->bit_rate)

                st->codec->bit_rate = bitrate[i];

            if (dar[i].num > 0 && dar[i].den > 0)

                av_reduce(&st->sample_aspect_ratio.num,

                          &st->sample_aspect_ratio.den,

                          dar[i].num, dar[i].den, INT_MAX);

//av_log(s, AV_LOG_ERROR, "dar %d:%d sar=%d:%d\n", dar[i].num, dar[i].den, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);

            // copy and convert language codes to the frontend

            if (asf->streams[i].stream_language_index < 128) {

                const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index];

                if (rfc1766 && strlen(rfc1766) > 1) {

                    const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any

                    const char *iso6392 = av_convert_lang_to(primary_tag, AV_LANG_ISO639_2_BIBL);

                    if (iso6392)

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

                }

            }

        }

    }

    return 0;

}


int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode,

                            Error **errp)

{

    FILE *fh;

    Error *local_err = NULL;

    int fd;

    int64_t ret = -1, handle;

    if (!has_mode) {

        mode = "r";

    }

    slog("guest-file-open called, filepath: %s, mode: %s", path, mode);

    fh = safe_open_or_create(path, mode, &local_err);

    if (local_err != NULL) {

        error_propagate(errp, local_err);

        return -1;

    }

    /* set fd non-blocking to avoid common use cases (like reading from a

     * named pipe) from hanging the agent

     */

    fd = fileno(fh);

    ret = fcntl(fd, F_GETFL);

    ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);

    if (ret == -1) {

        error_setg_errno(errp, errno, "failed to make file '%s' non-blocking",

                         path);

        fclose(fh);

        return -1;

    }

    handle = guest_file_handle_add(fh, errp);

    if (error_is_set(errp)) {

        fclose(fh);

        return -1;

    }

    slog("guest-file-open, handle: %" PRId64, handle);

    return handle;

}


static av_cold int rl2_read_header(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    AVStream *st;

    unsigned int frame_count;

    unsigned int audio_frame_counter = 0;

    unsigned int video_frame_counter = 0;

    unsigned int back_size;

    unsigned short sound_rate;

    unsigned short rate;

    unsigned short channels;

    unsigned short def_sound_size;

    unsigned int signature;

    unsigned int pts_den = 11025; /* video only case */

    unsigned int pts_num = 1103;

    unsigned int* chunk_offset = NULL;

    int* chunk_size = NULL;

    int* audio_size = NULL;

    int i;

    int ret = 0;

    avio_skip(pb,4);          /* skip FORM tag */

    back_size = avio_rl32(pb); /**< get size of the background frame */

    signature = avio_rb32(pb);

    avio_skip(pb, 4);         /* data size */

    frame_count = avio_rl32(pb);

    /* disallow back_sizes and frame_counts that may lead to overflows later */

    if(back_size > INT_MAX/2  || frame_count > INT_MAX / sizeof(uint32_t))

    avio_skip(pb, 2);         /* encoding mentod */

    sound_rate = avio_rl16(pb);

    rate = avio_rl16(pb);

    channels = avio_rl16(pb);

    def_sound_size = avio_rl16(pb);

    /** setup video stream */

    st = avformat_new_stream(s, NULL);

    if(!st)

         return AVERROR(ENOMEM);

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id = AV_CODEC_ID_RL2;

    st->codec->codec_tag = 0;  /* no fourcc */

    st->codec->width = 320;

    st->codec->height = 200;

    /** allocate and fill extradata */

    st->codec->extradata_size = EXTRADATA1_SIZE;

    if(signature == RLV3_TAG && back_size > 0)

        st->codec->extradata_size += back_size;

    st->codec->extradata = av_mallocz(st->codec->extradata_size +

                                          FF_INPUT_BUFFER_PADDING_SIZE);

    if(!st->codec->extradata)

        return AVERROR(ENOMEM);

    if(avio_read(pb,st->codec->extradata,st->codec->extradata_size) !=

                      st->codec->extradata_size)

        return AVERROR(EIO);

    /** setup audio stream if present */

    if(sound_rate){

        pts_num = def_sound_size;

        pts_den = rate;

        st = avformat_new_stream(s, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

        st->codec->codec_id = AV_CODEC_ID_PCM_U8;

        st->codec->codec_tag = 1;

        st->codec->channels = channels;

        st->codec->bits_per_coded_sample = 8;

        st->codec->sample_rate = rate;

        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *

            st->codec->bits_per_coded_sample;

        st->codec->block_align = st->codec->channels *

            st->codec->bits_per_coded_sample / 8;

        avpriv_set_pts_info(st,32,1,rate);

    avpriv_set_pts_info(s->streams[0], 32, pts_num, pts_den);

    chunk_size =   av_malloc(frame_count * sizeof(uint32_t));

    audio_size =   av_malloc(frame_count * sizeof(uint32_t));

    chunk_offset = av_malloc(frame_count * sizeof(uint32_t));

    if(!chunk_size || !audio_size || !chunk_offset){

        av_free(chunk_size);

        av_free(audio_size);

        av_free(chunk_offset);

        return AVERROR(ENOMEM);

    /** read offset and size tables */

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

        chunk_size[i] = avio_rl32(pb);

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

        chunk_offset[i] = avio_rl32(pb);

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

        audio_size[i] = avio_rl32(pb) & 0xFFFF;

    /** build the sample index */

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

        if(chunk_size[i] < 0 || audio_size[i] > chunk_size[i]){

            ret = AVERROR_INVALIDDATA;

            break;

        if(sound_rate && audio_size[i]){

            av_add_index_entry(s->streams[1], chunk_offset[i],

                audio_frame_counter,audio_size[i], 0, AVINDEX_KEYFRAME);

            audio_frame_counter += audio_size[i] / channels;

        av_add_index_entry(s->streams[0], chunk_offset[i] + audio_size[i],

            video_frame_counter,chunk_size[i]-audio_size[i],0,AVINDEX_KEYFRAME);

        ++video_frame_counter;

    av_free(chunk_size);

    av_free(audio_size);

    av_free(chunk_offset);

    return ret;


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

                             int *got_frame, AVPacket *pkt)

{

    CDXLVideoContext *c = avctx->priv_data;

    AVFrame * const p = data;

    int ret, w, h, encoding, aligned_width, buf_size = pkt->size;

    const uint8_t *buf = pkt->data;

    if (buf_size < 32)

        return AVERROR_INVALIDDATA;

    encoding        = buf[1] & 7;

    c->format       = buf[1] & 0xE0;

    w               = AV_RB16(&buf[14]);

    h               = AV_RB16(&buf[16]);

    c->bpp          = buf[19];

    c->palette_size = AV_RB16(&buf[20]);

    c->palette      = buf + 32;

    c->video        = c->palette + c->palette_size;

    c->video_size   = buf_size - c->palette_size - 32;

    if (c->palette_size > 512)

        return AVERROR_INVALIDDATA;

    if (buf_size < c->palette_size + 32)

        return AVERROR_INVALIDDATA;

    if (c->bpp < 1)

        return AVERROR_INVALIDDATA;

    if (c->format != BIT_PLANAR && c->format != BIT_LINE && c->format != CHUNKY) {

        avpriv_request_sample(avctx, "Pixel format 0x%0x", c->format);

        return AVERROR_PATCHWELCOME;

    }

    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)

        return ret;

    if (c->format == CHUNKY)

        aligned_width = avctx->width;

    else

        aligned_width = FFALIGN(c->avctx->width, 16);

    c->padded_bits  = aligned_width - c->avctx->width;

    if (c->video_size < aligned_width * avctx->height * c->bpp / 8)

        return AVERROR_INVALIDDATA;

    if (!encoding && c->palette_size && c->bpp <= 8) {

        avctx->pix_fmt = AV_PIX_FMT_PAL8;

    } else if (encoding == 1 && (c->bpp == 6 || c->bpp == 8)) {

        if (c->palette_size != (1 << (c->bpp - 1)))

            return AVERROR_INVALIDDATA;

        avctx->pix_fmt = AV_PIX_FMT_BGR24;

    } else if (!encoding && c->bpp == 24 && c->format == CHUNKY &&

               !c->palette_size) {

        avctx->pix_fmt = AV_PIX_FMT_RGB24;

    } else {

        avpriv_request_sample(avctx, "Encoding %d, bpp %d and format 0x%x",

                              encoding, c->bpp, c->format);

        return AVERROR_PATCHWELCOME;

    }

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

        return ret;

    p->pict_type = AV_PICTURE_TYPE_I;

    if (encoding) {

        av_fast_padded_malloc(&c->new_video, &c->new_video_size,

                              h * w + AV_INPUT_BUFFER_PADDING_SIZE);

        if (!c->new_video)

            return AVERROR(ENOMEM);

        if (c->bpp == 8)

            cdxl_decode_ham8(c, p);

        else

            cdxl_decode_ham6(c, p);

    } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {

        cdxl_decode_rgb(c, p);

    } else {

        cdxl_decode_raw(c, p);

    }

    *got_frame = 1;

    return buf_size;

}


int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )

{

    flag aSign;

    int32 aExp, shiftCount;

    uint64_t aSig, savedASig;

    int32 z;

    aSig = extractFloatx80Frac( a );

    aExp = extractFloatx80Exp( a );

    aSign = extractFloatx80Sign( a );

    if ( 0x401E < aExp ) {

        if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;

        goto invalid;

    }

    else if ( aExp < 0x3FFF ) {

        if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;

        return 0;

    }

    shiftCount = 0x403E - aExp;

    savedASig = aSig;

    aSig >>= shiftCount;

    z = aSig;

    if ( aSign ) z = - z;

    if ( ( z < 0 ) ^ aSign ) {

 invalid:

        float_raise( float_flag_invalid STATUS_VAR);

        return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;

    }

    if ( ( aSig<<shiftCount ) != savedASig ) {

        STATUS(float_exception_flags) |= float_flag_inexact;

    }

    return z;

}


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

                      AVPacket *avpkt)

{

    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);

    RawVideoContext *context       = avctx->priv_data;

    const uint8_t *buf             = avpkt->data;

    int buf_size                   = avpkt->size;

    int linesize_align             = 4;

    int res, len;

    int need_copy                  = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2;

    AVFrame   *frame   = data;

    AVPicture *picture = data;

    frame->pict_type        = AV_PICTURE_TYPE_I;

    frame->key_frame        = 1;

    frame->reordered_opaque = avctx->reordered_opaque;

    frame->pkt_pts          = avctx->pkt->pts;

    av_frame_set_pkt_pos     (frame, avctx->pkt->pos);

    av_frame_set_pkt_duration(frame, avctx->pkt->duration);

    if (context->tff >= 0) {

        frame->interlaced_frame = 1;

        frame->top_field_first  = context->tff;

    }

    if ((res = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)

        return res;

    if (need_copy)

        frame->buf[0] = av_buffer_alloc(context->frame_size);

    else

        frame->buf[0] = av_buffer_ref(avpkt->buf);

    if (!frame->buf[0])

        return AVERROR(ENOMEM);

    //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)

    if (context->is_2_4_bpp) {

        int i;

        uint8_t *dst = frame->buf[0]->data;

        buf_size = context->frame_size - AVPALETTE_SIZE;

        if (avctx->bits_per_coded_sample == 4) {

            for (i = 0; 2 * i + 1 < buf_size && i<avpkt->size; i++) {

                dst[2 * i + 0] = buf[i] >> 4;

                dst[2 * i + 1] = buf[i] & 15;

            }

            linesize_align = 8;

        } else {

            av_assert0(avctx->bits_per_coded_sample == 2);

            for (i = 0; 4 * i + 3 < buf_size && i<avpkt->size; i++) {

                dst[4 * i + 0] = buf[i] >> 6;

                dst[4 * i + 1] = buf[i] >> 4 & 3;

                dst[4 * i + 2] = buf[i] >> 2 & 3;

                dst[4 * i + 3] = buf[i]      & 3;

            }

            linesize_align = 16;

        }

        buf = dst;

    } else if (need_copy) {

        memcpy(frame->buf[0]->data, buf, FFMIN(buf_size, context->frame_size));

        buf = frame->buf[0]->data;

    }

    if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||

        avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))

        buf += buf_size - context->frame_size;

    len = context->frame_size - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? AVPALETTE_SIZE : 0);

    if (buf_size < len) {

        av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < expected frame_size %d\n", buf_size, len);

        av_buffer_unref(&frame->buf[0]);

        return AVERROR(EINVAL);

    }

    if ((res = avpicture_fill(picture, buf, avctx->pix_fmt,

                              avctx->width, avctx->height)) < 0) {

        av_buffer_unref(&frame->buf[0]);

        return res;

    }

    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {

        const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,

                                                     NULL);

        if (pal) {

            av_buffer_unref(&context->palette);

            context->palette = av_buffer_alloc(AVPALETTE_SIZE);

            if (!context->palette) {

                av_buffer_unref(&frame->buf[0]);

                return AVERROR(ENOMEM);

            }

            memcpy(context->palette->data, pal, AVPALETTE_SIZE);

            frame->palette_has_changed = 1;

        }

    }

    if ((avctx->pix_fmt==AV_PIX_FMT_BGR24    ||

        avctx->pix_fmt==AV_PIX_FMT_GRAY8    ||

        avctx->pix_fmt==AV_PIX_FMT_RGB555LE ||

        avctx->pix_fmt==AV_PIX_FMT_RGB555BE ||

        avctx->pix_fmt==AV_PIX_FMT_RGB565LE ||

        avctx->pix_fmt==AV_PIX_FMT_MONOWHITE ||

        avctx->pix_fmt==AV_PIX_FMT_PAL8) &&

        FFALIGN(frame->linesize[0], linesize_align) * avctx->height <= buf_size)

        frame->linesize[0] = FFALIGN(frame->linesize[0], linesize_align);

    if (avctx->pix_fmt == AV_PIX_FMT_NV12 && avctx->codec_tag == MKTAG('N', 'V', '1', '2') &&

        FFALIGN(frame->linesize[0], linesize_align) * avctx->height +

        FFALIGN(frame->linesize[1], linesize_align) * ((avctx->height + 1) / 2) <= buf_size) {

        int la0 = FFALIGN(frame->linesize[0], linesize_align);

        frame->data[1] += (la0 - frame->linesize[0]) * avctx->height;

        frame->linesize[0] = la0;

        frame->linesize[1] = FFALIGN(frame->linesize[1], linesize_align);

    }

    if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) ||

        (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {

        frame->buf[1]  = av_buffer_ref(context->palette);

        if (!frame->buf[1]) {

            av_buffer_unref(&frame->buf[0]);

            return AVERROR(ENOMEM);

        }

        frame->data[1] = frame->buf[1]->data;

    }

    if (avctx->pix_fmt == AV_PIX_FMT_BGR24 &&

        ((frame->linesize[0] + 3) & ~3) * avctx->height <= buf_size)

        frame->linesize[0] = (frame->linesize[0] + 3) & ~3;

    if (context->flip)

        flip(avctx, picture);

    if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2') ||

        avctx->codec_tag == MKTAG('Y', 'V', '1', '6') ||

        avctx->codec_tag == MKTAG('Y', 'V', '2', '4') ||

        avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))

        FFSWAP(uint8_t *, picture->data[1], picture->data[2]);

    if (avctx->codec_tag == AV_RL32("I420") && (avctx->width+1)*(avctx->height+1) * 3/2 == buf_size) {

        picture->data[1] = picture->data[1] +  (avctx->width+1)*(avctx->height+1) -avctx->width*avctx->height;

        picture->data[2] = picture->data[2] + ((avctx->width+1)*(avctx->height+1) -avctx->width*avctx->height)*5/4;

    }

    if (avctx->codec_tag == AV_RL32("yuv2") &&

        avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {

        int x, y;

        uint8_t *line = picture->data[0];

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

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

                line[2 * x + 1] ^= 0x80;

            line += picture->linesize[0];

        }

    }

    if (avctx->codec_tag == AV_RL32("YVYU") &&

        avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {

        int x, y;

        uint8_t *line = picture->data[0];

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

            for(x = 0; x < avctx->width - 1; x += 2)

                FFSWAP(uint8_t, line[2*x + 1], line[2*x + 3]);

            line += picture->linesize[0];

        }

    }

    if (avctx->field_order > AV_FIELD_PROGRESSIVE) { /* we have interlaced material flagged in container */

        frame->interlaced_frame = 1;

        if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)

            frame->top_field_first = 1;

    }

    *got_frame = 1;

    return buf_size;

}


int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx)

{

    struct vaapi_context * const vactx = avctx->hwaccel_context;

    MpegEncContext *s = avctx->priv_data;

    int ret;

    ret = ff_vaapi_commit_slices(vactx);

    if (ret < 0)

        goto finish;

    ret = ff_vaapi_render_picture(vactx,

                                  ff_vaapi_get_surface_id(&s->current_picture_ptr->f));

    if (ret < 0)

        goto finish;

    ff_mpeg_draw_horiz_band(s, 0, s->avctx->height);

finish:

    ff_vaapi_common_end_frame(avctx);

    return ret;

}


static void usb_uas_command(UASDevice *uas, uas_ui *ui)
{
    UASRequest *req;
    uint32_t len;
    uint16_t tag = be16_to_cpu(ui->hdr.tag);
    if (uas_using_streams(uas) && tag > UAS_MAX_STREAMS) {
        goto invalid_tag;
    }
    req = usb_uas_find_request(uas, tag);
    if (req) {
        goto overlapped_tag;
    }
    req = usb_uas_alloc_request(uas, ui);
    if (req->dev == NULL) {
        goto bad_target;
    }
    trace_usb_uas_command(uas->dev.addr, req->tag,
                          usb_uas_get_lun(req->lun),
                          req->lun >> 32, req->lun & 0xffffffff);
    QTAILQ_INSERT_TAIL(&uas->requests, req, next);
    if (uas_using_streams(uas) && uas->data3[req->tag] != NULL) {
        req->data = uas->data3[req->tag];
        req->data_async = true;
        uas->data3[req->tag] = NULL;
    }
    req->req = scsi_req_new(req->dev, req->tag,
                            usb_uas_get_lun(req->lun),
                            ui->command.cdb, req);
    if (uas->requestlog) {
        scsi_req_print(req->req);
    }
    len = scsi_req_enqueue(req->req);
    if (len) {
        req->data_size = len;
        scsi_req_continue(req->req);
    }
overlapped_tag:
    usb_uas_queue_fake_sense(uas, tag, sense_code_OVERLAPPED_COMMANDS);
bad_target:
    usb_uas_queue_fake_sense(uas, tag, sense_code_LUN_NOT_SUPPORTED);
    g_free(req);
}


static int rscc_decode_frame(AVCodecContext *avctx, void *data,
                                     int *got_frame, AVPacket *avpkt)
{
    RsccContext *ctx = avctx->priv_data;
    GetByteContext *gbc = &ctx->gbc;
    GetByteContext tiles_gbc;
    AVFrame *frame = data;
    const uint8_t *pixels, *raw;
    uint8_t *inflated_tiles = NULL;
    int tiles_nb, packed_size, pixel_size = 0;
    int i, ret = 0;
    bytestream2_init(gbc, avpkt->data, avpkt->size);
    /* Size check */
    if (bytestream2_get_bytes_left(gbc) < 12) {
        av_log(avctx, AV_LOG_ERROR, "Packet too small (%d)\n", avpkt->size);
        return AVERROR_INVALIDDATA;
    /* Read number of tiles, and allocate the array */
    tiles_nb = bytestream2_get_le16(gbc);
    av_fast_malloc(&ctx->tiles, &ctx->tiles_size,
                   tiles_nb * sizeof(*ctx->tiles));
    if (!ctx->tiles) {
        ret = AVERROR(ENOMEM);
    av_log(avctx, AV_LOG_DEBUG, "Frame with %d tiles.\n", tiles_nb);
    /* When there are more than 5 tiles, they are packed together with
     * a size header. When that size does not match the number of tiles
     * times the tile size, it means it needs to be inflated as well */
    if (tiles_nb > 5) {
        uLongf packed_tiles_size;
        if (tiles_nb < 32)
            packed_tiles_size = bytestream2_get_byte(gbc);
        else
            packed_tiles_size = bytestream2_get_le16(gbc);
        ff_dlog(avctx, "packed tiles of size %lu.\n", packed_tiles_size);
        /* If necessary, uncompress tiles, and hijack the bytestream reader */
        if (packed_tiles_size != tiles_nb * TILE_SIZE) {
            uLongf length = tiles_nb * TILE_SIZE;
            inflated_tiles = av_malloc(length);
            if (!inflated_tiles) {
                ret = AVERROR(ENOMEM);
            ret = uncompress(inflated_tiles, &length,
                             gbc->buffer, packed_tiles_size);
            if (ret) {
                av_log(avctx, AV_LOG_ERROR, "Tile deflate error %d.\n", ret);
                ret = AVERROR_UNKNOWN;
            /* Skip the compressed tile section in the main byte reader,
             * and point it to read the newly uncompressed data */
            bytestream2_skip(gbc, packed_tiles_size);
            bytestream2_init(&tiles_gbc, inflated_tiles, length);
            gbc = &tiles_gbc;
    /* Fill in array of tiles, keeping track of how many pixels are updated */
    for (i = 0; i < tiles_nb; i++) {
        ctx->tiles[i].x = bytestream2_get_le16(gbc);
        ctx->tiles[i].w = bytestream2_get_le16(gbc);
        ctx->tiles[i].y = bytestream2_get_le16(gbc);
        ctx->tiles[i].h = bytestream2_get_le16(gbc);
        pixel_size += ctx->tiles[i].w * ctx->tiles[i].h * ctx->component_size;
        ff_dlog(avctx, "tile %d orig(%d,%d) %dx%d.\n", i,
                ctx->tiles[i].x, ctx->tiles[i].y,
                ctx->tiles[i].w, ctx->tiles[i].h);
        if (ctx->tiles[i].w == 0 || ctx->tiles[i].h == 0) {
            av_log(avctx, AV_LOG_ERROR,
                   "invalid tile %d at (%d.%d) with size %dx%d.\n", i,
                   ctx->tiles[i].x, ctx->tiles[i].y,
                   ctx->tiles[i].w, ctx->tiles[i].h);
        } else if (ctx->tiles[i].x + ctx->tiles[i].w > avctx->width ||
                   ctx->tiles[i].y + ctx->tiles[i].h > avctx->height) {
            av_log(avctx, AV_LOG_ERROR,
                   "out of bounds tile %d at (%d.%d) with size %dx%d.\n", i,
                   ctx->tiles[i].x, ctx->tiles[i].y,
                   ctx->tiles[i].w, ctx->tiles[i].h);
    /* Reset the reader in case it had been modified before */
    gbc = &ctx->gbc;
    /* Extract how much pixel data the tiles contain */
    if (pixel_size < 0x100)
        packed_size = bytestream2_get_byte(gbc);
    else if (pixel_size < 0x10000)
        packed_size = bytestream2_get_le16(gbc);
    else if (pixel_size < 0x1000000)
        packed_size = bytestream2_get_le24(gbc);
    else
        packed_size = bytestream2_get_le32(gbc);
    ff_dlog(avctx, "pixel_size %d packed_size %d.\n", pixel_size, packed_size);
    if (packed_size < 0) {
        av_log(avctx, AV_LOG_ERROR, "Invalid tile size %d\n", packed_size);
    /* Get pixels buffer, it may be deflated or just raw */
    if (pixel_size == packed_size) {
        if (bytestream2_get_bytes_left(gbc) < pixel_size) {
            av_log(avctx, AV_LOG_ERROR, "Insufficient input for %d\n", pixel_size);
        pixels = gbc->buffer;
    } else {
        uLongf len = ctx->inflated_size;
        if (bytestream2_get_bytes_left(gbc) < packed_size) {
            av_log(avctx, AV_LOG_ERROR, "Insufficient input for %d\n", packed_size);
        ret = uncompress(ctx->inflated_buf, &len, gbc->buffer, packed_size);
        if (ret) {
            av_log(avctx, AV_LOG_ERROR, "Pixel deflate error %d.\n", ret);
            ret = AVERROR_UNKNOWN;
        pixels = ctx->inflated_buf;
    /* Allocate when needed */
    ret = ff_reget_buffer(avctx, ctx->reference);
    if (ret < 0)
    /* Pointer to actual pixels, will be updated when data is consumed */
    raw = pixels;
    for (i = 0; i < tiles_nb; i++) {
        uint8_t *dst = ctx->reference->data[0] + ctx->reference->linesize[0] *
                       (avctx->height - ctx->tiles[i].y - 1) +
                       ctx->tiles[i].x * ctx->component_size;
        av_image_copy_plane(dst, -1 * ctx->reference->linesize[0],
                            raw, ctx->tiles[i].w * ctx->component_size,
                            ctx->tiles[i].w * ctx->component_size,
                            ctx->tiles[i].h);
        raw += ctx->tiles[i].w * ctx->component_size * ctx->tiles[i].h;
    /* Frame is ready to be output */
    ret = av_frame_ref(frame, ctx->reference);
    if (ret < 0)
    /* Keyframe when the number of pixels updated matches the whole surface */
    if (pixel_size == ctx->inflated_size) {
        frame->pict_type = AV_PICTURE_TYPE_I;
        frame->key_frame = 1;
    } else {
        frame->pict_type = AV_PICTURE_TYPE_P;
    /* Palette handling */
    if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
        int size;
        const uint8_t *palette = av_packet_get_side_data(avpkt,
                                                         AV_PKT_DATA_PALETTE,
                                                         &size);
        if (palette && size == AVPALETTE_SIZE) {
            frame->palette_has_changed = 1;
            memcpy(ctx->palette, palette, AVPALETTE_SIZE);
        } else if (palette) {
            av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
        memcpy (frame->data[1], ctx->palette, AVPALETTE_SIZE);
    *got_frame = 1;
    ret = avpkt->size;
end:
    av_free(inflated_tiles);
    return ret;


static void swap_channel_layouts_on_filter(AVFilterContext *filter)

{

    AVFilterLink *link = NULL;

    int i, j, k;

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

        link = filter->inputs[i];

        if (link->type == AVMEDIA_TYPE_AUDIO &&

            link->out_channel_layouts->nb_channel_layouts == 1)

            break;

    }

    if (i == filter->nb_inputs)

        return;

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

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

        int best_idx, best_score = INT_MIN, best_count_diff = INT_MAX;

        if (outlink->type != AVMEDIA_TYPE_AUDIO ||

            outlink->in_channel_layouts->nb_channel_layouts < 2)

            continue;

        for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts; j++) {

            uint64_t  in_chlayout = link->out_channel_layouts->channel_layouts[0];

            uint64_t out_chlayout = outlink->in_channel_layouts->channel_layouts[j];

            int  in_channels      = av_get_channel_layout_nb_channels(in_chlayout);

            int out_channels      = av_get_channel_layout_nb_channels(out_chlayout);

            int count_diff        = out_channels - in_channels;

            int matched_channels, extra_channels;

            int score = 0;

            /* channel substitution */

            for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {

                uint64_t cmp0 = ch_subst[k][0];

                uint64_t cmp1 = ch_subst[k][1];

                if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&

                    (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {

                    in_chlayout  &= ~cmp0;

                    out_chlayout &= ~cmp1;

                    /* add score for channel match, minus a deduction for

                       having to do the substitution */

                    score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;

                }

            }

            /* no penalty for LFE channel mismatch */

            if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&

                (out_chlayout & AV_CH_LOW_FREQUENCY))

                score += 10;

            in_chlayout  &= ~AV_CH_LOW_FREQUENCY;

            out_chlayout &= ~AV_CH_LOW_FREQUENCY;

            matched_channels = av_get_channel_layout_nb_channels(in_chlayout &

                                                                 out_chlayout);

            extra_channels   = av_get_channel_layout_nb_channels(out_chlayout &

                                                                 (~in_chlayout));

            score += 10 * matched_channels - 5 * extra_channels;

            if (score > best_score ||

                (count_diff < best_count_diff && score == best_score)) {

                best_score = score;

                best_idx   = j;

                best_count_diff = count_diff;

            }

        }

        FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],

               outlink->in_channel_layouts->channel_layouts[best_idx]);

    }

}


int img_convert(AVPicture *dst, int dst_pix_fmt,

                const AVPicture *src, int src_pix_fmt,

                int src_width, int src_height)

{

    static int inited;

    int i, ret, dst_width, dst_height, int_pix_fmt;

    const PixFmtInfo *src_pix, *dst_pix;

    const ConvertEntry *ce;

    AVPicture tmp1, *tmp = &tmp1;

    if (src_pix_fmt < 0 || src_pix_fmt >= PIX_FMT_NB ||

        dst_pix_fmt < 0 || dst_pix_fmt >= PIX_FMT_NB)

        return -1;

    if (src_width <= 0 || src_height <= 0)

        return 0;

    if (!inited) {

        inited = 1;

        img_convert_init();

    }

    dst_width = src_width;

    dst_height = src_height;

    dst_pix = &pix_fmt_info[dst_pix_fmt];

    src_pix = &pix_fmt_info[src_pix_fmt];

    if (src_pix_fmt == dst_pix_fmt) {

        /* no conversion needed: just copy */

        av_picture_copy(dst, src, dst_pix_fmt, dst_width, dst_height);

        return 0;

    }

    ce = &convert_table[src_pix_fmt][dst_pix_fmt];

    if (ce->convert) {

        /* specific conversion routine */

        ce->convert(dst, src, dst_width, dst_height);

        return 0;

    }

    /* gray to YUV */

    if (is_yuv_planar(dst_pix) &&

        src_pix_fmt == PIX_FMT_GRAY8) {

        int w, h, y;

        uint8_t *d;

        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {

            ff_img_copy_plane(dst->data[0], dst->linesize[0],

                     src->data[0], src->linesize[0],

                     dst_width, dst_height);

        } else {

            img_apply_table(dst->data[0], dst->linesize[0],

                            src->data[0], src->linesize[0],

                            dst_width, dst_height,

                            y_jpeg_to_ccir);

        }

        /* fill U and V with 128 */

        w = dst_width;

        h = dst_height;

        w >>= dst_pix->x_chroma_shift;

        h >>= dst_pix->y_chroma_shift;

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

            d = dst->data[i];

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

                memset(d, 128, w);

                d += dst->linesize[i];

            }

        }

        return 0;

    }

    /* YUV to gray */

    if (is_yuv_planar(src_pix) &&

        dst_pix_fmt == PIX_FMT_GRAY8) {

        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {

            ff_img_copy_plane(dst->data[0], dst->linesize[0],

                     src->data[0], src->linesize[0],

                     dst_width, dst_height);

        } else {

            img_apply_table(dst->data[0], dst->linesize[0],

                            src->data[0], src->linesize[0],

                            dst_width, dst_height,

                            y_ccir_to_jpeg);

        }

        return 0;

    }

    /* YUV to YUV planar */

    if (is_yuv_planar(dst_pix) && is_yuv_planar(src_pix)) {

        int x_shift, y_shift, w, h, xy_shift;

        void (*resize_func)(uint8_t *dst, int dst_wrap,

                            const uint8_t *src, int src_wrap,

                            int width, int height);

        /* compute chroma size of the smallest dimensions */

        w = dst_width;

        h = dst_height;

        if (dst_pix->x_chroma_shift >= src_pix->x_chroma_shift)

            w >>= dst_pix->x_chroma_shift;

        else

            w >>= src_pix->x_chroma_shift;

        if (dst_pix->y_chroma_shift >= src_pix->y_chroma_shift)

            h >>= dst_pix->y_chroma_shift;

        else

            h >>= src_pix->y_chroma_shift;

        x_shift = (dst_pix->x_chroma_shift - src_pix->x_chroma_shift);

        y_shift = (dst_pix->y_chroma_shift - src_pix->y_chroma_shift);

        xy_shift = ((x_shift & 0xf) << 4) | (y_shift & 0xf);

        /* there must be filters for conversion at least from and to

           YUV444 format */

        switch(xy_shift) {

        case 0x00:

            resize_func = ff_img_copy_plane;

            break;

        case 0x10:

            resize_func = shrink21;

            break;

        case 0x20:

            resize_func = shrink41;

            break;

        case 0x01:

            resize_func = shrink12;

            break;

        case 0x11:

            resize_func = ff_shrink22;

            break;

        case 0x22:

            resize_func = ff_shrink44;

            break;

        case 0xf0:

            resize_func = grow21;

            break;

        case 0x0f:

            resize_func = grow12;

            break;

        case 0xe0:

            resize_func = grow41;

            break;

        case 0xff:

            resize_func = grow22;

            break;

        case 0xee:

            resize_func = grow44;

            break;

        case 0xf1:

            resize_func = conv411;

            break;

        default:

            /* currently not handled */

            goto no_chroma_filter;

        }

        ff_img_copy_plane(dst->data[0], dst->linesize[0],

                       src->data[0], src->linesize[0],

                       dst_width, dst_height);

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

            resize_func(dst->data[i], dst->linesize[i],

                        src->data[i], src->linesize[i],

                        dst_width>>dst_pix->x_chroma_shift, dst_height>>dst_pix->y_chroma_shift);

        /* if yuv color space conversion is needed, we do it here on

           the destination image */

        if (dst_pix->color_type != src_pix->color_type) {

            const uint8_t *y_table, *c_table;

            if (dst_pix->color_type == FF_COLOR_YUV) {

                y_table = y_jpeg_to_ccir;

                c_table = c_jpeg_to_ccir;

            } else {

                y_table = y_ccir_to_jpeg;

                c_table = c_ccir_to_jpeg;

            }

            img_apply_table(dst->data[0], dst->linesize[0],

                            dst->data[0], dst->linesize[0],

                            dst_width, dst_height,

                            y_table);

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

                img_apply_table(dst->data[i], dst->linesize[i],

                                dst->data[i], dst->linesize[i],

                                dst_width>>dst_pix->x_chroma_shift,

                                dst_height>>dst_pix->y_chroma_shift,

                                c_table);

        }

        return 0;

    }

 no_chroma_filter:

    /* try to use an intermediate format */

    if (src_pix_fmt == PIX_FMT_YUYV422 ||

        dst_pix_fmt == PIX_FMT_YUYV422) {

        /* specific case: convert to YUV422P first */

        int_pix_fmt = PIX_FMT_YUV422P;

    } else if (src_pix_fmt == PIX_FMT_UYVY422 ||

        dst_pix_fmt == PIX_FMT_UYVY422) {

        /* specific case: convert to YUV422P first */

        int_pix_fmt = PIX_FMT_YUV422P;

    } else if (src_pix_fmt == PIX_FMT_UYYVYY411 ||

        dst_pix_fmt == PIX_FMT_UYYVYY411) {

        /* specific case: convert to YUV411P first */

        int_pix_fmt = PIX_FMT_YUV411P;

    } else if ((src_pix->color_type == FF_COLOR_GRAY &&

                src_pix_fmt != PIX_FMT_GRAY8) ||

               (dst_pix->color_type == FF_COLOR_GRAY &&

                dst_pix_fmt != PIX_FMT_GRAY8)) {

        /* gray8 is the normalized format */

        int_pix_fmt = PIX_FMT_GRAY8;

    } else if ((is_yuv_planar(src_pix) &&

                src_pix_fmt != PIX_FMT_YUV444P &&

                src_pix_fmt != PIX_FMT_YUVJ444P)) {

        /* yuv444 is the normalized format */

        if (src_pix->color_type == FF_COLOR_YUV_JPEG)

            int_pix_fmt = PIX_FMT_YUVJ444P;

        else

            int_pix_fmt = PIX_FMT_YUV444P;

    } else if ((is_yuv_planar(dst_pix) &&

                dst_pix_fmt != PIX_FMT_YUV444P &&

                dst_pix_fmt != PIX_FMT_YUVJ444P)) {

        /* yuv444 is the normalized format */

        if (dst_pix->color_type == FF_COLOR_YUV_JPEG)

            int_pix_fmt = PIX_FMT_YUVJ444P;

        else

            int_pix_fmt = PIX_FMT_YUV444P;

    } else {

        /* the two formats are rgb or gray8 or yuv[j]444p */

        if (src_pix->is_alpha && dst_pix->is_alpha)

            int_pix_fmt = PIX_FMT_RGB32;

        else

            int_pix_fmt = PIX_FMT_RGB24;

    }

    if (src_pix_fmt == int_pix_fmt)

        return -1;

    if (avpicture_alloc(tmp, int_pix_fmt, dst_width, dst_height) < 0)

        return -1;

    ret = -1;

    if (img_convert(tmp, int_pix_fmt,

                    src, src_pix_fmt, src_width, src_height) < 0)

        goto fail1;

    if (img_convert(dst, dst_pix_fmt,

                    tmp, int_pix_fmt, dst_width, dst_height) < 0)

        goto fail1;

    ret = 0;

 fail1:

    avpicture_free(tmp);

    return ret;

}


static void nal_send(AVFormatContext *ctx, const uint8_t *buf, int len, int last_packet_of_frame)

{

    RTPMuxContext *rtp_ctx = ctx->priv_data;

    int rtp_payload_size   = rtp_ctx->max_payload_size - RTP_HEVC_HEADERS_SIZE;

    int nal_type           = (buf[0] >> 1) & 0x3F;

    /* send it as one single NAL unit? */

    if (len <= rtp_ctx->max_payload_size) {

        int buffered_size = rtp_ctx->buf_ptr - rtp_ctx->buf;

        /* Flush buffered NAL units if the current unit doesn't fit */

        if (buffered_size + 2 + len > rtp_ctx->max_payload_size) {

            flush_buffered(ctx, 0);

            buffered_size = 0;

        }

        /* If the NAL unit fits including the framing, write the unit

         * to the buffer as an aggregate packet, otherwise flush and

         * send as single NAL. */

        if (buffered_size + 4 + len <= rtp_ctx->max_payload_size) {

            if (buffered_size == 0) {

                *rtp_ctx->buf_ptr++ = 48 << 1;

                *rtp_ctx->buf_ptr++ = 1;

            }

            AV_WB16(rtp_ctx->buf_ptr, len);

            rtp_ctx->buf_ptr += 2;

            memcpy(rtp_ctx->buf_ptr, buf, len);

            rtp_ctx->buf_ptr += len;

            rtp_ctx->buffered_nals++;

        } else {

            flush_buffered(ctx, 0);

            ff_rtp_send_data(ctx, buf, len, last_packet_of_frame);

        }

    } else {

        flush_buffered(ctx, 0);

        /*

          create the HEVC payload header and transmit the buffer as fragmentation units (FU)

             0                   1

             0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

            |F|   Type    |  LayerId  | TID |

            +-------------+-----------------+

               F       = 0

               Type    = 49 (fragmentation unit (FU))

               LayerId = 0

               TID     = 1

         */

        rtp_ctx->buf[0] = 49 << 1;

        rtp_ctx->buf[1] = 1;

        /*

              create the FU header

              0 1 2 3 4 5 6 7

             +-+-+-+-+-+-+-+-+

             |S|E|  FuType   |

             +---------------+

                S       = variable

                E       = variable

                FuType  = NAL unit type

         */

        rtp_ctx->buf[2]  = nal_type;

        /* set the S bit: mark as start fragment */

        rtp_ctx->buf[2] |= 1 << 7;

        /* pass the original NAL header */

        buf += 2;

        len -= 2;

        while (len > rtp_payload_size) {

            /* complete and send current RTP packet */

            memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, rtp_payload_size);

            ff_rtp_send_data(ctx, rtp_ctx->buf, rtp_ctx->max_payload_size, 0);

            buf += rtp_payload_size;

            len -= rtp_payload_size;

            /* reset the S bit */

            rtp_ctx->buf[2] &= ~(1 << 7);

        }

        /* set the E bit: mark as last fragment */

        rtp_ctx->buf[2] |= 1 << 6;

        /* complete and send last RTP packet */

        memcpy(&rtp_ctx->buf[RTP_HEVC_HEADERS_SIZE], buf, len);

        ff_rtp_send_data(ctx, rtp_ctx->buf, len + 2, last_packet_of_frame);

    }

}


static void decode_band_structure(GetBitContext *gbc, int blk, int eac3,

                                  int ecpl, int start_subband, int end_subband,

                                  const uint8_t *default_band_struct,

                                  uint8_t *band_struct, int *num_subbands,

                                  int *num_bands, int *band_sizes)

{

    int subbnd, bnd, n_subbands, n_bands, bnd_sz[22];

    n_subbands = end_subband - start_subband;

    /* decode band structure from bitstream or use default */

    if (!eac3 || get_bits1(gbc)) {

        for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) {

            band_struct[subbnd] = get_bits1(gbc);

        }

    } else if (!blk) {

        memcpy(band_struct,

               &default_band_struct[start_subband+1],

               n_subbands-1);

    }

    band_struct[n_subbands-1] = 0;

    /* calculate number of bands and band sizes based on band structure.

       note that the first 4 subbands in enhanced coupling span only 6 bins

       instead of 12. */

    if (num_bands || band_sizes ) {

        n_bands = n_subbands;

        bnd_sz[0] = ecpl ? 6 : 12;

        for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) {

            int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12;

            if (band_struct[subbnd-1]) {

                n_bands--;

                bnd_sz[bnd] += subbnd_size;

            } else {

                bnd_sz[++bnd] = subbnd_size;

            }

        }

    }

    /* set optional output params */

    if (num_subbands)

        *num_subbands = n_subbands;

    if (num_bands)

        *num_bands = n_bands;

    if (band_sizes)

        memcpy(band_sizes, bnd_sz, sizeof(int)*n_bands);

}


static void init_coef_vlc(VLC *vlc,

                          uint16_t **prun_table, uint16_t **plevel_table,

                          const CoefVLCTable *vlc_table)

{

    int n = vlc_table->n;

    const uint8_t *table_bits = vlc_table->huffbits;

    const uint32_t *table_codes = vlc_table->huffcodes;

    const uint16_t *levels_table = vlc_table->levels;

    uint16_t *run_table, *level_table;

    const uint16_t *p;

    int i, l, j, level;

    init_vlc(vlc, 9, n, table_bits, 1, 1, table_codes, 4, 4);

    run_table = av_malloc(n * sizeof(uint16_t));

    level_table = av_malloc(n * sizeof(uint16_t));

    p = levels_table;

    i = 2;

    level = 1;

    while (i < n) {

        l = *p++;

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

            run_table[i] = j;

            level_table[i] = level;

            i++;

        }

        level++;

    }

    *prun_table = run_table;

    *plevel_table = level_table;

}


static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt,

                                      int discard)

{

    AviSynthContext *avs = s->priv_data;

    AVS_VideoFrame *frame;

    unsigned char *dst_p;

    const unsigned char *src_p;

    int n, i, plane, rowsize, planeheight, pitch, bits;

    const char *error;

    if (avs->curr_frame >= avs->vi->num_frames)

        return AVERROR_EOF;

    /* This must happen even if the stream is discarded to prevent desync. */

    n = avs->curr_frame++;

    if (discard)

        return 0;

#ifdef USING_AVISYNTH

    /* Define the bpp values for the new AviSynth 2.6 colorspaces.

     * Since AvxSynth doesn't have these functions, special-case

     * it in order to avoid implicit declaration errors. */

    if (avs_library.avs_is_yv24(avs->vi))

        bits = 24;

    else if (avs_library.avs_is_yv16(avs->vi))

        bits = 16;

    else if (avs_library.avs_is_yv411(avs->vi))

        bits = 12;

    else if (avs_library.avs_is_y8(avs->vi))

        bits = 8;

    else

        bits = avs_library.avs_bits_per_pixel(avs->vi);

#else

    bits = avs_bits_per_pixel(avs->vi);

#endif

    /* Without the cast to int64_t, calculation overflows at about 9k x 9k

     * resolution. */

    pkt->size = (((int64_t)avs->vi->width *

                  (int64_t)avs->vi->height) * bits) / 8;

    if (!pkt->size)

        return AVERROR_UNKNOWN;

    if (av_new_packet(pkt, pkt->size) < 0)

        return AVERROR(ENOMEM);

    pkt->pts      = n;

    pkt->dts      = n;

    pkt->duration = 1;

    pkt->stream_index = avs->curr_stream;

    frame = avs_library.avs_get_frame(avs->clip, n);

    error = avs_library.avs_clip_get_error(avs->clip);

    if (error) {

        av_log(s, AV_LOG_ERROR, "%s\n", error);

        avs->error = 1;

        av_packet_unref(pkt);

        return AVERROR_UNKNOWN;

    }

    dst_p = pkt->data;

    for (i = 0; i < avs->n_planes; i++) {

        plane = avs->planes[i];

#ifdef USING_AVISYNTH

        src_p = avs_library.avs_get_read_ptr_p(frame, plane);

        pitch = avs_library.avs_get_pitch_p(frame, plane);

        rowsize     = avs_library.avs_get_row_size_p(frame, plane);

        planeheight = avs_library.avs_get_height_p(frame, plane);

#else

        src_p = avs_get_read_ptr_p(frame, plane);

        pitch = avs_get_pitch_p(frame, plane);

        rowsize     = avs_get_row_size_p(frame, plane);

        planeheight = avs_get_height_p(frame, plane);

#endif

        /* Flip RGB video. */

        if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) {

            src_p = src_p + (planeheight - 1) * pitch;

            pitch = -pitch;

        }

        avs_library.avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch,

                                 rowsize, planeheight);

        dst_p += rowsize * planeheight;

    }

    avs_library.avs_release_video_frame(frame);

    return 0;

}


static void avc_luma_midh_qrt_and_aver_dst_16w_msa(const uint8_t *src,

                                                   int32_t src_stride,

                                                   uint8_t *dst,

                                                   int32_t dst_stride,

                                                   int32_t height,

                                                   uint8_t horiz_offset)

{

    uint32_t multiple8_cnt;

    for (multiple8_cnt = 4; multiple8_cnt--;) {

        avc_luma_midh_qrt_and_aver_dst_4w_msa(src, src_stride, dst, dst_stride,

                                              height, horiz_offset);

        src += 4;

        dst += 4;

    }

}


static int tiff_decode_tag(TiffContext *s, AVFrame *frame)

{

    unsigned tag, type, count, off, value = 0, value2 = 0;

    int i, start;

    int pos;

    int ret;

    double *dp;

    ret = ff_tread_tag(&s->gb, s->le, &tag, &type, &count, &start);

    if (ret < 0) {

        goto end;

    off = bytestream2_tell(&s->gb);

    if (count == 1) {

        switch (type) {

        case TIFF_BYTE:

        case TIFF_SHORT:

        case TIFF_LONG:

            value = ff_tget(&s->gb, type, s->le);

            break;

        case TIFF_RATIONAL:

            value  = ff_tget(&s->gb, TIFF_LONG, s->le);

            value2 = ff_tget(&s->gb, TIFF_LONG, s->le);

            break;

        case TIFF_STRING:

            if (count <= 4) {

                break;

        default:

            value = UINT_MAX;

    switch (tag) {

    case TIFF_WIDTH:

        s->width = value;

        break;

    case TIFF_HEIGHT:

        s->height = value;

        break;

    case TIFF_BPP:

        if (count > 4U) {

                   "This format is not supported (bpp=%d, %d components)\n",

                   value, count);

        s->bppcount = count;

        if (count == 1)

            s->bpp = value;

        else {

            switch (type) {

            case TIFF_BYTE:

            case TIFF_SHORT:

            case TIFF_LONG:

                s->bpp = 0;

                if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)

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

                    s->bpp += ff_tget(&s->gb, type, s->le);

                break;

            default:

                s->bpp = -1;

        break;

    case TIFF_SAMPLES_PER_PIXEL:

        if (count != 1) {

                   "Samples per pixel requires a single value, many provided\n");

        if (value > 4U) {

                   "Samples per pixel %d is too large\n", value);

        if (s->bppcount == 1)

            s->bpp *= value;

        s->bppcount = value;

        break;

    case TIFF_COMPR:

        s->compr     = value;

        av_log(s->avctx, AV_LOG_DEBUG, "compression: %d\n", s->compr);

        s->predictor = 0;

        switch (s->compr) {

        case TIFF_RAW:

        case TIFF_PACKBITS:

        case TIFF_LZW:

        case TIFF_CCITT_RLE:

            break;

        case TIFF_G3:

        case TIFF_G4:

            s->fax_opts = 0;

            break;

        case TIFF_DEFLATE:

        case TIFF_ADOBE_DEFLATE:

#if CONFIG_ZLIB

            break;

#else

            av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");

            return AVERROR(ENOSYS);

#endif

        case TIFF_JPEG:

        case TIFF_NEWJPEG:

            avpriv_report_missing_feature(s->avctx, "JPEG compression");

            return AVERROR_PATCHWELCOME;

        case TIFF_LZMA:

#if CONFIG_LZMA

            break;

#else

            av_log(s->avctx, AV_LOG_ERROR, "LZMA not compiled in\n");

            return AVERROR(ENOSYS);

#endif

        default:

            av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",

                   s->compr);

        break;

    case TIFF_ROWSPERSTRIP:

        if (!value || (type == TIFF_LONG && value == UINT_MAX))

            value = s->height;

        s->rps = FFMIN(value, s->height);

        break;

    case TIFF_STRIP_OFFS:

        if (count == 1) {

            s->strippos = 0;

            s->stripoff = value;

        } else

            s->strippos = off;

        s->strips = count;

        if (s->strips == 1)

            s->rps = s->height;

        s->sot = type;

        break;

    case TIFF_STRIP_SIZE:

        if (count == 1) {

                    "stripsize %u too large\n", value);

            s->stripsizesoff = 0;

            s->stripsize     = value;

            s->strips        = 1;

        } else {

            s->stripsizesoff = off;

        s->strips = count;

        s->sstype = type;

        break;

    case TIFF_XRES:

    case TIFF_YRES:

        set_sar(s, tag, value, value2);

        break;

    case TIFF_TILE_BYTE_COUNTS:

    case TIFF_TILE_LENGTH:

    case TIFF_TILE_OFFSETS:

    case TIFF_TILE_WIDTH:

        av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n");

        return AVERROR_PATCHWELCOME;

        break;

    case TIFF_PREDICTOR:

        s->predictor = value;

        break;

    case TIFF_PHOTOMETRIC:

        switch (value) {

        case TIFF_PHOTOMETRIC_WHITE_IS_ZERO:

        case TIFF_PHOTOMETRIC_BLACK_IS_ZERO:

        case TIFF_PHOTOMETRIC_RGB:

        case TIFF_PHOTOMETRIC_PALETTE:

        case TIFF_PHOTOMETRIC_YCBCR:

            s->photometric = value;

            break;

        case TIFF_PHOTOMETRIC_ALPHA_MASK:

        case TIFF_PHOTOMETRIC_SEPARATED:

        case TIFF_PHOTOMETRIC_CIE_LAB:

        case TIFF_PHOTOMETRIC_ICC_LAB:

        case TIFF_PHOTOMETRIC_ITU_LAB:

        case TIFF_PHOTOMETRIC_CFA:

        case TIFF_PHOTOMETRIC_LOG_L:

        case TIFF_PHOTOMETRIC_LOG_LUV:

        case TIFF_PHOTOMETRIC_LINEAR_RAW:

            avpriv_report_missing_feature(s->avctx,

                                          "PhotometricInterpretation 0x%04X",

                                          value);

            return AVERROR_PATCHWELCOME;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "PhotometricInterpretation %u is "

                   "unknown\n", value);

        break;

    case TIFF_FILL_ORDER:

        if (value < 1 || value > 2) {

                   "Unknown FillOrder value %d, trying default one\n", value);

            value = 1;

        s->fill_order = value - 1;

        break;

    case TIFF_PAL: {

        GetByteContext pal_gb[3];

        off = type_sizes[type];

        if (count / 3 > 256 ||

            bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)

        pal_gb[0] = pal_gb[1] = pal_gb[2] = s->gb;

        bytestream2_skip(&pal_gb[1], count / 3 * off);

        bytestream2_skip(&pal_gb[2], count / 3 * off * 2);

        off = (type_sizes[type] - 1) << 3;

        if (off > 31U) {

            av_log(s->avctx, AV_LOG_ERROR, "palette shift %d is out of range\n", off);

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

            uint32_t p = 0xFF000000;

            p |= (ff_tget(&pal_gb[0], type, s->le) >> off) << 16;

            p |= (ff_tget(&pal_gb[1], type, s->le) >> off) << 8;

            p |=  ff_tget(&pal_gb[2], type, s->le) >> off;

            s->palette[i] = p;

        s->palette_is_set = 1;

        break;

    case TIFF_PLANAR:

        s->planar = value == 2;

        break;

    case TIFF_YCBCR_SUBSAMPLING:

        if (count != 2) {

            av_log(s->avctx, AV_LOG_ERROR, "subsample count invalid\n");

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

            s->subsampling[i] = ff_tget(&s->gb, type, s->le);

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

                av_log(s->avctx, AV_LOG_ERROR, "subsampling %d is invalid\n", s->subsampling[i]);

        break;

    case TIFF_T4OPTIONS:

        if (s->compr == TIFF_G3)

            s->fax_opts = value;

        break;

    case TIFF_T6OPTIONS:

        if (s->compr == TIFF_G4)

            s->fax_opts = value;

        break;

#define ADD_METADATA(count, name, sep)\

    if ((ret = add_metadata(count, type, name, sep, s, frame)) < 0) {\

        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\

        goto end;\

    case TIFF_MODEL_PIXEL_SCALE:

        ADD_METADATA(count, "ModelPixelScaleTag", NULL);

        break;

    case TIFF_MODEL_TRANSFORMATION:

        ADD_METADATA(count, "ModelTransformationTag", NULL);

        break;

    case TIFF_MODEL_TIEPOINT:

        ADD_METADATA(count, "ModelTiepointTag", NULL);

        break;

    case TIFF_GEO_KEY_DIRECTORY:

        if (s->geotag_count) {

            avpriv_request_sample(s->avctx, "Multiple geo key directories\n");

        ADD_METADATA(1, "GeoTIFF_Version", NULL);

        ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");

        s->geotag_count   = ff_tget_short(&s->gb, s->le);

        if (s->geotag_count > count / 4 - 1) {

            s->geotag_count = count / 4 - 1;

            av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");

        if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4) {

            s->geotag_count = 0;

            return -1;

        s->geotags = av_mallocz_array(s->geotag_count, sizeof(TiffGeoTag));

        if (!s->geotags) {

            av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");

            s->geotag_count = 0;

            goto end;

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

            s->geotags[i].key    = ff_tget_short(&s->gb, s->le);

            s->geotags[i].type   = ff_tget_short(&s->gb, s->le);

            s->geotags[i].count  = ff_tget_short(&s->gb, s->le);

            if (!s->geotags[i].type)

                s->geotags[i].val  = get_geokey_val(s->geotags[i].key, ff_tget_short(&s->gb, s->le));

            else

                s->geotags[i].offset = ff_tget_short(&s->gb, s->le);

        break;

    case TIFF_GEO_DOUBLE_PARAMS:

        if (count >= INT_MAX / sizeof(int64_t))

        if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))

        dp = av_malloc_array(count, sizeof(double));

        if (!dp) {

            av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");

            goto end;

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

            dp[i] = ff_tget_double(&s->gb, s->le);

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

            if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {

                if (s->geotags[i].count == 0

                    || s->geotags[i].offset + s->geotags[i].count > count) {

                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);

                } else {

                    char *ap = doubles2str(&dp[s->geotags[i].offset], s->geotags[i].count, ", ");

                    if (!ap) {

                        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");

                        av_freep(&dp);

                        return AVERROR(ENOMEM);

                    s->geotags[i].val = ap;

        av_freep(&dp);

        break;

    case TIFF_GEO_ASCII_PARAMS:

        pos = bytestream2_tell(&s->gb);

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

            if (s->geotags[i].type == TIFF_GEO_ASCII_PARAMS) {

                if (s->geotags[i].count == 0

                    || s->geotags[i].offset +  s->geotags[i].count > count) {

                    av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);

                } else {

                    char *ap;

                    bytestream2_seek(&s->gb, pos + s->geotags[i].offset, SEEK_SET);

                    if (bytestream2_get_bytes_left(&s->gb) < s->geotags[i].count)

                    ap = av_malloc(s->geotags[i].count);

                    if (!ap) {

                        av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");

                        return AVERROR(ENOMEM);

                    bytestream2_get_bufferu(&s->gb, ap, s->geotags[i].count);

                    ap[s->geotags[i].count - 1] = '\0'; //replace the "|" delimiter with a 0 byte

                    s->geotags[i].val = ap;

        break;

    case TIFF_ARTIST:

        ADD_METADATA(count, "artist", NULL);

        break;

    case TIFF_COPYRIGHT:

        ADD_METADATA(count, "copyright", NULL);

        break;

    case TIFF_DATE:

        ADD_METADATA(count, "date", NULL);

        break;

    case TIFF_DOCUMENT_NAME:

        ADD_METADATA(count, "document_name", NULL);

        break;

    case TIFF_HOST_COMPUTER:

        ADD_METADATA(count, "computer", NULL);

        break;

    case TIFF_IMAGE_DESCRIPTION:

        ADD_METADATA(count, "description", NULL);

        break;

    case TIFF_MAKE:

        ADD_METADATA(count, "make", NULL);

        break;

    case TIFF_MODEL:

        ADD_METADATA(count, "model", NULL);

        break;

    case TIFF_PAGE_NAME:

        ADD_METADATA(count, "page_name", NULL);

        break;

    case TIFF_PAGE_NUMBER:

        ADD_METADATA(count, "page_number", " / ");

        break;

    case TIFF_SOFTWARE_NAME:

        ADD_METADATA(count, "software", NULL);

        break;

    default:

        if (s->avctx->err_recognition & AV_EF_EXPLODE) {

                   "Unknown or unsupported tag %d/0X%0X\n",

                   tag, tag);

end:

    if (s->bpp > 64U) {

                "This format is not supported (bpp=%d, %d components)\n",

                s->bpp, count);

        s->bpp = 0;

    bytestream2_seek(&s->gb, start, SEEK_SET);

    return 0;


int kvmppc_get_htab_fd(bool write)

{

    struct kvm_get_htab_fd s = {

        .flags = write ? KVM_GET_HTAB_WRITE : 0,

        .start_index = 0,

    };

    if (!cap_htab_fd) {

        fprintf(stderr, "KVM version doesn't support saving the hash table\n");

        return -1;

    }

    return kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &s);

}


static void machine_set_loadparm(Object *obj, const char *val, Error **errp)

{

    S390CcwMachineState *ms = S390_CCW_MACHINE(obj);

    int i;

    for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) {

        uint8_t c = toupper(val[i]); /* mimic HMC */

        if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '.') ||

            (c == ' ')) {

            ms->loadparm[i] = c;

        } else {

            error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)",

                       c, c);

            return;

        }

    }

    for (; i < sizeof(ms->loadparm); i++) {

        ms->loadparm[i] = ' '; /* pad right with spaces */

    }

}


static void eepro100_cu_command(EEPRO100State * s, uint8_t val)

{

    eepro100_tx_t tx;

    uint32_t cb_address;

    switch (val) {

    case CU_NOP:

        /* No operation. */

        break;

    case CU_START:

        if (get_cu_state(s) != cu_idle) {

            /* Intel documentation says that CU must be idle for the CU

             * start command. Intel driver for Linux also starts the CU

             * from suspended state. */

            logout("CU state is %u, should be %u\n", get_cu_state(s), cu_idle);

            //~ assert(!"wrong CU state");

        }

        set_cu_state(s, cu_active);

        s->cu_offset = s->pointer;

      next_command:

        cb_address = s->cu_base + s->cu_offset;

        cpu_physical_memory_read(cb_address, (uint8_t *) & tx, sizeof(tx));

        uint16_t status = le16_to_cpu(tx.status);

        uint16_t command = le16_to_cpu(tx.command);

        logout

            ("val=0x%02x (cu start), status=0x%04x, command=0x%04x, link=0x%08x\n",

             val, status, command, tx.link);

        bool bit_el = ((command & 0x8000) != 0);

        bool bit_s = ((command & 0x4000) != 0);

        bool bit_i = ((command & 0x2000) != 0);

        bool bit_nc = ((command & 0x0010) != 0);

        //~ bool bit_sf = ((command & 0x0008) != 0);

        uint16_t cmd = command & 0x0007;

        s->cu_offset = le32_to_cpu(tx.link);

        switch (cmd) {

        case CmdNOp:

            /* Do nothing. */

            break;

        case CmdIASetup:

            cpu_physical_memory_read(cb_address + 8, &s->macaddr[0], 6);

            TRACE(OTHER, logout("macaddr: %s\n", nic_dump(&s->macaddr[0], 6)));

            break;

        case CmdConfigure:

            cpu_physical_memory_read(cb_address + 8, &s->configuration[0],

                                     sizeof(s->configuration));

            TRACE(OTHER, logout("configuration: %s\n", nic_dump(&s->configuration[0], 16)));

            break;

        case CmdMulticastList:

            //~ missing("multicast list");

            break;

        case CmdTx:

            (void)0;

            uint32_t tbd_array = le32_to_cpu(tx.tx_desc_addr);

            uint16_t tcb_bytes = (le16_to_cpu(tx.tcb_bytes) & 0x3fff);

            TRACE(RXTX, logout

                ("transmit, TBD array address 0x%08x, TCB byte count 0x%04x, TBD count %u\n",

                 tbd_array, tcb_bytes, tx.tbd_count));

            assert(!bit_nc);

            //~ assert(!bit_sf);

            assert(tcb_bytes <= 2600);

            /* Next assertion fails for local configuration. */

            //~ assert((tcb_bytes > 0) || (tbd_array != 0xffffffff));

            if (!((tcb_bytes > 0) || (tbd_array != 0xffffffff))) {

                logout

                    ("illegal values of TBD array address and TCB byte count!\n");

            }

            // sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes

            uint8_t buf[2600];

            uint16_t size = 0;

            uint32_t tbd_address = cb_address + 0x10;

            assert(tcb_bytes <= sizeof(buf));

            while (size < tcb_bytes) {

                uint32_t tx_buffer_address = ldl_phys(tbd_address);

                uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);

                //~ uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);

                tbd_address += 8;

                TRACE(RXTX, logout

                    ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",

                     tx_buffer_address, tx_buffer_size));

                tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);

                cpu_physical_memory_read(tx_buffer_address, &buf[size],

                                         tx_buffer_size);

                size += tx_buffer_size;

            }

            if (tbd_array == 0xffffffff) {

                /* Simplified mode. Was already handled by code above. */

            } else {

                /* Flexible mode. */

                uint8_t tbd_count = 0;

                if (device_supports_eTxCB(s) && !(s->configuration[6] & BIT(4))) {

                    /* Extended Flexible TCB. */

                    assert(tcb_bytes == 0);

                    for (; tbd_count < 2; tbd_count++) {

                        uint32_t tx_buffer_address = ldl_phys(tbd_address);

                        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);

                        uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);

                        tbd_address += 8;

                        TRACE(RXTX, logout

                            ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",

                             tx_buffer_address, tx_buffer_size));

                        tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);

                        cpu_physical_memory_read(tx_buffer_address, &buf[size],

                                                 tx_buffer_size);

                        size += tx_buffer_size;

                        if (tx_buffer_el & 1) {

                            break;

                        }

                    }

                }

                tbd_address = tbd_array;

                for (; tbd_count < tx.tbd_count; tbd_count++) {

                    uint32_t tx_buffer_address = ldl_phys(tbd_address);

                    uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);

                    uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);

                    tbd_address += 8;

                    TRACE(RXTX, logout

                        ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",

                         tx_buffer_address, tx_buffer_size));

                    tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);

                    cpu_physical_memory_read(tx_buffer_address, &buf[size],

                                             tx_buffer_size);

                    size += tx_buffer_size;

                    if (tx_buffer_el & 1) {

                        break;

                    }

                }

            }

            TRACE(RXTX, logout("%p sending frame, len=%d,%s\n", s, size, nic_dump(buf, size)));

            qemu_send_packet(s->vc, buf, size);

            s->statistics.tx_good_frames++;

            /* Transmit with bad status would raise an CX/TNO interrupt.

             * (82557 only). Emulation never has bad status. */

            //~ eepro100_cx_interrupt(s);

            break;

        case CmdTDR:

            TRACE(OTHER, logout("load microcode\n"));

            /* Starting with offset 8, the command contains

             * 64 dwords microcode which we just ignore here. */

            break;

        default:

            missing("undefined command");

        }

        /* Write new status (success). */

        stw_phys(cb_address, status | 0x8000 | 0x2000);

        if (bit_i) {

            /* CU completed action. */

            eepro100_cx_interrupt(s);

        }

        if (bit_el) {

            /* CU becomes idle. Terminate command loop. */

            set_cu_state(s, cu_idle);

            eepro100_cna_interrupt(s);

        } else if (bit_s) {

            /* CU becomes suspended. */

            set_cu_state(s, cu_suspended);

            eepro100_cna_interrupt(s);

        } else {

            /* More entries in list. */

            TRACE(OTHER, logout("CU list with at least one more entry\n"));

            goto next_command;

        }

        TRACE(OTHER, logout("CU list empty\n"));

        /* List is empty. Now CU is idle or suspended. */

        break;

    case CU_RESUME:

        if (get_cu_state(s) != cu_suspended) {

            logout("bad CU resume from CU state %u\n", get_cu_state(s));

            /* Workaround for bad Linux eepro100 driver which resumes

             * from idle state. */

            //~ missing("cu resume");

            set_cu_state(s, cu_suspended);

        }

        if (get_cu_state(s) == cu_suspended) {

            TRACE(OTHER, logout("CU resuming\n"));

            set_cu_state(s, cu_active);

            goto next_command;

        }

        break;

    case CU_STATSADDR:

        /* Load dump counters address. */

        s->statsaddr = s->pointer;

        TRACE(OTHER, logout("val=0x%02x (status address)\n", val));

        break;

    case CU_SHOWSTATS:

        /* Dump statistical counters. */

        TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val));

        dump_statistics(s);

        break;

    case CU_CMD_BASE:

        /* Load CU base. */

        TRACE(OTHER, logout("val=0x%02x (CU base address)\n", val));

        s->cu_base = s->pointer;

        break;

    case CU_DUMPSTATS:

        /* Dump and reset statistical counters. */

        TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val));

        dump_statistics(s);

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

        break;

    case CU_SRESUME:

        /* CU static resume. */

        missing("CU static resume");

        break;

    default:

        missing("Undefined CU command");

    }

}


static av_cold int fieldmatch_init(AVFilterContext *ctx)

{

    const FieldMatchContext *fm = ctx->priv;

    AVFilterPad pad = {

        .name         = av_strdup("main"),

        .type         = AVMEDIA_TYPE_VIDEO,

        .filter_frame = filter_frame,

        .config_props = config_input,

    };

    if (!pad.name)

        return AVERROR(ENOMEM);

    ff_insert_inpad(ctx, INPUT_MAIN, &pad);

    if (fm->ppsrc) {

        pad.name = av_strdup("clean_src");

        pad.config_props = NULL;

        if (!pad.name)

            return AVERROR(ENOMEM);

        ff_insert_inpad(ctx, INPUT_CLEANSRC, &pad);

    }

    if ((fm->blockx & (fm->blockx - 1)) ||

        (fm->blocky & (fm->blocky - 1))) {

        av_log(ctx, AV_LOG_ERROR, "blockx and blocky settings must be power of two\n");

        return AVERROR(EINVAL);

    }

    if (fm->combpel > fm->blockx * fm->blocky) {

        av_log(ctx, AV_LOG_ERROR, "Combed pixel should not be larger than blockx x blocky\n");

        return AVERROR(EINVAL);

    }

    return 0;

}


static int count_contiguous_clusters(uint64_t nb_clusters, int cluster_size,

        uint64_t *l2_table, uint64_t start, uint64_t mask)

{

    int i;

    uint64_t offset = be64_to_cpu(l2_table[0]) & ~mask;

    if (!offset)

        return 0;

    for (i = start; i < start + nb_clusters; i++)

        if (offset + i * cluster_size != (be64_to_cpu(l2_table[i]) & ~mask))

            break;

	return (i - start);

}


static void gen_ove_ov(DisasContext *dc, TCGv ov)

{

    gen_helper_ove(cpu_env, ov);

}


void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s)

{

    uint64_t channel_mask = 0;

    int frame_type, i;

    s->codec = get_bits(gb, TAK_ENCODER_CODEC_BITS);

    skip_bits(gb, TAK_ENCODER_PROFILE_BITS);

    frame_type = get_bits(gb, TAK_SIZE_FRAME_DURATION_BITS);

    s->samples = get_bits64(gb, TAK_SIZE_SAMPLES_NUM_BITS);

    s->data_type   = get_bits(gb, TAK_FORMAT_DATA_TYPE_BITS);

    s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) +

                     TAK_SAMPLE_RATE_MIN;

    s->bps         = get_bits(gb, TAK_FORMAT_BPS_BITS) +

                     TAK_BPS_MIN;

    s->channels    = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) +

                     TAK_CHANNELS_MIN;

    if (get_bits1(gb)) {

        skip_bits(gb, TAK_FORMAT_VALID_BITS);

        if (get_bits1(gb)) {

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

                int value = get_bits(gb, TAK_FORMAT_CH_LAYOUT_BITS);

                if (value < FF_ARRAY_ELEMS(tak_channel_layouts))

                    channel_mask |= tak_channel_layouts[value];

            }

        }

    }

    s->ch_layout     = channel_mask;

    s->frame_samples = tak_get_nb_samples(s->sample_rate, frame_type);

}


int show_formats(void *optctx, const char *opt, const char *arg)

{

    AVInputFormat *ifmt  = NULL;

    AVOutputFormat *ofmt = NULL;

    const char *last_name;

    printf("File formats:\n"

           " D. = Demuxing supported\n"

           " .E = Muxing supported\n"

           " --\n");

    last_name = "000";

    for (;;) {

        int decode = 0;

        int encode = 0;

        const char *name      = NULL;

        const char *long_name = NULL;

        while ((ofmt = av_oformat_next(ofmt))) {

            if ((name == NULL || strcmp(ofmt->name, name) < 0) &&

                strcmp(ofmt->name, last_name) > 0) {

                name      = ofmt->name;

                long_name = ofmt->long_name;

                encode    = 1;

            }

        }

        while ((ifmt = av_iformat_next(ifmt))) {

            if ((name == NULL || strcmp(ifmt->name, name) < 0) &&

                strcmp(ifmt->name, last_name) > 0) {

                name      = ifmt->name;

                long_name = ifmt->long_name;

                encode    = 0;

            }

            if (name && strcmp(ifmt->name, name) == 0)

                decode = 1;

        }

        if (name == NULL)

            break;

        last_name = name;

        printf(" %s%s %-15s %s\n",

               decode ? "D" : " ",

               encode ? "E" : " ",

               name,

            long_name ? long_name:" ");

    }

    return 0;

}


static void SET_TYPE(resample_nearest)(void *dst0, int dst_index, const void *src0, int index)

{

    FELEM *dst = dst0;

    const FELEM *src = src0;

    dst[dst_index] = src[index];

}


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

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

                           int src_x_offset, int src_y_offset,

                           qpel_mc_func *qpix_op, h264_chroma_mc_func chroma_op){

    MpegEncContext * const s = &h->s;

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

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

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

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

    uint8_t * src_cb, * src_cr;

    int extra_width= h->emu_edge_width;

    int extra_height= h->emu_edge_height;

    int emu=0;

    const int full_mx= mx>>2;

    const int full_my= my>>2;

    const int pic_width  = 16*s->mb_width;

    const int pic_height = 16*s->mb_height >> MB_FIELD;

    if(!pic->data[0]) //FIXME this is unacceptable, some sensible error concealment must be done for missing reference frames

        return;

    if(mx&7) extra_width -= 3;

    if(my&7) extra_height -= 3;

    if(   full_mx < 0-extra_width

       || full_my < 0-extra_height

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

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

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

            src_y= s->edge_emu_buffer + 2 + 2*h->mb_linesize;

        emu=1;

    }

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

    if(!square){

        qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);

    }

    if(ENABLE_GRAY && s->flags&CODEC_FLAG_GRAY) return;

    if(MB_FIELD){

        // chroma offset when predicting from a field of opposite parity

        my += 2 * ((s->mb_y & 1) - (pic->reference - 1));

        emu |= (my>>3) < 0 || (my>>3) + 8 >= (pic_height>>1);

    }

    src_cb= pic->data[1] + (mx>>3) + (my>>3)*h->mb_uvlinesize;

    src_cr= pic->data[2] + (mx>>3) + (my>>3)*h->mb_uvlinesize;

    if(emu){

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

            src_cb= s->edge_emu_buffer;

    }

    chroma_op(dest_cb, src_cb, h->mb_uvlinesize, chroma_height, mx&7, my&7);

    if(emu){

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

            src_cr= s->edge_emu_buffer;

    }

    chroma_op(dest_cr, src_cr, h->mb_uvlinesize, chroma_height, mx&7, my&7);

}


static void rtsp_send_cmd(AVFormatContext *s,

                          const char *cmd, RTSPMessageHeader *reply,

                          unsigned char **content_ptr)

{

    RTSPState *rt = s->priv_data;

    char buf[4096], buf1[1024];

    rt->seq++;

    av_strlcpy(buf, cmd, sizeof(buf));

    snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq);

    av_strlcat(buf, buf1, sizeof(buf));

    if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) {

        snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id);

        av_strlcat(buf, buf1, sizeof(buf));

    }

    av_strlcat(buf, "\r\n", sizeof(buf));

#ifdef DEBUG

    printf("Sending:\n%s--\n", buf);

#endif

    url_write(rt->rtsp_hd, buf, strlen(buf));

    rtsp_read_reply(rt, reply, content_ptr);

}


static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const char *vfilters)

{

    static const enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };

    char sws_flags_str[128];

    char buffersrc_args[256];

    int ret;

    AVBufferSinkParams *buffersink_params = av_buffersink_params_alloc();

    AVFilterContext *filt_src = NULL, *filt_out = NULL, *filt_format;

    AVCodecContext *codec = is->video_st->codec;

    snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags);

    graph->scale_sws_opts = av_strdup(sws_flags_str);

    snprintf(buffersrc_args, sizeof(buffersrc_args),

             "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",

             codec->width, codec->height, codec->pix_fmt,

             is->video_st->time_base.num, is->video_st->time_base.den,

             codec->sample_aspect_ratio.num, codec->sample_aspect_ratio.den);

    if ((ret = avfilter_graph_create_filter(&filt_src,

                                            avfilter_get_by_name("buffer"),

                                            "ffplay_buffer", buffersrc_args, NULL,

                                            graph)) < 0)

        return ret;

    buffersink_params->pixel_fmts = pix_fmts;

    ret = avfilter_graph_create_filter(&filt_out,

                                       avfilter_get_by_name("buffersink"),

                                       "ffplay_buffersink", NULL, buffersink_params, graph);

    av_freep(&buffersink_params);

    if (ret < 0)

        return ret;

    if ((ret = avfilter_graph_create_filter(&filt_format,

                                            avfilter_get_by_name("format"),

                                            "format", "yuv420p", NULL, graph)) < 0)

        return ret;

    if ((ret = avfilter_link(filt_format, 0, filt_out, 0)) < 0)

        return ret;

    if (vfilters) {

        AVFilterInOut *outputs = avfilter_inout_alloc();

        AVFilterInOut *inputs  = avfilter_inout_alloc();

        outputs->name    = av_strdup("in");

        outputs->filter_ctx = filt_src;

        outputs->pad_idx = 0;

        outputs->next    = NULL;

        inputs->name    = av_strdup("out");

        inputs->filter_ctx = filt_format;

        inputs->pad_idx = 0;

        inputs->next    = NULL;

        if ((ret = avfilter_graph_parse(graph, vfilters, &inputs, &outputs, NULL)) < 0)

            return ret;

    } else {

        if ((ret = avfilter_link(filt_src, 0, filt_format, 0)) < 0)

            return ret;

    }

    if ((ret = avfilter_graph_config(graph, NULL)) < 0)

        return ret;

    is->in_video_filter  = filt_src;

    is->out_video_filter = filt_out;

    if (codec->codec->capabilities & CODEC_CAP_DR1) {

        is->use_dr1 = 1;

        codec->get_buffer     = codec_get_buffer;

        codec->release_buffer = codec_release_buffer;

        codec->opaque         = &is->buffer_pool;

    }

    return ret;

}