/* 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->codecpar->codec_type  = AVMEDIA_TYPE_VIDEO;
    st->codecpar->codec_id    = video->codec;
    // parsing is necessary to make FFmpeg generate correct timestamps
    if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO)
        st->need_parsing = AVSTREAM_PARSE_HEADERS;
    st->codecpar->codec_tag   = 0; /* no fourcc */
    st->codecpar->width       = video->width;
    st->codecpar->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 || ea->bytes > 2) {
            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->codecpar->codec_type            = AVMEDIA_TYPE_AUDIO;
        st->codecpar->codec_id              = ea->audio_codec;
        st->codecpar->codec_tag             = 0;   /* no tag */
        st->codecpar->channels              = ea->num_channels;
        st->codecpar->sample_rate           = ea->sample_rate;
        st->codecpar->bits_per_coded_sample = ea->bytes * 8;
        st->codecpar->bit_rate              = (int64_t)st->codecpar->channels *
                                              st->codecpar->sample_rate *
                                              st->codecpar->bits_per_coded_sample / 4;
        st->codecpar->block_align           = st->codecpar->channels *
                                              st->codecpar->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,
};
