static int film_read_packet(AVFormatContext *s,

                            AVPacket *pkt)

{

    FilmDemuxContext *film = s->priv_data;

    AVIOContext *pb = s->pb;

    film_sample *sample;

    int ret = 0;

    int i;

    int left, right;



    if (film->current_sample >= film->sample_count)

        return AVERROR(EIO);



    sample = &film->sample_table[film->current_sample];



    /* position the stream (will probably be there anyway) */

    avio_seek(pb, sample->sample_offset, SEEK_SET);



    /* do a special song and dance when loading FILM Cinepak chunks */

    if ((sample->stream == film->video_stream_index) &&

        (film->video_type == AV_CODEC_ID_CINEPAK)) {

        pkt->pos= avio_tell(pb);

        if (av_new_packet(pkt, sample->sample_size))

            return AVERROR(ENOMEM);

        avio_read(pb, pkt->data, sample->sample_size);

    } else if ((sample->stream == film->audio_stream_index) &&

        (film->audio_channels == 2) &&

        (film->audio_type != AV_CODEC_ID_ADPCM_ADX)) {

        /* stereo PCM needs to be interleaved */



        if (av_new_packet(pkt, sample->sample_size))

            return AVERROR(ENOMEM);



        /* make sure the interleave buffer is large enough */

        if (sample->sample_size > film->stereo_buffer_size) {

            av_free(film->stereo_buffer);

            film->stereo_buffer_size = sample->sample_size;

            film->stereo_buffer = av_malloc(film->stereo_buffer_size);

            if (!film->stereo_buffer) {

                film->stereo_buffer_size = 0;

                return AVERROR(ENOMEM);

            }

        }



        pkt->pos= avio_tell(pb);

        ret = avio_read(pb, film->stereo_buffer, sample->sample_size);

        if (ret != sample->sample_size)

            ret = AVERROR(EIO);



        left = 0;

        right = sample->sample_size / 2;

        for (i = 0; i < sample->sample_size; ) {

            if (film->audio_bits == 8) {

                pkt->data[i++] = film->stereo_buffer[left++];

                pkt->data[i++] = film->stereo_buffer[right++];

            } else {

                pkt->data[i++] = film->stereo_buffer[left++];

                pkt->data[i++] = film->stereo_buffer[left++];

                pkt->data[i++] = film->stereo_buffer[right++];

                pkt->data[i++] = film->stereo_buffer[right++];

            }

        }

    } else {

        ret= av_get_packet(pb, pkt, sample->sample_size);

        if (ret != sample->sample_size)

            ret = AVERROR(EIO);

    }



    pkt->stream_index = sample->stream;

    pkt->pts = sample->pts;



    film->current_sample++;



    return ret;

}
