/* Electronic Arts Multimedia File Demuxer
 * Copyright (c) 2004 The FFmpeg Project
 * Copyright (c) 2006-2008 Peter Ross
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Electronic Arts Multimedia file demuxer (WVE/UV2/etc.)
 * by Robin Kay (komadori at gekkou.co.uk)
 */

#include <inttypes.h>

#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "internal.h"

#define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
#define SEAD_TAG MKTAG('S', 'E', 'A', 'D')  /* Sxxx header */
#define SNDC_TAG MKTAG('S', 'N', 'D', 'C')  /* Sxxx data */
#define SEND_TAG MKTAG('S', 'E', 'N', 'D')  /* Sxxx end */
#define SHEN_TAG MKTAG('S', 'H', 'E', 'N')  /* SxEN header */
#define SDEN_TAG MKTAG('S', 'D', 'E', 'N')  /* SxEN data */
#define SEEN_TAG MKTAG('S', 'E', 'E', 'N')  /* SxEN end */
#define ISNh_TAG MKTAG('1', 'S', 'N', 'h')  /* 1SNx header */
#define EACS_TAG MKTAG('E', 'A', 'C', 'S')
#define ISNd_TAG MKTAG('1', 'S', 'N', 'd')  /* 1SNx data */
#define ISNe_TAG MKTAG('1', 'S', 'N', 'e')  /* 1SNx end */
#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
#define GSTR_TAG MKTAG('G', 'S', 'T', 'R')
#define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
#define SCEl_TAG MKTAG('S', 'C', 'E', 'l')
#define kVGT_TAG MKTAG('k', 'V', 'G', 'T')  /* TGV I-frame */
#define fVGT_TAG MKTAG('f', 'V', 'G', 'T')  /* TGV P-frame */
#define mTCD_TAG MKTAG('m', 'T', 'C', 'D')  /* MDEC */
#define MADk_TAG MKTAG('M', 'A', 'D', 'k')  /* MAD I-frame */
#define MADm_TAG MKTAG('M', 'A', 'D', 'm')  /* MAD P-frame */
#define MADe_TAG MKTAG('M', 'A', 'D', 'e')  /* MAD lqp-frame */
#define MPCh_TAG MKTAG('M', 'P', 'C', 'h')  /* MPEG-2 */
#define TGQs_TAG MKTAG('T', 'G', 'Q', 's')  /* TGQ I-frame (appears in .TGQ files) */
#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T')  /* TGQ I-frame (appears in .UV files) */
#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T')  /* TQI/UV2 I-frame (.UV2/.WVE) */
#define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
#define MV0K_TAG MKTAG('M', 'V', '0', 'K')
#define MV0F_TAG MKTAG('M', 'V', '0', 'F')
#define AVhd_TAG MKTAG('A', 'V', 'h', 'd')
#define AV0K_TAG MKTAG('A', 'V', '0', 'K')
#define AV0F_TAG MKTAG('A', 'V', '0', 'F')
#define MVIh_TAG MKTAG('M', 'V', 'I', 'h')  /* CMV header */
#define MVIf_TAG MKTAG('M', 'V', 'I', 'f')  /* CMV I-frame */
#define AVP6_TAG MKTAG('A', 'V', 'P', '6')

typedef struct VideoProperties {
    enum AVCodecID codec;
    AVRational time_base;
    int width, height;
    int nb_frames;
    int stream_index;
} VideoProperties;

typedef struct EaDemuxContext {
    int big_endian;

    VideoProperties video, alpha;

    enum AVCodecID audio_codec;
    int audio_stream_index;

    int bytes;
    int sample_rate;
    int num_channels;
    int num_samples;

    int platform;
} EaDemuxContext;

static uint32_t read_arbitrary(AVIOContext *pb)
{
    uint8_t size, byte;
    int i;
    uint32_t word;

    size = avio_r8(pb);

    word = 0;
    for (i = 0; i < size; i++) {
        byte   = avio_r8(pb);
        word <<= 8;
        word  |= byte;
    }

    return word;
}

