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 Libav. 6 * 7 * Libav 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 * Libav 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 Libav; 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 "libavutil/intreadwrite.h" 29#include "avformat.h" 30#include "internal.h" 31 32#define SCHl_TAG MKTAG('S', 'C', 'H', 'l') 33#define SEAD_TAG MKTAG('S', 'E', 'A', 'D') /* Sxxx header */ 34#define SNDC_TAG MKTAG('S', 'N', 'D', 'C') /* Sxxx data */ 35#define SEND_TAG MKTAG('S', 'E', 'N', 'D') /* Sxxx end */ 36#define SHEN_TAG MKTAG('S', 'H', 'E', 'N') /* SxEN header */ 37#define SDEN_TAG MKTAG('S', 'D', 'E', 'N') /* SxEN data */ 38#define SEEN_TAG MKTAG('S', 'E', 'E', 'N') /* SxEN end */ 39#define ISNh_TAG MKTAG('1', 'S', 'N', 'h') /* 1SNx header */ 40#define EACS_TAG MKTAG('E', 'A', 'C', 'S') 41#define ISNd_TAG MKTAG('1', 'S', 'N', 'd') /* 1SNx data */ 42#define ISNe_TAG MKTAG('1', 'S', 'N', 'e') /* 1SNx end */ 43#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0) 44#define GSTR_TAG MKTAG('G', 'S', 'T', 'R') 45#define SCDl_TAG MKTAG('S', 'C', 'D', 'l') 46#define SCEl_TAG MKTAG('S', 'C', 'E', 'l') 47#define kVGT_TAG MKTAG('k', 'V', 'G', 'T') /* TGV i-frame */ 48#define fVGT_TAG MKTAG('f', 'V', 'G', 'T') /* TGV p-frame */ 49#define mTCD_TAG MKTAG('m', 'T', 'C', 'D') /* MDEC */ 50#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */ 51#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD p-frame */ 52#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */ 53#define MPCh_TAG MKTAG('M', 'P', 'C', 'h') /* MPEG2 */ 54#define TGQs_TAG MKTAG('T', 'G', 'Q', 's') /* TGQ i-frame (appears in .TGQ files) */ 55#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T') /* TGQ i-frame (appears in .UV files) */ 56#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T') /* TQI/UV2 i-frame (.UV2/.WVE) */ 57#define MVhd_TAG MKTAG('M', 'V', 'h', 'd') 58#define MV0K_TAG MKTAG('M', 'V', '0', 'K') 59#define MV0F_TAG MKTAG('M', 'V', '0', 'F') 60#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */ 61#define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV i-frame */ 62 63typedef struct EaDemuxContext { 64 int big_endian; 65 66 enum CodecID video_codec; 67 AVRational time_base; 68 int width, height; 69 int video_stream_index; 70 71 enum CodecID audio_codec; 72 int audio_stream_index; 73 int audio_frame_counter; 74 75 int bytes; 76 int sample_rate; 77 int num_channels; 78 int num_samples; 79} EaDemuxContext; 80 81static uint32_t read_arbitary(AVIOContext *pb) { 82 uint8_t size, byte; 83 int i; 84 uint32_t word; 85 86 size = avio_r8(pb); 87 88 word = 0; 89 for (i = 0; i < size; i++) { 90 byte = avio_r8(pb); 91 word <<= 8; 92 word |= byte; 93 } 94 95 return word; 96} 97 98/* 99 * Process PT/GSTR sound header 100 * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx 101 */ 102static int process_audio_header_elements(AVFormatContext *s) 103{ 104 int inHeader = 1; 105 EaDemuxContext *ea = s->priv_data; 106 AVIOContext *pb = s->pb; 107 int compression_type = -1, revision = -1, revision2 = -1; 108 109 ea->bytes = 2; 110 ea->sample_rate = -1; 111 ea->num_channels = 1; 112 113 while (!pb->eof_reached && inHeader) { 114 int inSubheader; 115 uint8_t byte; 116 byte = avio_r8(pb); 117 118 switch (byte) { 119 case 0xFD: 120 av_log (s, AV_LOG_DEBUG, "entered audio subheader\n"); 121 inSubheader = 1; 122 while (!pb->eof_reached && inSubheader) { 123 uint8_t subbyte; 124 subbyte = avio_r8(pb); 125 126 switch (subbyte) { 127 case 0x80: 128 revision = read_arbitary(pb); 129 av_log (s, AV_LOG_DEBUG, "revision (element 0x80) set to 0x%08x\n", revision); 130 break; 131 case 0x82: 132 ea->num_channels = read_arbitary(pb); 133 av_log (s, AV_LOG_DEBUG, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels); 134 break; 135 case 0x83: 136 compression_type = read_arbitary(pb); 137 av_log (s, AV_LOG_DEBUG, "compression_type (element 0x83) set to 0x%08x\n", compression_type); 138 break; 139 case 0x84: 140 ea->sample_rate = read_arbitary(pb); 141 av_log (s, AV_LOG_DEBUG, "sample_rate (element 0x84) set to %i\n", ea->sample_rate); 142 break; 143 case 0x85: 144 ea->num_samples = read_arbitary(pb); 145 av_log (s, AV_LOG_DEBUG, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples); 146 break; 147 case 0x8A: 148 av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); 149 av_log (s, AV_LOG_DEBUG, "exited audio subheader\n"); 150 inSubheader = 0; 151 break; 152 case 0xA0: 153 revision2 = read_arbitary(pb); 154 av_log (s, AV_LOG_DEBUG, "revision2 (element 0xA0) set to 0x%08x\n", revision2); 155 break; 156 case 0xFF: 157 av_log (s, AV_LOG_DEBUG, "end of header block reached (within audio subheader)\n"); 158 inSubheader = 0; 159 inHeader = 0; 160 break; 161 default: 162 av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); 163 break; 164 } 165 } 166 break; 167 case 0xFF: 168 av_log (s, AV_LOG_DEBUG, "end of header block reached\n"); 169 inHeader = 0; 170 break; 171 default: 172 av_log (s, AV_LOG_DEBUG, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb)); 173 break; 174 } 175 } 176 177 switch (compression_type) { 178 case 0: ea->audio_codec = CODEC_ID_PCM_S16LE; break; 179 case 7: ea->audio_codec = CODEC_ID_ADPCM_EA; break; 180 case -1: 181 switch (revision) { 182 case 1: ea->audio_codec = CODEC_ID_ADPCM_EA_R1; break; 183 case 2: ea->audio_codec = CODEC_ID_ADPCM_EA_R2; break; 184 case 3: ea->audio_codec = CODEC_ID_ADPCM_EA_R3; break; 185 case -1: break; 186 default: 187 av_log(s, AV_LOG_ERROR, "unsupported stream type; revision=%i\n", revision); 188 return 0; 189 } 190 switch (revision2) { 191 case 8: ea->audio_codec = CODEC_ID_PCM_S16LE_PLANAR; break; 192 case 10: ea->audio_codec = CODEC_ID_ADPCM_EA_R2; break; 193 case 16: ea->audio_codec = CODEC_ID_MP3; break; 194 case -1: break; 195 default: 196 ea->audio_codec = CODEC_ID_NONE; 197 av_log(s, AV_LOG_ERROR, "unsupported stream type; revision2=%i\n", revision2); 198 return 0; 199 } 200 break; 201 default: 202 av_log(s, AV_LOG_ERROR, "unsupported stream type; compression_type=%i\n", compression_type); 203 return 0; 204 } 205 206 if (ea->sample_rate == -1) 207 ea->sample_rate = revision==3 ? 48000 : 22050; 208 209 return 1; 210} 211 212/* 213 * Process EACS sound header 214 * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx 215 */ 216static int process_audio_header_eacs(AVFormatContext *s) 217{ 218 EaDemuxContext *ea = s->priv_data; 219 AVIOContext *pb = s->pb; 220 int compression_type; 221 222 ea->sample_rate = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); 223 ea->bytes = avio_r8(pb); /* 1=8-bit, 2=16-bit */ 224 ea->num_channels = avio_r8(pb); 225 compression_type = avio_r8(pb); 226 avio_skip(pb, 13); 227 228 switch (compression_type) { 229 case 0: 230 switch (ea->bytes) { 231 case 1: ea->audio_codec = CODEC_ID_PCM_S8; break; 232 case 2: ea->audio_codec = CODEC_ID_PCM_S16LE; break; 233 } 234 break; 235 case 1: ea->audio_codec = CODEC_ID_PCM_MULAW; ea->bytes = 1; break; 236 case 2: ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_EACS; break; 237 default: 238 av_log (s, AV_LOG_ERROR, "unsupported stream type; audio compression_type=%i\n", compression_type); 239 } 240 241 return 1; 242} 243 244/* 245 * Process SEAD sound header 246 * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx 247 */ 248static int process_audio_header_sead(AVFormatContext *s) 249{ 250 EaDemuxContext *ea = s->priv_data; 251 AVIOContext *pb = s->pb; 252 253 ea->sample_rate = avio_rl32(pb); 254 ea->bytes = avio_rl32(pb); /* 1=8-bit, 2=16-bit */ 255 ea->num_channels = avio_rl32(pb); 256 ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_SEAD; 257 258 return 1; 259} 260 261static int process_video_header_mdec(AVFormatContext *s) 262{ 263 EaDemuxContext *ea = s->priv_data; 264 AVIOContext *pb = s->pb; 265 avio_skip(pb, 4); 266 ea->width = avio_rl16(pb); 267 ea->height = avio_rl16(pb); 268 ea->time_base = (AVRational){1,15}; 269 ea->video_codec = CODEC_ID_MDEC; 270 return 1; 271} 272 273static int process_video_header_vp6(AVFormatContext *s) 274{ 275 EaDemuxContext *ea = s->priv_data; 276 AVIOContext *pb = s->pb; 277 278 avio_skip(pb, 16); 279 ea->time_base.den = avio_rl32(pb); 280 ea->time_base.num = avio_rl32(pb); 281 ea->video_codec = CODEC_ID_VP6; 282 283 return 1; 284} 285 286/* 287 * Process EA file header 288 * Returns 1 if the EA file is valid and successfully opened, 0 otherwise 289 */ 290static int process_ea_header(AVFormatContext *s) { 291 uint32_t blockid, size = 0; 292 EaDemuxContext *ea = s->priv_data; 293 AVIOContext *pb = s->pb; 294 int i; 295 296 for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) { 297 unsigned int startpos = avio_tell(pb); 298 int err = 0; 299 300 blockid = avio_rl32(pb); 301 size = avio_rl32(pb); 302 if (i == 0) 303 ea->big_endian = size > 0x000FFFFF; 304 if (ea->big_endian) 305 size = av_bswap32(size); 306 307 switch (blockid) { 308 case ISNh_TAG: 309 if (avio_rl32(pb) != EACS_TAG) { 310 av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n"); 311 return 0; 312 } 313 err = process_audio_header_eacs(s); 314 break; 315 316 case SCHl_TAG : 317 case SHEN_TAG : 318 blockid = avio_rl32(pb); 319 if (blockid == GSTR_TAG) { 320 avio_skip(pb, 4); 321 } else if ((blockid & 0xFFFF)!=PT00_TAG) { 322 av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n"); 323 return 0; 324 } 325 err = process_audio_header_elements(s); 326 break; 327 328 case SEAD_TAG: 329 err = process_audio_header_sead(s); 330 break; 331 332 case MVIh_TAG : 333 ea->video_codec = CODEC_ID_CMV; 334 ea->time_base = (AVRational){0,0}; 335 break; 336 337 case kVGT_TAG: 338 ea->video_codec = CODEC_ID_TGV; 339 ea->time_base = (AVRational){0,0}; 340 break; 341 342 case mTCD_TAG : 343 err = process_video_header_mdec(s); 344 break; 345 346 case MPCh_TAG: 347 ea->video_codec = CODEC_ID_MPEG2VIDEO; 348 break; 349 350 case pQGT_TAG: 351 case TGQs_TAG: 352 ea->video_codec = CODEC_ID_TGQ; 353 break; 354 355 case pIQT_TAG: 356 ea->video_codec = CODEC_ID_TQI; 357 break; 358 359 case MADk_TAG : 360 ea->video_codec = CODEC_ID_MAD; 361 break; 362 363 case MVhd_TAG : 364 err = process_video_header_vp6(s); 365 break; 366 } 367 368 if (err < 0) { 369 av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err); 370 return err; 371 } 372 373 avio_seek(pb, startpos + size, SEEK_SET); 374 } 375 376 avio_seek(pb, 0, SEEK_SET); 377 378 return 1; 379} 380 381 382static int ea_probe(AVProbeData *p) 383{ 384 switch (AV_RL32(&p->buf[0])) { 385 case ISNh_TAG: 386 case SCHl_TAG: 387 case SEAD_TAG: 388 case SHEN_TAG: 389 case kVGT_TAG: 390 case MADk_TAG: 391 case MPCh_TAG: 392 case MVhd_TAG: 393 case MVIh_TAG: 394 break; 395 default: 396 return 0; 397 } 398 if (AV_RL32(&p->buf[4]) > 0xfffff && AV_RB32(&p->buf[4]) > 0xfffff) 399 return 0; 400 return AVPROBE_SCORE_MAX; 401} 402 403static int ea_read_header(AVFormatContext *s, 404 AVFormatParameters *ap) 405{ 406 EaDemuxContext *ea = s->priv_data; 407 AVStream *st; 408 409 if (!process_ea_header(s)) 410 return AVERROR(EIO); 411 412 if (ea->video_codec) { 413 /* initialize the video decoder stream */ 414 st = avformat_new_stream(s, NULL); 415 if (!st) 416 return AVERROR(ENOMEM); 417 ea->video_stream_index = st->index; 418 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 419 st->codec->codec_id = ea->video_codec; 420 st->codec->codec_tag = 0; /* no fourcc */ 421 st->codec->time_base = ea->time_base; 422 st->codec->width = ea->width; 423 st->codec->height = ea->height; 424 } 425 426 if (ea->audio_codec) { 427 if (ea->num_channels <= 0) { 428 av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels); 429 ea->audio_codec = 0; 430 return 1; 431 } 432 if (ea->sample_rate <= 0) { 433 av_log(s, AV_LOG_ERROR, "Unsupported sample rate: %d\n", ea->sample_rate); 434 ea->audio_codec = 0; 435 return 1; 436 } 437 if (ea->bytes <= 0) { 438 av_log(s, AV_LOG_ERROR, "Invalid number of bytes per sample: %d\n", ea->bytes); 439 ea->audio_codec = CODEC_ID_NONE; 440 return 1; 441 } 442 443 /* initialize the audio decoder stream */ 444 st = avformat_new_stream(s, NULL); 445 if (!st) 446 return AVERROR(ENOMEM); 447 avpriv_set_pts_info(st, 33, 1, ea->sample_rate); 448 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 449 st->codec->codec_id = ea->audio_codec; 450 st->codec->codec_tag = 0; /* no tag */ 451 st->codec->channels = ea->num_channels; 452 st->codec->sample_rate = ea->sample_rate; 453 st->codec->bits_per_coded_sample = ea->bytes * 8; 454 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 455 st->codec->bits_per_coded_sample / 4; 456 st->codec->block_align = st->codec->channels*st->codec->bits_per_coded_sample; 457 ea->audio_stream_index = st->index; 458 ea->audio_frame_counter = 0; 459 } 460 461 return 1; 462} 463 464static int ea_read_packet(AVFormatContext *s, 465 AVPacket *pkt) 466{ 467 EaDemuxContext *ea = s->priv_data; 468 AVIOContext *pb = s->pb; 469 int ret = 0; 470 int packet_read = 0; 471 unsigned int chunk_type, chunk_size; 472 int key = 0; 473 int av_uninit(num_samples); 474 475 while (!packet_read) { 476 chunk_type = avio_rl32(pb); 477 chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); 478 if (chunk_size <= 8) 479 return AVERROR_INVALIDDATA; 480 chunk_size -= 8; 481 482 switch (chunk_type) { 483 /* audio data */ 484 case ISNh_TAG: 485 /* header chunk also contains data; skip over the header portion*/ 486 if (chunk_size < 32) 487 return AVERROR_INVALIDDATA; 488 avio_skip(pb, 32); 489 chunk_size -= 32; 490 case ISNd_TAG: 491 case SCDl_TAG: 492 case SNDC_TAG: 493 case SDEN_TAG: 494 if (!ea->audio_codec) { 495 avio_skip(pb, chunk_size); 496 break; 497 } else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR || 498 ea->audio_codec == CODEC_ID_MP3) { 499 num_samples = avio_rl32(pb); 500 avio_skip(pb, 8); 501 chunk_size -= 12; 502 } 503 ret = av_get_packet(pb, pkt, chunk_size); 504 if (ret < 0) 505 return ret; 506 pkt->stream_index = ea->audio_stream_index; 507 pkt->pts = 90000; 508 pkt->pts *= ea->audio_frame_counter; 509 pkt->pts /= ea->sample_rate; 510 511 switch (ea->audio_codec) { 512 case CODEC_ID_ADPCM_EA: 513 /* 2 samples/byte, 1 or 2 samples per frame depending 514 * on stereo; chunk also has 12-byte header */ 515 ea->audio_frame_counter += ((chunk_size - 12) * 2) / 516 ea->num_channels; 517 break; 518 case CODEC_ID_PCM_S16LE_PLANAR: 519 case CODEC_ID_MP3: 520 ea->audio_frame_counter += num_samples; 521 break; 522 default: 523 ea->audio_frame_counter += chunk_size / 524 (ea->bytes * ea->num_channels); 525 } 526 527 packet_read = 1; 528 break; 529 530 /* ending tag */ 531 case 0: 532 case ISNe_TAG: 533 case SCEl_TAG: 534 case SEND_TAG: 535 case SEEN_TAG: 536 ret = AVERROR(EIO); 537 packet_read = 1; 538 break; 539 540 case MVIh_TAG: 541 case kVGT_TAG: 542 case pQGT_TAG: 543 case TGQs_TAG: 544 case MADk_TAG: 545 key = AV_PKT_FLAG_KEY; 546 case MVIf_TAG: 547 case fVGT_TAG: 548 case MADm_TAG: 549 case MADe_TAG: 550 avio_seek(pb, -8, SEEK_CUR); // include chunk preamble 551 chunk_size += 8; 552 goto get_video_packet; 553 554 case mTCD_TAG: 555 avio_skip(pb, 8); // skip ea dct header 556 chunk_size -= 8; 557 goto get_video_packet; 558 559 case MV0K_TAG: 560 case MPCh_TAG: 561 case pIQT_TAG: 562 key = AV_PKT_FLAG_KEY; 563 case MV0F_TAG: 564get_video_packet: 565 ret = av_get_packet(pb, pkt, chunk_size); 566 if (ret < 0) 567 return ret; 568 pkt->stream_index = ea->video_stream_index; 569 pkt->flags |= key; 570 packet_read = 1; 571 break; 572 573 default: 574 avio_skip(pb, chunk_size); 575 break; 576 } 577 } 578 579 return ret; 580} 581 582AVInputFormat ff_ea_demuxer = { 583 .name = "ea", 584 .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia Format"), 585 .priv_data_size = sizeof(EaDemuxContext), 586 .read_probe = ea_probe, 587 .read_header = ea_read_header, 588 .read_packet = ea_read_packet, 589}; 590