static int fourxm_read_packet(AVFormatContext *s,

                              AVPacket *pkt)

{

    FourxmDemuxContext *fourxm = s->priv_data;

    ByteIOContext *pb = s->pb;

    unsigned int fourcc_tag;

    unsigned int size, out_size;

    int ret = 0;

    unsigned int track_number;

    int packet_read = 0;

    unsigned char header[8];

    int audio_frame_count;



    while (!packet_read) {



        if ((ret = get_buffer(s->pb, header, 8)) < 0)

            return ret;

        fourcc_tag = AV_RL32(&header[0]);

        size = AV_RL32(&header[4]);

        if (url_feof(pb))

            return AVERROR(EIO);

        switch (fourcc_tag) {



        case LIST_TAG:

            /* this is a good time to bump the video pts */

            fourxm->video_pts ++;



            /* skip the LIST-* tag and move on to the next fourcc */

            get_le32(pb);

            break;



        case ifrm_TAG:

        case pfrm_TAG:

        case cfrm_TAG:

        case ifr2_TAG:

        case pfr2_TAG:

        case cfr2_TAG:

            /* allocate 8 more bytes than 'size' to account for fourcc

             * and size */

            if (size + 8 < size || av_new_packet(pkt, size + 8))

                return AVERROR(EIO);

            pkt->stream_index = fourxm->video_stream_index;

            pkt->pts = fourxm->video_pts;

            pkt->pos = url_ftell(s->pb);

            memcpy(pkt->data, header, 8);

            ret = get_buffer(s->pb, &pkt->data[8], size);



            if (ret < 0){

                av_free_packet(pkt);

            }else

                packet_read = 1;

            break;



        case snd__TAG:

            track_number = get_le32(pb);

            out_size= get_le32(pb);

            size-=8;



            if (track_number < fourxm->track_count) {

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

                if(ret<0)

                    return AVERROR(EIO);

                pkt->stream_index =

                    fourxm->tracks[track_number].stream_index;

                pkt->pts = fourxm->tracks[track_number].audio_pts;

                packet_read = 1;



                /* pts accounting */

                audio_frame_count = size;

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

                    audio_frame_count -=

                        2 * (fourxm->tracks[track_number].channels);

                audio_frame_count /=

                      fourxm->tracks[track_number].channels;

                if (fourxm->tracks[track_number].adpcm){

                    audio_frame_count *= 2;

                }else

                    audio_frame_count /=

                    (fourxm->tracks[track_number].bits / 8);

                fourxm->tracks[track_number].audio_pts += audio_frame_count;



            } else {

                url_fseek(pb, size, SEEK_CUR);

            }

            break;



        default:

            url_fseek(pb, size, SEEK_CUR);

            break;

        }

    }

    return ret;

}

static int fourxm_read_packet(AVFormatContext *s,

                              AVPacket *pkt)

{

    FourxmDemuxContext *fourxm = s->priv_data;

    ByteIOContext *pb = s->pb;

    unsigned int fourcc_tag;

    unsigned int size, out_size;

    int ret = 0;

    unsigned int track_number;

    int packet_read = 0;

    unsigned char header[8];

    int audio_frame_count;



    while (!packet_read) {



        if ((ret = get_buffer(s->pb, header, 8)) < 0)

            return ret;

        fourcc_tag = AV_RL32(&header[0]);

        size = AV_RL32(&header[4]);

        if (url_feof(pb))

            return AVERROR(EIO);

        switch (fourcc_tag) {



        case LIST_TAG:

            

            fourxm->video_pts ++;



            

            get_le32(pb);

            break;



        case ifrm_TAG:

        case pfrm_TAG:

        case cfrm_TAG:

        case ifr2_TAG:

        case pfr2_TAG:

        case cfr2_TAG:

            



            if (size + 8 < size || av_new_packet(pkt, size + 8))

                return AVERROR(EIO);

            pkt->stream_index = fourxm->video_stream_index;

            pkt->pts = fourxm->video_pts;

            pkt->pos = url_ftell(s->pb);

            memcpy(pkt->data, header, 8);

            ret = get_buffer(s->pb, &pkt->data[8], size);



            if (ret < 0){

                av_free_packet(pkt);

            }else

                packet_read = 1;

            break;



        case snd__TAG:

            track_number = get_le32(pb);

            out_size= get_le32(pb);

            size-=8;



            if (track_number < fourxm->track_count) {

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

                if(ret<0)

                    return AVERROR(EIO);

                pkt->stream_index =

                    fourxm->tracks[track_number].stream_index;

                pkt->pts = fourxm->tracks[track_number].audio_pts;

                packet_read = 1;



                

                audio_frame_count = size;

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

                    audio_frame_count -=

                        2 * (fourxm->tracks[track_number].channels);

                audio_frame_count /=

                      fourxm->tracks[track_number].channels;

                if (fourxm->tracks[track_number].adpcm){

                    audio_frame_count *= 2;

                }else

                    audio_frame_count /=

                    (fourxm->tracks[track_number].bits / 8);

                fourxm->tracks[track_number].audio_pts += audio_frame_count;



            } else {

                url_fseek(pb, size, SEEK_CUR);

            }

            break;



        default:

            url_fseek(pb, size, SEEK_CUR);

            break;

        }

    }

    return ret;

}

static int FUNC_0(AVFormatContext *VAR_0,

                              AVPacket *VAR_1)