static int process_audio_header_elements(AVFormatContext *s)
{
    EaDemuxContext *ea = s->priv_data;
    AVIOContext    *pb = s->pb;
    int in_header = 1;
    int compression_type = -1, revision = -1, revision2 = -1;

    ea->bytes        = 2;
    ea->sample_rate  = -1;
    ea->num_channels = 1;

    while (!avio_feof(pb) && in_header) {
        int in_subheader;
        uint8_t byte;
        byte = avio_r8(pb);

        switch (byte) {
        case 0xFD:
            av_log(s, AV_LOG_DEBUG, "entered audio subheader\n");
            in_subheader = 1;
            while (!avio_feof(pb) && in_subheader) {
                uint8_t subbyte;
                subbyte = avio_r8(pb);

                switch (subbyte) {
                case 0x80:
                    revision = read_arbitrary(pb);
                    av_log(s, AV_LOG_DEBUG,
                           "revision (element 0x80) set to 0x%08x\n", revision);
                    break;
                case 0x82:
                    ea->num_channels = read_arbitrary(pb);
                    av_log(s, AV_LOG_DEBUG,
                           "num_channels (element 0x82) set to 0x%08x\n",
                           ea->num_channels);
                    break;
                case 0x83:
                    compression_type = read_arbitrary(pb);
                    av_log(s, AV_LOG_DEBUG,
                           "compression_type (element 0x83) set to 0x%08x\n",
                           compression_type);
                    break;
                case 0x84:
                    ea->sample_rate = read_arbitrary(pb);
                    av_log(s, AV_LOG_DEBUG,
                           "sample_rate (element 0x84) set to %i\n",
                           ea->sample_rate);
                    break;
                case 0x85:
                    ea->num_samples = read_arbitrary(pb);
                    av_log(s, AV_LOG_DEBUG,
                           "num_samples (element 0x85) set to 0x%08x\n",
                           ea->num_samples);
                    break;
                case 0x8A:
                    av_log(s, AV_LOG_DEBUG,
                           "element 0x%02x set to 0x%08"PRIx32"\n",
                           subbyte, read_arbitrary(pb));
                    av_log(s, AV_LOG_DEBUG, "exited audio subheader\n");
                    in_subheader = 0;
                    break;
                case 0xA0:
                    revision2 = read_arbitrary(pb);
                    av_log(s, AV_LOG_DEBUG,
                           "revision2 (element 0xA0) set to 0x%08x\n",
                           revision2);
                    break;
                case 0xFF:
                    av_log(s, AV_LOG_DEBUG,
                           "end of header block reached (within audio subheader)\n");
                    in_subheader = 0;
                    in_header    = 0;
                    break;
                default:
                    av_log(s, AV_LOG_DEBUG,
                           "element 0x%02x set to 0x%08"PRIx32"\n",
                           subbyte, read_arbitrary(pb));
                    break;
                }
            }
            break;
        case 0xFF:
            av_log(s, AV_LOG_DEBUG, "end of header block reached\n");
            in_header = 0;
            break;
        default:
            av_log(s, AV_LOG_DEBUG,
                   "header element 0x%02x set to 0x%08"PRIx32"\n",
                   byte, read_arbitrary(pb));
            break;
        }
    }

    switch (compression_type) {
    case  0:
        ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
        break;
    case  7:
        ea->audio_codec = AV_CODEC_ID_ADPCM_EA;
        break;
    case -1:
        switch (revision) {
        case  1:
            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1;
            break;
        case  2:
            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2;
            break;
        case  3:
            ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3;
            break;
        case -1:
            break;
        default:
            avpriv_request_sample(s, "stream type; revision=%i", revision);
            return 0;
        }
        switch (revision2) {
        case  8:
            ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR;
            break;
        case 10:
            switch (revision) {
            case -1:
            case  2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break;
            case  3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break;
            default:
                avpriv_request_sample(s, "stream type; revision=%i, revision2=%i", revision, revision2);
                return 0;
            }
            break;
        case 15:
        case 16:
            ea->audio_codec = AV_CODEC_ID_MP3;
            break;
        case -1:
            break;
        default:
            ea->audio_codec = AV_CODEC_ID_NONE;
            avpriv_request_sample(s, "stream type; revision2=%i", revision2);
            return 0;
        }
        break;
    default:
        avpriv_request_sample(s,
                              "stream type; compression_type=%i",
                              compression_type);
        return 0;
    }

    if (ea->audio_codec == AV_CODEC_ID_NONE && ea->platform == 0x01)
        ea->audio_codec = AV_CODEC_ID_ADPCM_PSX;
    if (ea->sample_rate == -1)
        ea->sample_rate = revision == 3 ? 48000 : 22050;

    return 1;
}

