static int fourxm_read_header(AVFormatContext *s,

                              AVFormatParameters *ap)

{

    ByteIOContext *pb = s->pb;

    unsigned int fourcc_tag;

    unsigned int size;

    int header_size;

    FourxmDemuxContext *fourxm = s->priv_data;

    unsigned char *header;

    int i;

    int current_track = -1;

    AVStream *st;



    fourxm->track_count = 0;

    fourxm->tracks = NULL;

    fourxm->selected_track = 0;

    fourxm->fps = 1.0;



    /* skip the first 3 32-bit numbers */

    url_fseek(pb, 12, SEEK_CUR);



    /* check for LIST-HEAD */

    GET_LIST_HEADER();

    header_size = size - 4;

    if (fourcc_tag != HEAD_TAG || size < 4)

        return AVERROR_INVALIDDATA;



    /* allocate space for the header and load the whole thing */

    header = av_malloc(header_size);

    if (!header)

        return AVERROR(ENOMEM);

    if (get_buffer(pb, header, header_size) != header_size)

        return AVERROR(EIO);



    /* take the lazy approach and search for any and all vtrk and strk chunks */

    for (i = 0; i < header_size - 8; i++) {

        fourcc_tag = AV_RL32(&header[i]);

        size = AV_RL32(&header[i + 4]);



        if (fourcc_tag == std__TAG) {

            fourxm->fps = av_int2flt(AV_RL32(&header[i + 12]));

        } else if (fourcc_tag == vtrk_TAG) {

            /* check that there is enough data */

            if (size != vtrk_SIZE) {

                av_free(header);

                return AVERROR_INVALIDDATA;

            }

            fourxm->width = AV_RL32(&header[i + 36]);

            fourxm->height = AV_RL32(&header[i + 40]);



            /* allocate a new AVStream */

            st = av_new_stream(s, 0);

            if (!st)

                return AVERROR(ENOMEM);

            av_set_pts_info(st, 60, 1, fourxm->fps);



            fourxm->video_stream_index = st->index;



            st->codec->codec_type = CODEC_TYPE_VIDEO;

            st->codec->codec_id = CODEC_ID_4XM;

            st->codec->extradata_size = 4;

            st->codec->extradata = av_malloc(4);

            AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));

            st->codec->width = fourxm->width;

            st->codec->height = fourxm->height;



            i += 8 + size;

        } else if (fourcc_tag == strk_TAG) {

            /* check that there is enough data */

            if (size != strk_SIZE) {

                av_free(header);

                return AVERROR_INVALIDDATA;

            }

            current_track = AV_RL32(&header[i + 8]);

            if (current_track + 1 > fourxm->track_count) {

                fourxm->track_count = current_track + 1;

                if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack))

                    return -1;

                fourxm->tracks = av_realloc(fourxm->tracks,

                    fourxm->track_count * sizeof(AudioTrack));

                if (!fourxm->tracks) {

                    av_free(header);

                    return AVERROR(ENOMEM);

                }

            }

            fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);

            fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);

            fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);

            fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);

            i += 8 + size;



            /* allocate a new AVStream */

            st = av_new_stream(s, current_track);

            if (!st)

                return AVERROR(ENOMEM);



            av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);



            fourxm->tracks[current_track].stream_index = st->index;



            st->codec->codec_type = CODEC_TYPE_AUDIO;

            st->codec->codec_tag = 0;

            st->codec->channels = fourxm->tracks[current_track].channels;

            st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;

            st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;

            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;

            if (fourxm->tracks[current_track].adpcm)

                st->codec->codec_id = CODEC_ID_ADPCM_4XM;

            else if (st->codec->bits_per_coded_sample == 8)

                st->codec->codec_id = CODEC_ID_PCM_U8;

            else

                st->codec->codec_id = CODEC_ID_PCM_S16LE;

        }

    }



    av_free(header);



    /* skip over the LIST-MOVI chunk (which is where the stream should be */

    GET_LIST_HEADER();

    if (fourcc_tag != MOVI_TAG)

        return AVERROR_INVALIDDATA;



    /* initialize context members */

    fourxm->video_pts = -1;  /* first frame will push to 0 */

    fourxm->audio_pts = 0;



    return 0;

}

static int fourxm_read_header(AVFormatContext *s,

                              AVFormatParameters *ap)