{

    FourxmDemuxContext *fourxm = VAR_0->priv_data;

    ByteIOContext *pb = VAR_0->pb;

    unsigned int VAR_2;

    unsigned int VAR_3, VAR_4;

    int VAR_5 = 0;

    unsigned int VAR_6;

    int VAR_7 = 0;

    unsigned char VAR_8[8];

    int VAR_9;



    while (!VAR_7) {



        if ((VAR_5 = get_buffer(VAR_0->pb, VAR_8, 8)) < 0)

            return VAR_5;

        VAR_2 = AV_RL32(&VAR_8[0]);

        VAR_3 = AV_RL32(&VAR_8[4]);

        if (url_feof(pb))

            return AVERROR(EIO);

        switch (VAR_2) {



        case LIST_TAG:

            

            fourxm->video_pts ++;



            

            get_le32(pb);

            break;



        case ifrm_TAG:

        case pfrm_TAG:

        case cfrm_TAG:

        case ifr2_TAG:

        case pfr2_TAG:

        case cfr2_TAG:

            



            if (VAR_3 + 8 < VAR_3 || av_new_packet(VAR_1, VAR_3 + 8))

                return AVERROR(EIO);

            VAR_1->stream_index = fourxm->video_stream_index;

            VAR_1->pts = fourxm->video_pts;

            VAR_1->pos = url_ftell(VAR_0->pb);

            memcpy(VAR_1->data, VAR_8, 8);

            VAR_5 = get_buffer(VAR_0->pb, &VAR_1->data[8], VAR_3);



            if (VAR_5 < 0){

                av_free_packet(VAR_1);

            }else

                VAR_7 = 1;

            break;



        case snd__TAG:

            VAR_6 = get_le32(pb);

            VAR_4= get_le32(pb);

            VAR_3-=8;



            if (VAR_6 < fourxm->track_count) {

                VAR_5= av_get_packet(VAR_0->pb, VAR_1, VAR_3);

                if(VAR_5<0)

                    return AVERROR(EIO);

                VAR_1->stream_index =

                    fourxm->tracks[VAR_6].stream_index;

                VAR_1->pts = fourxm->tracks[VAR_6].audio_pts;

                VAR_7 = 1;



                

                VAR_9 = VAR_3;

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

                    VAR_9 -=

                        2 * (fourxm->tracks[VAR_6].channels);

                VAR_9 /=

                      fourxm->tracks[VAR_6].channels;

                if (fourxm->tracks[VAR_6].adpcm){

                    VAR_9 *= 2;

                }else

                    VAR_9 /=

                    (fourxm->tracks[VAR_6].bits / 8);

                fourxm->tracks[VAR_6].audio_pts += VAR_9;



            } else {

                url_fseek(pb, VAR_3, SEEK_CUR);

            }

            break;



        default:

            url_fseek(pb, VAR_3, SEEK_CUR);

            break;

        }

    }

    return VAR_5;

}

static int FUNC_0(AVFormatContext *VAR_0,
AVPacket *VAR_1)
{ FourxmDemuxContext *fourxm = VAR_0->priv_data; ByteIOContext *pb = VAR_0->pb; unsigned int VAR_2; unsigned int VAR_3, VAR_4; int VAR_5 = 0; unsigned int VAR_6; int VAR_7 = 0; unsigned char VAR_8[8]; int VAR_9; while (!VAR_7) { if ((VAR_5 = get_buffer(VAR_0->pb, VAR_8, 8)) < 0)
return VAR_5; VAR_2 = AV_RL32(&VAR_8[0]); VAR_3 = AV_RL32(&VAR_8[4]); if (url_feof(pb))
return AVERROR(EIO); switch (VAR_2) { case LIST_TAG:
fourxm->video_pts ++; get_le32(pb); break; case ifrm_TAG:
case pfrm_TAG:
case cfrm_TAG:
case ifr2_TAG:
case pfr2_TAG:
case cfr2_TAG:
if (VAR_3 + 8 < VAR_3 || av_new_packet(VAR_1, VAR_3 + 8))
return AVERROR(EIO); VAR_1->stream_index = fourxm->video_stream_index; VAR_1->pts = fourxm->video_pts; VAR_1->pos = url_ftell(VAR_0->pb); memcpy(VAR_1->data, VAR_8, 8); VAR_5 = get_buffer(VAR_0->pb, &VAR_1->data[8], VAR_3); if (VAR_5 < 0){ av_free_packet(VAR_1); }else VAR_7 = 1; break; case snd__TAG:
VAR_6 = get_le32(pb); VAR_4= get_le32(pb); VAR_3-=8; if (VAR_6 < fourxm->track_count) { VAR_5= av_get_packet(VAR_0->pb, VAR_1, VAR_3); if(VAR_5<0)
return AVERROR(EIO); VAR_1->stream_index =
fourxm->tracks[VAR_6].stream_index; VAR_1->pts = fourxm->tracks[VAR_6].audio_pts; VAR_7 = 1; VAR_9 = VAR_3; if (fourxm->tracks[VAR_6].adpcm)
VAR_9 -=
2 * (fourxm->tracks[VAR_6].channels); VAR_9 /=
fourxm->tracks[VAR_6].channels; if (fourxm->tracks[VAR_6].adpcm){ VAR_9 *= 2; }else VAR_9 /=
(fourxm->tracks[VAR_6].bits / 8); fourxm->tracks[VAR_6].audio_pts += VAR_9; } else { url_fseek(pb, VAR_3, SEEK_CUR); } break; default:
url_fseek(pb, VAR_3, SEEK_CUR); break; } } return VAR_5; }