static void process_audio_header_eacs(AVFormatContext *s)
{
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;
    int compression_type;

    ea->sample_rate  = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
    ea->bytes        = avio_r8(pb);   /* 1=8-bit, 2=16-bit */
    ea->num_channels = avio_r8(pb);
    compression_type = avio_r8(pb);
    avio_skip(pb, 13);

    switch (compression_type) {
    case 0:
        switch (ea->bytes) {
        case 1:
            ea->audio_codec = AV_CODEC_ID_PCM_S8;
            break;
        case 2:
            ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
            break;
        }
        break;
    case 1:
        ea->audio_codec = AV_CODEC_ID_PCM_MULAW;
        ea->bytes       = 1;
        break;
    case 2:
        ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS;
        break;
    default:
        avpriv_request_sample(s,
                              "stream type; audio compression_type=%i",
                              compression_type);
    }
}

static void process_audio_header_sead(AVFormatContext *s)
{
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;

    ea->sample_rate  = avio_rl32(pb);
    ea->bytes        = avio_rl32(pb);  /* 1=8-bit, 2=16-bit */
    ea->num_channels = avio_rl32(pb);
    ea->audio_codec  = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
}

static void process_video_header_mdec(AVFormatContext *s, VideoProperties *video)
{
    AVIOContext *pb    = s->pb;
    avio_skip(pb, 4);
    video->width       = avio_rl16(pb);
    video->height      = avio_rl16(pb);
    video->time_base   = (AVRational) { 1, 15 };
    video->codec = AV_CODEC_ID_MDEC;
}

static int process_video_header_vp6(AVFormatContext *s, VideoProperties *video)
{
    AVIOContext *pb = s->pb;

    avio_skip(pb, 8);
    video->nb_frames = avio_rl32(pb);
    avio_skip(pb, 4);
    video->time_base.den = avio_rl32(pb);
    video->time_base.num = avio_rl32(pb);
    if (video->time_base.den <= 0 || video->time_base.num <= 0) {
        av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
        return AVERROR_INVALIDDATA;
    }
    video->codec   = AV_CODEC_ID_VP6;

    return 1;
}

static void process_video_header_cmv(AVFormatContext *s, VideoProperties *video)
{
    int fps;

    avio_skip(s->pb, 10);
    fps = avio_rl16(s->pb);
    if (fps)
        video->time_base = (AVRational) { 1, fps };
    video->codec = AV_CODEC_ID_CMV;
}

/* Process EA file header.
 * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
static int process_ea_header(AVFormatContext *s)
{
    uint32_t blockid, size = 0;
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;
    int i;

    for (i = 0; i < 5 && (!ea->audio_codec || !ea->video.codec); i++) {
        uint64_t startpos     = avio_tell(pb);
        int err               = 0;

        blockid = avio_rl32(pb);
        size    = avio_rl32(pb);
        if (i == 0)
            ea->big_endian = size > av_bswap32(size);
        if (ea->big_endian)
            size = av_bswap32(size);

        if (size < 8) {
            av_log(s, AV_LOG_ERROR, "chunk size too small\n");
            return AVERROR_INVALIDDATA;
        }

        switch (blockid) {
        case ISNh_TAG:
            if (avio_rl32(pb) != EACS_TAG) {
                avpriv_request_sample(s, "unknown 1SNh headerid");
                return 0;
            }
            process_audio_header_eacs(s);
            break;

        case SCHl_TAG:
        case SHEN_TAG:
            blockid = avio_rl32(pb);
            if (blockid == GSTR_TAG) {
                avio_skip(pb, 4);
            } else if ((blockid & 0xFF) != (PT00_TAG & 0xFF)) {
                blockid = avio_rl32(pb);
            }
            ea->platform = (blockid >> 16) & 0xFF;
            err = process_audio_header_elements(s);
            break;

        case SEAD_TAG:
            process_audio_header_sead(s);
            break;

        case MVIh_TAG:
            process_video_header_cmv(s, &ea->video);
            break;

        case kVGT_TAG:
            ea->video.codec = AV_CODEC_ID_TGV;
            break;

        case mTCD_TAG:
            process_video_header_mdec(s, &ea->video);
            break;

        case MPCh_TAG:
            ea->video.codec = AV_CODEC_ID_MPEG2VIDEO;
            break;

        case pQGT_TAG:
        case TGQs_TAG:
            ea->video.codec = AV_CODEC_ID_TGQ;
            ea->video.time_base   = (AVRational) { 1, 15 };
            break;

        case pIQT_TAG:
            ea->video.codec = AV_CODEC_ID_TQI;
            ea->video.time_base   = (AVRational) { 1, 15 };
            break;

        case MADk_TAG:
            ea->video.codec = AV_CODEC_ID_MAD;
            avio_skip(pb, 6);
            ea->video.time_base = (AVRational) { avio_rl16(pb), 1000 };
            break;

        case MVhd_TAG:
            err = process_video_header_vp6(s, &ea->video);
            break;

        case AVhd_TAG:
            err = process_video_header_vp6(s, &ea->alpha);
            break;
        }

        if (err < 0) {
            av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err);
            return err;
        }

        avio_seek(pb, startpos + size, SEEK_SET);
    }

    avio_seek(pb, 0, SEEK_SET);

    return 1;
}

static int ea_probe(AVProbeData *p)
{
    unsigned big_endian, size;

    switch (AV_RL32(&p->buf[0])) {
    case ISNh_TAG:
    case SCHl_TAG:
    case SEAD_TAG:
    case SHEN_TAG:
    case kVGT_TAG:
    case MADk_TAG:
    case MPCh_TAG:
    case MVhd_TAG:
    case MVIh_TAG:
    case AVP6_TAG:
        break;
    default:
        return 0;
    }
    size = AV_RL32(&p->buf[4]);
    big_endian = size > 0x000FFFFF;
    if (big_endian)
        size = av_bswap32(size);
    if (size > 0xfffff || size < 8)
        return 0;

    return AVPROBE_SCORE_MAX;
}

static int init_video_stream(AVFormatContext *s, VideoProperties *video)
{
    AVStream *st;

    if (!video->codec)
        return 0;

    /* initialize the video decoder stream */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    video->stream_index = st->index;
    st->codec->codec_type  = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id    = video->codec;
    // parsing is necessary to make FFmpeg generate correct timestamps
    if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
        st->need_parsing = AVSTREAM_PARSE_HEADERS;
    st->codec->codec_tag   = 0; /* no fourcc */
    st->codec->width       = video->width;
    st->codec->height      = video->height;
    st->duration           = st->nb_frames = video->nb_frames;
    if (video->time_base.num)
        avpriv_set_pts_info(st, 64, video->time_base.num, video->time_base.den);
    st->r_frame_rate       =
    st->avg_frame_rate     = av_inv_q(video->time_base);
    return 0;
}

