annotate ffmpeg/libavformat/electronicarts.c @ 13:844d341cf643 tip

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