{

    ByteIOContext *pb = s->pb;

    unsigned int fourcc_tag;

    unsigned int size;

    int header_size;

    FourxmDemuxContext *fourxm = s->priv_data;

    unsigned char *header;

    int i;

    int current_track = -1;

    AVStream *st;



    fourxm->track_count = 0;

    fourxm->tracks = NULL;

    fourxm->selected_track = 0;

    fourxm->fps = 1.0;



    

    url_fseek(pb, 12, SEEK_CUR);



    

    GET_LIST_HEADER();

    header_size = size - 4;

    if (fourcc_tag != HEAD_TAG || size < 4)

        return AVERROR_INVALIDDATA;



    

    header = av_malloc(header_size);

    if (!header)

        return AVERROR(ENOMEM);

    if (get_buffer(pb, header, header_size) != header_size)

        return AVERROR(EIO);



    

    for (i = 0; i < header_size - 8; i++) {

        fourcc_tag = AV_RL32(&header[i]);

        size = AV_RL32(&header[i + 4]);



        if (fourcc_tag == std__TAG) {

            fourxm->fps = av_int2flt(AV_RL32(&header[i + 12]));

        } else if (fourcc_tag == vtrk_TAG) {

            

            if (size != vtrk_SIZE) {

                av_free(header);

                return AVERROR_INVALIDDATA;

            }

            fourxm->width = AV_RL32(&header[i + 36]);

            fourxm->height = AV_RL32(&header[i + 40]);



            

            st = av_new_stream(s, 0);

            if (!st)

                return AVERROR(ENOMEM);

            av_set_pts_info(st, 60, 1, fourxm->fps);



            fourxm->video_stream_index = st->index;



            st->codec->codec_type = CODEC_TYPE_VIDEO;

            st->codec->codec_id = CODEC_ID_4XM;

            st->codec->extradata_size = 4;

            st->codec->extradata = av_malloc(4);

            AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16]));

            st->codec->width = fourxm->width;

            st->codec->height = fourxm->height;



            i += 8 + size;

        } else if (fourcc_tag == strk_TAG) {

            

            if (size != strk_SIZE) {

                av_free(header);

                return AVERROR_INVALIDDATA;

            }

            current_track = AV_RL32(&header[i + 8]);

            if (current_track + 1 > fourxm->track_count) {

                fourxm->track_count = current_track + 1;

                if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack))

                    return -1;

                fourxm->tracks = av_realloc(fourxm->tracks,

                    fourxm->track_count * sizeof(AudioTrack));

                if (!fourxm->tracks) {

                    av_free(header);

                    return AVERROR(ENOMEM);

                }

            }

            fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]);

            fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]);

            fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]);

            fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]);

            i += 8 + size;



            

            st = av_new_stream(s, current_track);

            if (!st)

                return AVERROR(ENOMEM);



            av_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate);



            fourxm->tracks[current_track].stream_index = st->index;



            st->codec->codec_type = CODEC_TYPE_AUDIO;

            st->codec->codec_tag = 0;

            st->codec->channels = fourxm->tracks[current_track].channels;

            st->codec->sample_rate = fourxm->tracks[current_track].sample_rate;

            st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits;

            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;

            if (fourxm->tracks[current_track].adpcm)

                st->codec->codec_id = CODEC_ID_ADPCM_4XM;

            else if (st->codec->bits_per_coded_sample == 8)

                st->codec->codec_id = CODEC_ID_PCM_U8;

            else

                st->codec->codec_id = CODEC_ID_PCM_S16LE;

        }

    }



    av_free(header);



    

    GET_LIST_HEADER();

    if (fourcc_tag != MOVI_TAG)

        return AVERROR_INVALIDDATA;



    

    fourxm->video_pts = -1;  

    fourxm->audio_pts = 0;



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0,

                              AVFormatParameters *VAR_1)