static int ea_read_header(AVFormatContext *s)
{
    EaDemuxContext *ea = s->priv_data;
    AVStream *st;

    if (process_ea_header(s)<=0)
        return AVERROR(EIO);

    if (init_video_stream(s, &ea->video) || init_video_stream(s, &ea->alpha))
        return AVERROR(ENOMEM);

    if (ea->audio_codec) {
        if (ea->num_channels <= 0 || ea->num_channels > 2) {
            av_log(s, AV_LOG_WARNING,
                   "Unsupported number of channels: %d\n", ea->num_channels);
            ea->audio_codec = 0;
            return 1;
        }
        if (ea->sample_rate <= 0) {
            av_log(s, AV_LOG_ERROR,
                   "Unsupported sample rate: %d\n", ea->sample_rate);
            ea->audio_codec = 0;
            return 1;
        }
        if (ea->bytes <= 0) {
            av_log(s, AV_LOG_ERROR,
                   "Invalid number of bytes per sample: %d\n", ea->bytes);
            ea->audio_codec = AV_CODEC_ID_NONE;
            return 1;
        }

        /* initialize the audio decoder stream */
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        avpriv_set_pts_info(st, 33, 1, ea->sample_rate);
        st->codec->codec_type            = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id              = ea->audio_codec;
        st->codec->codec_tag             = 0;   /* no tag */
        st->codec->channels              = ea->num_channels;
        st->codec->sample_rate           = ea->sample_rate;
        st->codec->bits_per_coded_sample = ea->bytes * 8;
        st->codec->bit_rate              = st->codec->channels *
                                           st->codec->sample_rate *
                                           st->codec->bits_per_coded_sample / 4;
        st->codec->block_align           = st->codec->channels *
                                           st->codec->bits_per_coded_sample;
        ea->audio_stream_index           = st->index;
        st->start_time                   = 0;
    }

    return 1;
}

