LCOV - code coverage report
Current view: top level - src/libavformat - electronicarts.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 308 377 81.7 %
Date: 2017-01-24 04:42:20 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /* Electronic Arts Multimedia File Demuxer
       2             :  * Copyright (c) 2004  The FFmpeg project
       3             :  * Copyright (c) 2006-2008 Peter Ross
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * Electronic Arts Multimedia file demuxer (WVE/UV2/etc.)
      25             :  * by Robin Kay (komadori at gekkou.co.uk)
      26             :  */
      27             : 
      28             : #include <inttypes.h>
      29             : 
      30             : #include "libavutil/intreadwrite.h"
      31             : #include "avformat.h"
      32             : #include "internal.h"
      33             : 
      34             : #define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
      35             : #define SEAD_TAG MKTAG('S', 'E', 'A', 'D')  /* Sxxx header */
      36             : #define SNDC_TAG MKTAG('S', 'N', 'D', 'C')  /* Sxxx data */
      37             : #define SEND_TAG MKTAG('S', 'E', 'N', 'D')  /* Sxxx end */
      38             : #define SHEN_TAG MKTAG('S', 'H', 'E', 'N')  /* SxEN header */
      39             : #define SDEN_TAG MKTAG('S', 'D', 'E', 'N')  /* SxEN data */
      40             : #define SEEN_TAG MKTAG('S', 'E', 'E', 'N')  /* SxEN end */
      41             : #define ISNh_TAG MKTAG('1', 'S', 'N', 'h')  /* 1SNx header */
      42             : #define EACS_TAG MKTAG('E', 'A', 'C', 'S')
      43             : #define ISNd_TAG MKTAG('1', 'S', 'N', 'd')  /* 1SNx data */
      44             : #define ISNe_TAG MKTAG('1', 'S', 'N', 'e')  /* 1SNx end */
      45             : #define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
      46             : #define GSTR_TAG MKTAG('G', 'S', 'T', 'R')
      47             : #define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
      48             : #define SCEl_TAG MKTAG('S', 'C', 'E', 'l')
      49             : #define kVGT_TAG MKTAG('k', 'V', 'G', 'T')  /* TGV I-frame */
      50             : #define fVGT_TAG MKTAG('f', 'V', 'G', 'T')  /* TGV P-frame */
      51             : #define mTCD_TAG MKTAG('m', 'T', 'C', 'D')  /* MDEC */
      52             : #define MADk_TAG MKTAG('M', 'A', 'D', 'k')  /* MAD I-frame */
      53             : #define MADm_TAG MKTAG('M', 'A', 'D', 'm')  /* MAD P-frame */
      54             : #define MADe_TAG MKTAG('M', 'A', 'D', 'e')  /* MAD lqp-frame */
      55             : #define MPCh_TAG MKTAG('M', 'P', 'C', 'h')  /* MPEG-2 */
      56             : #define TGQs_TAG MKTAG('T', 'G', 'Q', 's')  /* TGQ I-frame (appears in .TGQ files) */
      57             : #define pQGT_TAG MKTAG('p', 'Q', 'G', 'T')  /* TGQ I-frame (appears in .UV files) */
      58             : #define pIQT_TAG MKTAG('p', 'I', 'Q', 'T')  /* TQI/UV2 I-frame (.UV2/.WVE) */
      59             : #define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
      60             : #define MV0K_TAG MKTAG('M', 'V', '0', 'K')
      61             : #define MV0F_TAG MKTAG('M', 'V', '0', 'F')
      62             : #define AVhd_TAG MKTAG('A', 'V', 'h', 'd')
      63             : #define AV0K_TAG MKTAG('A', 'V', '0', 'K')
      64             : #define AV0F_TAG MKTAG('A', 'V', '0', 'F')
      65             : #define MVIh_TAG MKTAG('M', 'V', 'I', 'h')  /* CMV header */
      66             : #define MVIf_TAG MKTAG('M', 'V', 'I', 'f')  /* CMV I-frame */
      67             : #define AVP6_TAG MKTAG('A', 'V', 'P', '6')
      68             : 
      69             : typedef struct VideoProperties {
      70             :     enum AVCodecID codec;
      71             :     AVRational time_base;
      72             :     int width, height;
      73             :     int nb_frames;
      74             :     int stream_index;
      75             : } VideoProperties;
      76             : 
      77             : typedef struct EaDemuxContext {
      78             :     int big_endian;
      79             : 
      80             :     VideoProperties video, alpha;
      81             : 
      82             :     enum AVCodecID audio_codec;
      83             :     int audio_stream_index;
      84             : 
      85             :     int bytes;
      86             :     int sample_rate;
      87             :     int num_channels;
      88             :     int num_samples;
      89             : 
      90             :     int platform;
      91             : } EaDemuxContext;
      92             : 
      93          64 : static uint32_t read_arbitrary(AVIOContext *pb)
      94             : {
      95             :     uint8_t size, byte;
      96             :     int i;
      97             :     uint32_t word;
      98             : 
      99          64 :     size = avio_r8(pb);
     100             : 
     101          64 :     word = 0;
     102         182 :     for (i = 0; i < size; i++) {
     103         118 :         byte   = avio_r8(pb);
     104         118 :         word <<= 8;
     105         118 :         word  |= byte;
     106             :     }
     107             : 
     108          64 :     return word;
     109             : }
     110             : 
     111           9 : static int process_audio_header_elements(AVFormatContext *s)
     112             : {
     113           9 :     EaDemuxContext *ea = s->priv_data;
     114           9 :     AVIOContext    *pb = s->pb;
     115           9 :     int in_header = 1;
     116           9 :     int compression_type = -1, revision = -1, revision2 = -1;
     117             : 
     118           9 :     ea->bytes        = 2;
     119           9 :     ea->sample_rate  = -1;
     120           9 :     ea->num_channels = 1;
     121             : 
     122          53 :     while (!avio_feof(pb) && in_header) {
     123             :         int in_subheader;
     124             :         uint8_t byte;
     125          35 :         byte = avio_r8(pb);
     126             : 
     127          35 :         switch (byte) {
     128             :         case 0xFD:
     129           9 :             av_log(s, AV_LOG_DEBUG, "entered audio subheader\n");
     130           9 :             in_subheader = 1;
     131          65 :             while (!avio_feof(pb) && in_subheader) {
     132             :                 uint8_t subbyte;
     133          47 :                 subbyte = avio_r8(pb);
     134             : 
     135          47 :                 switch (subbyte) {
     136             :                 case 0x80:
     137           5 :                     revision = read_arbitrary(pb);
     138           5 :                     av_log(s, AV_LOG_DEBUG,
     139             :                            "revision (element 0x80) set to 0x%08x\n", revision);
     140           5 :                     break;
     141             :                 case 0x82:
     142           9 :                     ea->num_channels = read_arbitrary(pb);
     143           9 :                     av_log(s, AV_LOG_DEBUG,
     144             :                            "num_channels (element 0x82) set to 0x%08x\n",
     145             :                            ea->num_channels);
     146           9 :                     break;
     147             :                 case 0x83:
     148           4 :                     compression_type = read_arbitrary(pb);
     149           4 :                     av_log(s, AV_LOG_DEBUG,
     150             :                            "compression_type (element 0x83) set to 0x%08x\n",
     151             :                            compression_type);
     152           4 :                     break;
     153             :                 case 0x84:
     154           5 :                     ea->sample_rate = read_arbitrary(pb);
     155           5 :                     av_log(s, AV_LOG_DEBUG,
     156             :                            "sample_rate (element 0x84) set to %i\n",
     157             :                            ea->sample_rate);
     158           5 :                     break;
     159             :                 case 0x85:
     160           9 :                     ea->num_samples = read_arbitrary(pb);
     161           9 :                     av_log(s, AV_LOG_DEBUG,
     162             :                            "num_samples (element 0x85) set to 0x%08x\n",
     163             :                            ea->num_samples);
     164           9 :                     break;
     165             :                 case 0x8A:
     166           4 :                     av_log(s, AV_LOG_DEBUG,
     167             :                            "element 0x%02x set to 0x%08"PRIx32"\n",
     168             :                            subbyte, read_arbitrary(pb));
     169           4 :                     av_log(s, AV_LOG_DEBUG, "exited audio subheader\n");
     170           4 :                     in_subheader = 0;
     171           4 :                     break;
     172             :                 case 0xA0:
     173           2 :                     revision2 = read_arbitrary(pb);
     174           2 :                     av_log(s, AV_LOG_DEBUG,
     175             :                            "revision2 (element 0xA0) set to 0x%08x\n",
     176             :                            revision2);
     177           2 :                     break;
     178             :                 case 0xFF:
     179           5 :                     av_log(s, AV_LOG_DEBUG,
     180             :                            "end of header block reached (within audio subheader)\n");
     181           5 :                     in_subheader = 0;
     182           5 :                     in_header    = 0;
     183           5 :                     break;
     184             :                 default:
     185           4 :                     av_log(s, AV_LOG_DEBUG,
     186             :                            "element 0x%02x set to 0x%08"PRIx32"\n",
     187             :                            subbyte, read_arbitrary(pb));
     188           4 :                     break;
     189             :                 }
     190             :             }
     191           9 :             break;
     192             :         case 0xFF:
     193           4 :             av_log(s, AV_LOG_DEBUG, "end of header block reached\n");
     194           4 :             in_header = 0;
     195           4 :             break;
     196             :         default:
     197          22 :             av_log(s, AV_LOG_DEBUG,
     198             :                    "header element 0x%02x set to 0x%08"PRIx32"\n",
     199             :                    byte, read_arbitrary(pb));
     200          22 :             break;
     201             :         }
     202             :     }
     203             : 
     204           9 :     switch (compression_type) {
     205             :     case  0:
     206           0 :         ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
     207           0 :         break;
     208             :     case  7:
     209           4 :         ea->audio_codec = AV_CODEC_ID_ADPCM_EA;
     210           4 :         break;
     211             :     case -1:
     212           5 :         switch (revision) {
     213             :         case  1:
     214           3 :             ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1;
     215           3 :             break;
     216             :         case  2:
     217           0 :             ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2;
     218           0 :             break;
     219             :         case  3:
     220           2 :             ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3;
     221           2 :             break;
     222             :         case -1:
     223           0 :             break;
     224             :         default:
     225           0 :             avpriv_request_sample(s, "stream type; revision=%i", revision);
     226           0 :             return 0;
     227             :         }
     228           5 :         switch (revision2) {
     229             :         case  8:
     230           1 :             ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR;
     231           1 :             break;
     232             :         case 10:
     233           1 :             switch (revision) {
     234             :             case -1:
     235           0 :             case  2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break;
     236           1 :             case  3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break;
     237             :             default:
     238           0 :                 avpriv_request_sample(s, "stream type; revision=%i, revision2=%i", revision, revision2);
     239           0 :                 return 0;
     240             :             }
     241           1 :             break;
     242             :         case 15:
     243             :         case 16:
     244           0 :             ea->audio_codec = AV_CODEC_ID_MP3;
     245           0 :             break;
     246             :         case -1:
     247           3 :             break;
     248             :         default:
     249           0 :             ea->audio_codec = AV_CODEC_ID_NONE;
     250           0 :             avpriv_request_sample(s, "stream type; revision2=%i", revision2);
     251           0 :             return 0;
     252             :         }
     253           5 :         break;
     254             :     default:
     255           0 :         avpriv_request_sample(s,
     256             :                               "stream type; compression_type=%i",
     257             :                               compression_type);
     258           0 :         return 0;
     259             :     }
     260             : 
     261           9 :     if (ea->audio_codec == AV_CODEC_ID_NONE && ea->platform == 0x01)
     262           0 :         ea->audio_codec = AV_CODEC_ID_ADPCM_PSX;
     263           9 :     if (ea->sample_rate == -1)
     264           4 :         ea->sample_rate = revision == 3 ? 48000 : 22050;
     265             : 
     266           9 :     return 1;
     267             : }
     268             : 
     269           3 : static void process_audio_header_eacs(AVFormatContext *s)
     270             : {
     271           3 :     EaDemuxContext *ea = s->priv_data;
     272           3 :     AVIOContext *pb    = s->pb;
     273             :     int compression_type;
     274             : 
     275           3 :     ea->sample_rate  = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
     276           3 :     ea->bytes        = avio_r8(pb);   /* 1=8-bit, 2=16-bit */
     277           3 :     ea->num_channels = avio_r8(pb);
     278           3 :     compression_type = avio_r8(pb);
     279           3 :     avio_skip(pb, 13);
     280             : 
     281           3 :     switch (compression_type) {
     282             :     case 0:
     283           0 :         switch (ea->bytes) {
     284             :         case 1:
     285           0 :             ea->audio_codec = AV_CODEC_ID_PCM_S8;
     286           0 :             break;
     287             :         case 2:
     288           0 :             ea->audio_codec = AV_CODEC_ID_PCM_S16LE;
     289           0 :             break;
     290             :         }
     291           0 :         break;
     292             :     case 1:
     293           1 :         ea->audio_codec = AV_CODEC_ID_PCM_MULAW;
     294           1 :         ea->bytes       = 1;
     295           1 :         break;
     296             :     case 2:
     297           2 :         ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS;
     298           2 :         break;
     299             :     default:
     300           0 :         avpriv_request_sample(s,
     301             :                               "stream type; audio compression_type=%i",
     302             :                               compression_type);
     303             :     }
     304           3 : }
     305             : 
     306           2 : static void process_audio_header_sead(AVFormatContext *s)
     307             : {
     308           2 :     EaDemuxContext *ea = s->priv_data;
     309           2 :     AVIOContext *pb    = s->pb;
     310             : 
     311           2 :     ea->sample_rate  = avio_rl32(pb);
     312           2 :     ea->bytes        = avio_rl32(pb);  /* 1=8-bit, 2=16-bit */
     313           2 :     ea->num_channels = avio_rl32(pb);
     314           2 :     ea->audio_codec  = AV_CODEC_ID_ADPCM_IMA_EA_SEAD;
     315           2 : }
     316             : 
     317           2 : static void process_video_header_mdec(AVFormatContext *s, VideoProperties *video)
     318             : {
     319           2 :     AVIOContext *pb    = s->pb;
     320           2 :     avio_skip(pb, 4);
     321           2 :     video->width       = avio_rl16(pb);
     322           2 :     video->height      = avio_rl16(pb);
     323           2 :     video->time_base   = (AVRational) { 1, 15 };
     324           2 :     video->codec = AV_CODEC_ID_MDEC;
     325           2 : }
     326             : 
     327           5 : static int process_video_header_vp6(AVFormatContext *s, VideoProperties *video)
     328             : {
     329           5 :     AVIOContext *pb = s->pb;
     330             : 
     331           5 :     avio_skip(pb, 8);
     332           5 :     video->nb_frames = avio_rl32(pb);
     333           5 :     avio_skip(pb, 4);
     334           5 :     video->time_base.den = avio_rl32(pb);
     335           5 :     video->time_base.num = avio_rl32(pb);
     336           5 :     if (video->time_base.den <= 0 || video->time_base.num <= 0) {
     337           0 :         av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
     338           0 :         return AVERROR_INVALIDDATA;
     339             :     }
     340           5 :     video->codec   = AV_CODEC_ID_VP6;
     341             : 
     342           5 :     return 1;
     343             : }
     344             : 
     345           1 : static void process_video_header_cmv(AVFormatContext *s, VideoProperties *video)
     346             : {
     347             :     int fps;
     348             : 
     349           1 :     avio_skip(s->pb, 10);
     350           1 :     fps = avio_rl16(s->pb);
     351           1 :     if (fps)
     352           1 :         video->time_base = (AVRational) { 1, fps };
     353           1 :     video->codec = AV_CODEC_ID_CMV;
     354           1 : }
     355             : 
     356             : /* Process EA file header.
     357             :  * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
     358          18 : static int process_ea_header(AVFormatContext *s)
     359             : {
     360          18 :     uint32_t blockid, size = 0;
     361          18 :     EaDemuxContext *ea = s->priv_data;
     362          18 :     AVIOContext *pb    = s->pb;
     363             :     int i;
     364             : 
     365          67 :     for (i = 0; i < 5 && (!ea->audio_codec || !ea->video.codec); i++) {
     366          49 :         uint64_t startpos     = avio_tell(pb);
     367          49 :         int err               = 0;
     368             : 
     369          49 :         blockid = avio_rl32(pb);
     370          49 :         size    = avio_rl32(pb);
     371          49 :         if (i == 0)
     372          18 :             ea->big_endian = size > av_bswap32(size);
     373          49 :         if (ea->big_endian)
     374           3 :             size = av_bswap32(size);
     375             : 
     376          49 :         if (size < 8) {
     377           0 :             av_log(s, AV_LOG_ERROR, "chunk size too small\n");
     378           0 :             return AVERROR_INVALIDDATA;
     379             :         }
     380             : 
     381          49 :         switch (blockid) {
     382             :         case ISNh_TAG:
     383           3 :             if (avio_rl32(pb) != EACS_TAG) {
     384           0 :                 avpriv_request_sample(s, "unknown 1SNh headerid");
     385           0 :                 return 0;
     386             :             }
     387           3 :             process_audio_header_eacs(s);
     388           3 :             break;
     389             : 
     390             :         case SCHl_TAG:
     391             :         case SHEN_TAG:
     392           9 :             blockid = avio_rl32(pb);
     393           9 :             if (blockid == GSTR_TAG) {
     394           1 :                 avio_skip(pb, 4);
     395           8 :             } else if ((blockid & 0xFF) != (PT00_TAG & 0xFF)) {
     396           0 :                 blockid = avio_rl32(pb);
     397             :             }
     398           9 :             ea->platform = (blockid >> 16) & 0xFF;
     399           9 :             err = process_audio_header_elements(s);
     400           9 :             break;
     401             : 
     402             :         case SEAD_TAG:
     403           2 :             process_audio_header_sead(s);
     404           2 :             break;
     405             : 
     406             :         case MVIh_TAG:
     407           1 :             process_video_header_cmv(s, &ea->video);
     408           1 :             break;
     409             : 
     410             :         case kVGT_TAG:
     411           4 :             ea->video.codec = AV_CODEC_ID_TGV;
     412           4 :             break;
     413             : 
     414             :         case mTCD_TAG:
     415           2 :             process_video_header_mdec(s, &ea->video);
     416           2 :             break;
     417             : 
     418             :         case MPCh_TAG:
     419           1 :             ea->video.codec = AV_CODEC_ID_MPEG2VIDEO;
     420           1 :             break;
     421             : 
     422             :         case pQGT_TAG:
     423             :         case TGQs_TAG:
     424           1 :             ea->video.codec = AV_CODEC_ID_TGQ;
     425           1 :             ea->video.time_base   = (AVRational) { 1, 15 };
     426           1 :             break;
     427             : 
     428             :         case pIQT_TAG:
     429           2 :             ea->video.codec = AV_CODEC_ID_TQI;
     430           2 :             ea->video.time_base   = (AVRational) { 1, 15 };
     431           2 :             break;
     432             : 
     433             :         case MADk_TAG:
     434           3 :             ea->video.codec = AV_CODEC_ID_MAD;
     435           3 :             avio_skip(pb, 6);
     436           3 :             ea->video.time_base = (AVRational) { avio_rl16(pb), 1000 };
     437           3 :             break;
     438             : 
     439             :         case MVhd_TAG:
     440           4 :             err = process_video_header_vp6(s, &ea->video);
     441           4 :             break;
     442             : 
     443             :         case AVhd_TAG:
     444           1 :             err = process_video_header_vp6(s, &ea->alpha);
     445           1 :             break;
     446             :         }
     447             : 
     448          49 :         if (err < 0) {
     449           0 :             av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err);
     450           0 :             return err;
     451             :         }
     452             : 
     453          49 :         avio_seek(pb, startpos + size, SEEK_SET);
     454             :     }
     455             : 
     456          18 :     avio_seek(pb, 0, SEEK_SET);
     457             : 
     458          18 :     return 1;
     459             : }
     460             : 
     461        5563 : static int ea_probe(AVProbeData *p)
     462             : {
     463             :     unsigned big_endian, size;
     464             : 
     465        5563 :     switch (AV_RL32(&p->buf[0])) {
     466             :     case ISNh_TAG:
     467             :     case SCHl_TAG:
     468             :     case SEAD_TAG:
     469             :     case SHEN_TAG:
     470             :     case kVGT_TAG:
     471             :     case MADk_TAG:
     472             :     case MPCh_TAG:
     473             :     case MVhd_TAG:
     474             :     case MVIh_TAG:
     475             :     case AVP6_TAG:
     476          18 :         break;
     477             :     default:
     478        5545 :         return 0;
     479             :     }
     480          18 :     size = AV_RL32(&p->buf[4]);
     481          18 :     big_endian = size > 0x000FFFFF;
     482          18 :     if (big_endian)
     483           1 :         size = av_bswap32(size);
     484          18 :     if (size > 0xfffff || size < 8)
     485           0 :         return 0;
     486             : 
     487          18 :     return AVPROBE_SCORE_MAX;
     488             : }
     489             : 
     490          36 : static int init_video_stream(AVFormatContext *s, VideoProperties *video)
     491             : {
     492             :     AVStream *st;
     493             : 
     494          36 :     if (!video->codec)
     495          17 :         return 0;
     496             : 
     497             :     /* initialize the video decoder stream */
     498          19 :     st = avformat_new_stream(s, NULL);
     499          19 :     if (!st)
     500           0 :         return AVERROR(ENOMEM);
     501          19 :     video->stream_index = st->index;
     502          19 :     st->codecpar->codec_type  = AVMEDIA_TYPE_VIDEO;
     503          19 :     st->codecpar->codec_id    = video->codec;
     504             :     // parsing is necessary to make FFmpeg generate correct timestamps
     505          19 :     if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO)
     506           1 :         st->need_parsing = AVSTREAM_PARSE_HEADERS;
     507          19 :     st->codecpar->codec_tag   = 0; /* no fourcc */
     508          19 :     st->codecpar->width       = video->width;
     509          19 :     st->codecpar->height      = video->height;
     510          19 :     st->duration           = st->nb_frames = video->nb_frames;
     511          19 :     if (video->time_base.num)
     512          14 :         avpriv_set_pts_info(st, 64, video->time_base.num, video->time_base.den);
     513          19 :     st->r_frame_rate       =
     514             :     st->avg_frame_rate     = av_inv_q(video->time_base);
     515          19 :     return 0;
     516             : }
     517             : 
     518          18 : static int ea_read_header(AVFormatContext *s)
     519             : {
     520          18 :     EaDemuxContext *ea = s->priv_data;
     521             :     AVStream *st;
     522             : 
     523          18 :     if (process_ea_header(s)<=0)
     524           0 :         return AVERROR(EIO);
     525             : 
     526          18 :     if (init_video_stream(s, &ea->video) || init_video_stream(s, &ea->alpha))
     527           0 :         return AVERROR(ENOMEM);
     528             : 
     529          18 :     if (ea->audio_codec) {
     530          14 :         if (ea->num_channels <= 0 || ea->num_channels > 2) {
     531           0 :             av_log(s, AV_LOG_WARNING,
     532             :                    "Unsupported number of channels: %d\n", ea->num_channels);
     533           0 :             ea->audio_codec = 0;
     534           0 :             return 1;
     535             :         }
     536          14 :         if (ea->sample_rate <= 0) {
     537           0 :             av_log(s, AV_LOG_ERROR,
     538             :                    "Unsupported sample rate: %d\n", ea->sample_rate);
     539           0 :             ea->audio_codec = 0;
     540           0 :             return 1;
     541             :         }
     542          14 :         if (ea->bytes <= 0) {
     543           0 :             av_log(s, AV_LOG_ERROR,
     544             :                    "Invalid number of bytes per sample: %d\n", ea->bytes);
     545           0 :             ea->audio_codec = AV_CODEC_ID_NONE;
     546           0 :             return 1;
     547             :         }
     548             : 
     549             :         /* initialize the audio decoder stream */
     550          14 :         st = avformat_new_stream(s, NULL);
     551          14 :         if (!st)
     552           0 :             return AVERROR(ENOMEM);
     553          14 :         avpriv_set_pts_info(st, 33, 1, ea->sample_rate);
     554          14 :         st->codecpar->codec_type            = AVMEDIA_TYPE_AUDIO;
     555          14 :         st->codecpar->codec_id              = ea->audio_codec;
     556          14 :         st->codecpar->codec_tag             = 0;   /* no tag */
     557          14 :         st->codecpar->channels              = ea->num_channels;
     558          14 :         st->codecpar->sample_rate           = ea->sample_rate;
     559          14 :         st->codecpar->bits_per_coded_sample = ea->bytes * 8;
     560          42 :         st->codecpar->bit_rate              = (int64_t)st->codecpar->channels *
     561          28 :                                               st->codecpar->sample_rate *
     562          28 :                                               st->codecpar->bits_per_coded_sample / 4;
     563          28 :         st->codecpar->block_align           = st->codecpar->channels *
     564          14 :                                               st->codecpar->bits_per_coded_sample;
     565          14 :         ea->audio_stream_index           = st->index;
     566          14 :         st->start_time                   = 0;
     567             :     }
     568             : 
     569          18 :     return 1;
     570             : }
     571             : 
     572        3379 : static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
     573             : {
     574        3379 :     EaDemuxContext *ea = s->priv_data;
     575        3379 :     AVIOContext *pb    = s->pb;
     576        3379 :     int partial_packet = 0;
     577             :     unsigned int chunk_type, chunk_size;
     578        3379 :     int ret = 0, packet_read = 0, key = 0;
     579        3379 :     int av_uninit(num_samples);
     580             : 
     581       10153 :     while (!packet_read || partial_packet) {
     582        3410 :         chunk_type = avio_rl32(pb);
     583        3410 :         chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
     584        3410 :         if (chunk_size < 8)
     585          15 :             return AVERROR_INVALIDDATA;
     586        3395 :         chunk_size -= 8;
     587             : 
     588        3395 :         switch (chunk_type) {
     589             :         /* audio data */
     590             :         case ISNh_TAG:
     591             :             /* header chunk also contains data; skip over the header portion */
     592           3 :             if (chunk_size < 32)
     593           0 :                 return AVERROR_INVALIDDATA;
     594           3 :             avio_skip(pb, 32);
     595           3 :             chunk_size -= 32;
     596             :         case ISNd_TAG:
     597             :         case SCDl_TAG:
     598             :         case SNDC_TAG:
     599             :         case SDEN_TAG:
     600        1424 :             if (!ea->audio_codec) {
     601           0 :                 avio_skip(pb, chunk_size);
     602           0 :                 break;
     603        2706 :             } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR ||
     604        1282 :                        ea->audio_codec == AV_CODEC_ID_MP3) {
     605         142 :                 num_samples = avio_rl32(pb);
     606         142 :                 avio_skip(pb, 8);
     607         142 :                 chunk_size -= 12;
     608        1282 :             } else if (ea->audio_codec == AV_CODEC_ID_ADPCM_PSX) {
     609           0 :                 avio_skip(pb, 8);
     610           0 :                 chunk_size -= 8;
     611             :             }
     612             : 
     613        1424 :             if (partial_packet) {
     614           0 :                 avpriv_request_sample(s, "video header followed by audio packet");
     615           0 :                 av_packet_unref(pkt);
     616           0 :                 partial_packet = 0;
     617             :             }
     618             : 
     619        1424 :             if (!chunk_size)
     620           1 :                 continue;
     621             : 
     622        1423 :             ret = av_get_packet(pb, pkt, chunk_size);
     623        1423 :             if (ret < 0)
     624           0 :                 return ret;
     625        1423 :             pkt->stream_index = ea->audio_stream_index;
     626             : 
     627        1423 :             switch (ea->audio_codec) {
     628             :             case AV_CODEC_ID_ADPCM_EA:
     629             :             case AV_CODEC_ID_ADPCM_EA_R1:
     630             :             case AV_CODEC_ID_ADPCM_EA_R2:
     631             :             case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
     632             :             case AV_CODEC_ID_ADPCM_EA_R3:
     633         905 :                 if (pkt->size < 4) {
     634           0 :                     av_log(s, AV_LOG_ERROR, "Packet is too short\n");
     635           0 :                     av_packet_unref(pkt);
     636           0 :                     return AVERROR_INVALIDDATA;
     637             :                 }
     638         905 :                 if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3)
     639         125 :                     pkt->duration = AV_RB32(pkt->data);
     640             :                 else
     641         780 :                     pkt->duration = AV_RL32(pkt->data);
     642         905 :                 break;
     643             :             case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
     644          98 :                 pkt->duration = ret * 2 / ea->num_channels;
     645          98 :                 break;
     646             :             case AV_CODEC_ID_PCM_S16LE_PLANAR:
     647             :             case AV_CODEC_ID_MP3:
     648         142 :                 pkt->duration = num_samples;
     649         142 :                 break;
     650             :             case AV_CODEC_ID_ADPCM_PSX:
     651           0 :                 pkt->duration = chunk_size / (16 * ea->num_channels) * 28;
     652           0 :                 break;
     653             :             default:
     654         278 :                 pkt->duration = chunk_size / (ea->bytes * ea->num_channels);
     655             :             }
     656             : 
     657        1423 :             packet_read = 1;
     658        1423 :             break;
     659             : 
     660             :         /* ending tag */
     661             :         case 0:
     662             :         case ISNe_TAG:
     663             :         case SCEl_TAG:
     664             :         case SEND_TAG:
     665             :         case SEEN_TAG:
     666        3864 :             while (!avio_feof(pb)) {
     667        3848 :                 int tag = avio_rl32(pb);
     668             : 
     669        3848 :                 if (tag == ISNh_TAG ||
     670        3848 :                     tag == SCHl_TAG ||
     671        3848 :                     tag == SEAD_TAG ||
     672             :                     tag == SHEN_TAG) {
     673           0 :                     avio_skip(pb, -4);
     674           0 :                     break;
     675             :                 }
     676             :             }
     677           8 :             if (avio_feof(pb))
     678           8 :                 ret = AVERROR_EOF;
     679           8 :             packet_read = 1;
     680           8 :             break;
     681             : 
     682             :         case MVIh_TAG:
     683             :         case kVGT_TAG:
     684             :         case pQGT_TAG:
     685             :         case TGQs_TAG:
     686             :         case MADk_TAG:
     687         329 :             key = AV_PKT_FLAG_KEY;
     688             :         case MVIf_TAG:
     689             :         case fVGT_TAG:
     690             :         case MADm_TAG:
     691             :         case MADe_TAG:
     692         983 :             avio_seek(pb, -8, SEEK_CUR);    // include chunk preamble
     693         983 :             chunk_size += 8;
     694         983 :             goto get_video_packet;
     695             : 
     696             :         case mTCD_TAG:
     697         270 :             if (chunk_size < 8)
     698           0 :                 return AVERROR_INVALIDDATA;
     699             : 
     700         270 :             avio_skip(pb, 8);               // skip ea DCT header
     701         270 :             chunk_size -= 8;
     702         270 :             goto get_video_packet;
     703             : 
     704             :         case MV0K_TAG:
     705             :         case AV0K_TAG:
     706             :         case MPCh_TAG:
     707             :         case pIQT_TAG:
     708         220 :             key = AV_PKT_FLAG_KEY;
     709             :         case MV0F_TAG:
     710             :         case AV0F_TAG:
     711             : get_video_packet:
     712        1935 :             if (!chunk_size)
     713           0 :                 continue;
     714             : 
     715        1935 :             if (partial_packet) {
     716           2 :                 ret = av_append_packet(pb, pkt, chunk_size);
     717             :             } else
     718        1933 :                 ret = av_get_packet(pb, pkt, chunk_size);
     719        1935 :             if (ret < 0) {
     720           0 :                 packet_read = 1;
     721           0 :                 break;
     722             :             }
     723        1935 :             partial_packet = chunk_type == MVIh_TAG;
     724        1935 :             if (chunk_type == AV0K_TAG || chunk_type == AV0F_TAG)
     725          48 :                 pkt->stream_index = ea->alpha.stream_index;
     726             :             else
     727        1887 :                 pkt->stream_index = ea->video.stream_index;
     728        1935 :             pkt->flags       |= key;
     729        1935 :             packet_read       = 1;
     730        1935 :             break;
     731             : 
     732             :         default:
     733          28 :             avio_skip(pb, chunk_size);
     734          28 :             break;
     735             :         }
     736             :     }
     737             : 
     738        3364 :     if (ret < 0 && partial_packet)
     739           0 :         av_packet_unref(pkt);
     740        3364 :     return ret;
     741             : }
     742             : 
     743             : AVInputFormat ff_ea_demuxer = {
     744             :     .name           = "ea",
     745             :     .long_name      = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia"),
     746             :     .priv_data_size = sizeof(EaDemuxContext),
     747             :     .read_probe     = ea_probe,
     748             :     .read_header    = ea_read_header,
     749             :     .read_packet    = ea_read_packet,
     750             : };

Generated by: LCOV version 1.12