{

    ByteIOContext *pb = VAR_0->pb;

    unsigned int VAR_2;

    unsigned int VAR_3;

    int VAR_4;

    FourxmDemuxContext *fourxm = VAR_0->priv_data;

    unsigned char *VAR_5;

    int VAR_6;

    int VAR_7 = -1;

    AVStream *st;



    fourxm->track_count = 0;

    fourxm->tracks = NULL;

    fourxm->selected_track = 0;

    fourxm->fps = 1.0;



    

    url_fseek(pb, 12, SEEK_CUR);



    

    GET_LIST_HEADER();

    VAR_4 = VAR_3 - 4;

    if (VAR_2 != HEAD_TAG || VAR_3 < 4)

        return AVERROR_INVALIDDATA;



    

    VAR_5 = av_malloc(VAR_4);

    if (!VAR_5)

        return AVERROR(ENOMEM);

    if (get_buffer(pb, VAR_5, VAR_4) != VAR_4)

        return AVERROR(EIO);



    

    for (VAR_6 = 0; VAR_6 < VAR_4 - 8; VAR_6++) {

        VAR_2 = AV_RL32(&VAR_5[VAR_6]);

        VAR_3 = AV_RL32(&VAR_5[VAR_6 + 4]);



        if (VAR_2 == std__TAG) {

            fourxm->fps = av_int2flt(AV_RL32(&VAR_5[VAR_6 + 12]));

        } else if (VAR_2 == vtrk_TAG) {

            

            if (VAR_3 != vtrk_SIZE) {

                av_free(VAR_5);

                return AVERROR_INVALIDDATA;

            }

            fourxm->width = AV_RL32(&VAR_5[VAR_6 + 36]);

            fourxm->height = AV_RL32(&VAR_5[VAR_6 + 40]);



            

            st = av_new_stream(VAR_0, 0);

            if (!st)

                return AVERROR(ENOMEM);

            av_set_pts_info(st, 60, 1, fourxm->fps);



            fourxm->video_stream_index = st->index;



            st->codec->codec_type = CODEC_TYPE_VIDEO;

            st->codec->codec_id = CODEC_ID_4XM;

            st->codec->extradata_size = 4;

            st->codec->extradata = av_malloc(4);

            AV_WL32(st->codec->extradata, AV_RL32(&VAR_5[VAR_6 + 16]));

            st->codec->width = fourxm->width;

            st->codec->height = fourxm->height;



            VAR_6 += 8 + VAR_3;

        } else if (VAR_2 == strk_TAG) {

            

            if (VAR_3 != strk_SIZE) {

                av_free(VAR_5);

                return AVERROR_INVALIDDATA;

            }

            VAR_7 = AV_RL32(&VAR_5[VAR_6 + 8]);

            if (VAR_7 + 1 > fourxm->track_count) {

                fourxm->track_count = VAR_7 + 1;

                if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack))

                    return -1;

                fourxm->tracks = av_realloc(fourxm->tracks,

                    fourxm->track_count * sizeof(AudioTrack));

                if (!fourxm->tracks) {

                    av_free(VAR_5);

                    return AVERROR(ENOMEM);

                }

            }

            fourxm->tracks[VAR_7].adpcm = AV_RL32(&VAR_5[VAR_6 + 12]);

            fourxm->tracks[VAR_7].channels = AV_RL32(&VAR_5[VAR_6 + 36]);

            fourxm->tracks[VAR_7].sample_rate = AV_RL32(&VAR_5[VAR_6 + 40]);

            fourxm->tracks[VAR_7].bits = AV_RL32(&VAR_5[VAR_6 + 44]);

            VAR_6 += 8 + VAR_3;



            

            st = av_new_stream(VAR_0, VAR_7);

            if (!st)

                return AVERROR(ENOMEM);



            av_set_pts_info(st, 60, 1, fourxm->tracks[VAR_7].sample_rate);



            fourxm->tracks[VAR_7].stream_index = st->index;



            st->codec->codec_type = CODEC_TYPE_AUDIO;

            st->codec->codec_tag = 0;

            st->codec->channels = fourxm->tracks[VAR_7].channels;

            st->codec->sample_rate = fourxm->tracks[VAR_7].sample_rate;

            st->codec->bits_per_coded_sample = fourxm->tracks[VAR_7].bits;

            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;

            if (fourxm->tracks[VAR_7].adpcm)

                st->codec->codec_id = CODEC_ID_ADPCM_4XM;

            else if (st->codec->bits_per_coded_sample == 8)

                st->codec->codec_id = CODEC_ID_PCM_U8;

            else

                st->codec->codec_id = CODEC_ID_PCM_S16LE;

        }

    }



    av_free(VAR_5);



    

    GET_LIST_HEADER();

    if (VAR_2 != MOVI_TAG)

        return AVERROR_INVALIDDATA;



    

    fourxm->video_pts = -1;  

    fourxm->audio_pts = 0;



    return 0;

}