static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;
    int partial_packet = 0;
    unsigned int chunk_type, chunk_size;
    int ret = 0, packet_read = 0, key = 0;
    int av_uninit(num_samples);

    while (!packet_read || partial_packet) {
        chunk_type = avio_rl32(pb);
        chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
        if (chunk_size < 8)
            return AVERROR_INVALIDDATA;
        chunk_size -= 8;

        switch (chunk_type) {
        /* audio data */
        case ISNh_TAG:
            /* header chunk also contains data; skip over the header portion */
            if (chunk_size < 32)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 32);
            chunk_size -= 32;
        case ISNd_TAG:
        case SCDl_TAG:
        case SNDC_TAG:
        case SDEN_TAG:
            if (!ea->audio_codec) {
                avio_skip(pb, chunk_size);
                break;
            } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR ||
                       ea->audio_codec == AV_CODEC_ID_MP3) {
                num_samples = avio_rl32(pb);
                avio_skip(pb, 8);
                chunk_size -= 12;
            } else if (ea->audio_codec == AV_CODEC_ID_ADPCM_PSX) {
                avio_skip(pb, 8);
                chunk_size -= 8;
            }

            if (partial_packet) {
                avpriv_request_sample(s, "video header followed by audio packet");
                av_packet_unref(pkt);
                partial_packet = 0;
            }

            if (!chunk_size)
                continue;

            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0)
                return ret;
            pkt->stream_index = ea->audio_stream_index;

            switch (ea->audio_codec) {
            case AV_CODEC_ID_ADPCM_EA:
            case AV_CODEC_ID_ADPCM_EA_R1:
            case AV_CODEC_ID_ADPCM_EA_R2:
            case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
            case AV_CODEC_ID_ADPCM_EA_R3:
                if (pkt->size < 4) {
                    av_log(s, AV_LOG_ERROR, "Packet is too short\n");
                    av_packet_unref(pkt);
                    return AVERROR_INVALIDDATA;
                }
                if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3)
                    pkt->duration = AV_RB32(pkt->data);
                else
                    pkt->duration = AV_RL32(pkt->data);
                break;
            case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
                pkt->duration = ret * 2 / ea->num_channels;
                break;
            case AV_CODEC_ID_PCM_S16LE_PLANAR:
            case AV_CODEC_ID_MP3:
                pkt->duration = num_samples;
                break;
            case AV_CODEC_ID_ADPCM_PSX:
                pkt->duration = chunk_size / (16 * ea->num_channels) * 28;
                break;
            default:
                pkt->duration = chunk_size / (ea->bytes * ea->num_channels);
            }

            packet_read = 1;
            break;

        /* ending tag */
        case 0:
        case ISNe_TAG:
        case SCEl_TAG:
        case SEND_TAG:
        case SEEN_TAG:
            while (!avio_feof(pb)) {
                int tag = avio_rl32(pb);

                if (tag == ISNh_TAG ||
                    tag == SCHl_TAG ||
                    tag == SEAD_TAG ||
                    tag == SHEN_TAG) {
                    avio_skip(pb, -4);
                    break;
                }
            }
            if (avio_feof(pb))
                ret = AVERROR_EOF;
            packet_read = 1;
            break;

        case MVIh_TAG:
        case kVGT_TAG:
        case pQGT_TAG:
        case TGQs_TAG:
        case MADk_TAG:
            key = AV_PKT_FLAG_KEY;
        case MVIf_TAG:
        case fVGT_TAG:
        case MADm_TAG:
        case MADe_TAG:
            avio_seek(pb, -8, SEEK_CUR);    // include chunk preamble
            chunk_size += 8;
            goto get_video_packet;

        case mTCD_TAG:
            if (chunk_size < 8)
                return AVERROR_INVALIDDATA;

            avio_skip(pb, 8);               // skip ea DCT header
            chunk_size -= 8;
            goto get_video_packet;

        case MV0K_TAG:
        case AV0K_TAG:
        case MPCh_TAG:
        case pIQT_TAG:
            key = AV_PKT_FLAG_KEY;
        case MV0F_TAG:
        case AV0F_TAG:
get_video_packet:
            if (!chunk_size)
                continue;

            if (partial_packet) {
                ret = av_append_packet(pb, pkt, chunk_size);
            } else
                ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0) {
                packet_read = 1;
                break;
            }
            partial_packet = chunk_type == MVIh_TAG;
            if (chunk_type == AV0K_TAG || chunk_type == AV0F_TAG)
                pkt->stream_index = ea->alpha.stream_index;
            else
                pkt->stream_index = ea->video.stream_index;
            pkt->flags       |= key;
            packet_read       = 1;
            break;

        default:
            avio_skip(pb, chunk_size);
            break;
        }
    }

    if (ret < 0 && partial_packet)
        av_packet_unref(pkt);
    return ret;
}

AVInputFormat ff_ea_demuxer = {
    .name           = "ea",
    .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia"),
    .priv_data_size = sizeof(EaDemuxContext),
    .read_probe     = ea_probe,
    .read_header    = ea_read_header,
    .read_packet    = ea_read_packet,
};