static int FUNC_0(AVFormatContext *VAR_0,
AVFormatParameters *VAR_1)
{ ByteIOContext *pb = VAR_0->pb; unsigned int VAR_2; unsigned int VAR_3; int VAR_4; FourxmDemuxContext *fourxm = VAR_0->priv_data; unsigned char *VAR_5; int VAR_6; int VAR_7 = -1; AVStream *st; fourxm->track_count = 0; fourxm->tracks = NULL; fourxm->selected_track = 0; fourxm->fps = 1.0; url_fseek(pb, 12, SEEK_CUR); GET_LIST_HEADER(); VAR_4 = VAR_3 - 4; if (VAR_2 != HEAD_TAG || VAR_3 < 4)
return AVERROR_INVALIDDATA; VAR_5 = av_malloc(VAR_4); if (!VAR_5)
return AVERROR(ENOMEM); if (get_buffer(pb, VAR_5, VAR_4) != VAR_4)
return AVERROR(EIO); for (VAR_6 = 0; VAR_6 < VAR_4 - 8; VAR_6++) { VAR_2 = AV_RL32(&VAR_5[VAR_6]); VAR_3 = AV_RL32(&VAR_5[VAR_6 + 4]); if (VAR_2 == std__TAG) { fourxm->fps = av_int2flt(AV_RL32(&VAR_5[VAR_6 + 12])); } else if (VAR_2 == vtrk_TAG) { if (VAR_3 != vtrk_SIZE) { av_free(VAR_5); return AVERROR_INVALIDDATA; } fourxm->width = AV_RL32(&VAR_5[VAR_6 + 36]); fourxm->height = AV_RL32(&VAR_5[VAR_6 + 40]); st = av_new_stream(VAR_0, 0); if (!st)
return AVERROR(ENOMEM); av_set_pts_info(st, 60, 1, fourxm->fps); fourxm->video_stream_index = st->index; st->codec->codec_type = CODEC_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_4XM; st->codec->extradata_size = 4; st->codec->extradata = av_malloc(4); AV_WL32(st->codec->extradata, AV_RL32(&VAR_5[VAR_6 + 16])); st->codec->width = fourxm->width; st->codec->height = fourxm->height; VAR_6 += 8 + VAR_3; } else if (VAR_2 == strk_TAG) { if (VAR_3 != strk_SIZE) { av_free(VAR_5); return AVERROR_INVALIDDATA; } VAR_7 = AV_RL32(&VAR_5[VAR_6 + 8]); if (VAR_7 + 1 > fourxm->track_count) { fourxm->track_count = VAR_7 + 1; if((unsigned)fourxm->track_count >= UINT_MAX / sizeof(AudioTrack))
return -1; fourxm->tracks = av_realloc(fourxm->tracks,
fourxm->track_count * sizeof(AudioTrack)); if (!fourxm->tracks) { av_free(VAR_5); return AVERROR(ENOMEM); } } fourxm->tracks[VAR_7].adpcm = AV_RL32(&VAR_5[VAR_6 + 12]); fourxm->tracks[VAR_7].channels = AV_RL32(&VAR_5[VAR_6 + 36]); fourxm->tracks[VAR_7].sample_rate = AV_RL32(&VAR_5[VAR_6 + 40]); fourxm->tracks[VAR_7].bits = AV_RL32(&VAR_5[VAR_6 + 44]); VAR_6 += 8 + VAR_3; st = av_new_stream(VAR_0, VAR_7); if (!st)
return AVERROR(ENOMEM); av_set_pts_info(st, 60, 1, fourxm->tracks[VAR_7].sample_rate); fourxm->tracks[VAR_7].stream_index = st->index; st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->codec_tag = 0; st->codec->channels = fourxm->tracks[VAR_7].channels; st->codec->sample_rate = fourxm->tracks[VAR_7].sample_rate; st->codec->bits_per_coded_sample = fourxm->tracks[VAR_7].bits; 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; if (fourxm->tracks[VAR_7].adpcm)
st->codec->codec_id = CODEC_ID_ADPCM_4XM; else if (st->codec->bits_per_coded_sample == 8)
st->codec->codec_id = CODEC_ID_PCM_U8; else
st->codec->codec_id = CODEC_ID_PCM_S16LE; } } av_free(VAR_5); GET_LIST_HEADER(); if (VAR_2 != MOVI_TAG)
return AVERROR_INVALIDDATA; fourxm->video_pts = -1; fourxm->audio_pts = 0; return 0; }