FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
electronicarts.c
Go to the documentation of this file.
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 "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') /* MPEG-2 */
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 
63 typedef struct EaDemuxContext {
65 
68  int width, height;
69  int nb_frames;
71 
74 
75  int bytes;
80 
81 static uint32_t read_arbitrary(AVIOContext *pb)
82 {
83  uint8_t size, byte;
84  int i;
85  uint32_t word;
86 
87  size = avio_r8(pb);
88 
89  word = 0;
90  for (i = 0; i < size; i++) {
91  byte = avio_r8(pb);
92  word <<= 8;
93  word |= byte;
94  }
95 
96  return word;
97 }
98 
100 {
101  EaDemuxContext *ea = s->priv_data;
102  AVIOContext *pb = s->pb;
103  int in_header = 1;
104  int compression_type = -1, revision = -1, revision2 = -1;
105 
106  ea->bytes = 2;
107  ea->sample_rate = -1;
108  ea->num_channels = 1;
109 
110  while (!url_feof(pb) && in_header) {
111  int in_subheader;
112  uint8_t byte;
113  byte = avio_r8(pb);
114 
115  switch (byte) {
116  case 0xFD:
117  av_log(s, AV_LOG_DEBUG, "entered audio subheader\n");
118  in_subheader = 1;
119  while (!url_feof(pb) && in_subheader) {
120  uint8_t subbyte;
121  subbyte = avio_r8(pb);
122 
123  switch (subbyte) {
124  case 0x80:
125  revision = read_arbitrary(pb);
126  av_log(s, AV_LOG_DEBUG,
127  "revision (element 0x80) set to 0x%08x\n", revision);
128  break;
129  case 0x82:
130  ea->num_channels = read_arbitrary(pb);
131  av_log(s, AV_LOG_DEBUG,
132  "num_channels (element 0x82) set to 0x%08x\n",
133  ea->num_channels);
134  break;
135  case 0x83:
136  compression_type = read_arbitrary(pb);
137  av_log(s, AV_LOG_DEBUG,
138  "compression_type (element 0x83) set to 0x%08x\n",
139  compression_type);
140  break;
141  case 0x84:
142  ea->sample_rate = read_arbitrary(pb);
143  av_log(s, AV_LOG_DEBUG,
144  "sample_rate (element 0x84) set to %i\n",
145  ea->sample_rate);
146  break;
147  case 0x85:
148  ea->num_samples = read_arbitrary(pb);
149  av_log(s, AV_LOG_DEBUG,
150  "num_samples (element 0x85) set to 0x%08x\n",
151  ea->num_samples);
152  break;
153  case 0x8A:
154  av_log(s, AV_LOG_DEBUG,
155  "element 0x%02x set to 0x%08x\n",
156  subbyte, read_arbitrary(pb));
157  av_log(s, AV_LOG_DEBUG, "exited audio subheader\n");
158  in_subheader = 0;
159  break;
160  case 0xA0:
161  revision2 = read_arbitrary(pb);
162  av_log(s, AV_LOG_DEBUG,
163  "revision2 (element 0xA0) set to 0x%08x\n",
164  revision2);
165  break;
166  case 0xFF:
167  av_log(s, AV_LOG_DEBUG,
168  "end of header block reached (within audio subheader)\n");
169  in_subheader = 0;
170  in_header = 0;
171  break;
172  default:
173  av_log(s, AV_LOG_DEBUG,
174  "element 0x%02x set to 0x%08x\n",
175  subbyte, read_arbitrary(pb));
176  break;
177  }
178  }
179  break;
180  case 0xFF:
181  av_log(s, AV_LOG_DEBUG, "end of header block reached\n");
182  in_header = 0;
183  break;
184  default:
185  av_log(s, AV_LOG_DEBUG,
186  "header element 0x%02x set to 0x%08x\n",
187  byte, read_arbitrary(pb));
188  break;
189  }
190  }
191 
192  switch (compression_type) {
193  case 0:
195  break;
196  case 7:
198  break;
199  case -1:
200  switch (revision) {
201  case 1:
203  break;
204  case 2:
206  break;
207  case 3:
209  break;
210  case -1:
211  break;
212  default:
213  avpriv_request_sample(s, "stream type; revision=%i", revision);
214  return 0;
215  }
216  switch (revision2) {
217  case 8:
219  break;
220  case 10:
221  switch (revision) {
222  case -1:
223  case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break;
224  case 3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break;
225  default:
226  avpriv_request_sample(s, "stream type; revision=%i, revision2=%i", revision, revision2);
227  return 0;
228  }
229  break;
230  case 16:
232  break;
233  case -1:
234  break;
235  default:
237  avpriv_request_sample(s, "stream type; revision2=%i", revision2);
238  return 0;
239  }
240  break;
241  default:
243  "stream type; compression_type=%i",
244  compression_type);
245  return 0;
246  }
247 
248  if (ea->sample_rate == -1)
249  ea->sample_rate = revision == 3 ? 48000 : 22050;
250 
251  return 1;
252 }
253 
255 {
256  EaDemuxContext *ea = s->priv_data;
257  AVIOContext *pb = s->pb;
258  int compression_type;
259 
260  ea->sample_rate = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
261  ea->bytes = avio_r8(pb); /* 1=8-bit, 2=16-bit */
262  ea->num_channels = avio_r8(pb);
263  compression_type = avio_r8(pb);
264  avio_skip(pb, 13);
265 
266  switch (compression_type) {
267  case 0:
268  switch (ea->bytes) {
269  case 1:
271  break;
272  case 2:
274  break;
275  }
276  break;
277  case 1:
279  ea->bytes = 1;
280  break;
281  case 2:
283  break;
284  default:
286  "stream type; audio compression_type=%i",
287  compression_type);
288  }
289 }
290 
292 {
293  EaDemuxContext *ea = s->priv_data;
294  AVIOContext *pb = s->pb;
295 
296  ea->sample_rate = avio_rl32(pb);
297  ea->bytes = avio_rl32(pb); /* 1=8-bit, 2=16-bit */
298  ea->num_channels = avio_rl32(pb);
300 }
301 
303 {
304  EaDemuxContext *ea = s->priv_data;
305  AVIOContext *pb = s->pb;
306  avio_skip(pb, 4);
307  ea->width = avio_rl16(pb);
308  ea->height = avio_rl16(pb);
309  ea->time_base = (AVRational) { 1, 15 };
311 }
312 
314 {
315  EaDemuxContext *ea = s->priv_data;
316  AVIOContext *pb = s->pb;
317 
318  avio_skip(pb, 8);
319  ea->nb_frames = avio_rl32(pb);
320  avio_skip(pb, 4);
321  ea->time_base.den = avio_rl32(pb);
322  ea->time_base.num = avio_rl32(pb);
323  if (ea->time_base.den <= 0 || ea->time_base.num <= 0) {
324  av_log(s, AV_LOG_ERROR, "Timebase is invalid\n");
325  return AVERROR_INVALIDDATA;
326  }
328 
329  return 1;
330 }
331 
333 {
334  EaDemuxContext *ea = s->priv_data;
335  int fps;
336 
337  avio_skip(s->pb, 10);
338  fps = avio_rl16(s->pb);
339  if (fps)
340  ea->time_base = (AVRational) { 1, fps };
342 }
343 
344 /* Process EA file header.
345  * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
347 {
348  uint32_t blockid, size = 0;
349  EaDemuxContext *ea = s->priv_data;
350  AVIOContext *pb = s->pb;
351  int i;
352 
353  for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
354  uint64_t startpos = avio_tell(pb);
355  int err = 0;
356 
357  blockid = avio_rl32(pb);
358  size = avio_rl32(pb);
359  if (i == 0)
360  ea->big_endian = size > av_bswap32(size);
361  if (ea->big_endian)
362  size = av_bswap32(size);
363 
364  if (size < 8) {
365  av_log(s, AV_LOG_ERROR, "chunk size too small\n");
366  return AVERROR_INVALIDDATA;
367  }
368 
369  switch (blockid) {
370  case ISNh_TAG:
371  if (avio_rl32(pb) != EACS_TAG) {
372  avpriv_request_sample(s, "unknown 1SNh headerid");
373  return 0;
374  }
376  break;
377 
378  case SCHl_TAG:
379  case SHEN_TAG:
380  blockid = avio_rl32(pb);
381  if (blockid == GSTR_TAG) {
382  avio_skip(pb, 4);
383  } else if ((blockid & 0xFFFF) != PT00_TAG) {
384  avpriv_request_sample(s, "unknown SCHl headerid");
385  return 0;
386  }
388  break;
389 
390  case SEAD_TAG:
392  break;
393 
394  case MVIh_TAG:
396  break;
397 
398  case kVGT_TAG:
400  break;
401 
402  case mTCD_TAG:
404  break;
405 
406  case MPCh_TAG:
408  break;
409 
410  case pQGT_TAG:
411  case TGQs_TAG:
413  break;
414 
415  case pIQT_TAG:
417  break;
418 
419  case MADk_TAG:
421  break;
422 
423  case MVhd_TAG:
424  err = process_video_header_vp6(s);
425  break;
426  }
427 
428  if (err < 0) {
429  av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err);
430  return err;
431  }
432 
433  avio_seek(pb, startpos + size, SEEK_SET);
434  }
435 
436  avio_seek(pb, 0, SEEK_SET);
437 
438  return 1;
439 }
440 
441 static int ea_probe(AVProbeData *p)
442 {
443  unsigned big_endian, size;
444 
445  switch (AV_RL32(&p->buf[0])) {
446  case ISNh_TAG:
447  case SCHl_TAG:
448  case SEAD_TAG:
449  case SHEN_TAG:
450  case kVGT_TAG:
451  case MADk_TAG:
452  case MPCh_TAG:
453  case MVhd_TAG:
454  case MVIh_TAG:
455  break;
456  default:
457  return 0;
458  }
459  size = AV_RL32(&p->buf[4]);
460  big_endian = size > 0x000FFFFF;
461  if (big_endian)
462  size = av_bswap32(size);
463  if (size > 0xfffff || size < 8)
464  return 0;
465 
466  return AVPROBE_SCORE_MAX;
467 }
468 
470 {
471  EaDemuxContext *ea = s->priv_data;
472  AVStream *st;
473 
474  if (process_ea_header(s)<=0)
475  return AVERROR(EIO);
476 
477  if (ea->video_codec) {
478  /* initialize the video decoder stream */
479  st = avformat_new_stream(s, NULL);
480  if (!st)
481  return AVERROR(ENOMEM);
482  ea->video_stream_index = st->index;
484  st->codec->codec_id = ea->video_codec;
485  // parsing is necessary to make FFmpeg generate correct timestamps
488  st->codec->codec_tag = 0; /* no fourcc */
489  st->codec->width = ea->width;
490  st->codec->height = ea->height;
491  st->duration = st->nb_frames = ea->nb_frames;
492  if (ea->time_base.num)
493  avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den);
494  st->r_frame_rate =
495  st->avg_frame_rate = av_inv_q(ea->time_base);
496  }
497 
498  if (ea->audio_codec) {
499  if (ea->num_channels <= 0 || ea->num_channels > 2) {
501  "Unsupported number of channels: %d\n", ea->num_channels);
502  ea->audio_codec = 0;
503  return 1;
504  }
505  if (ea->sample_rate <= 0) {
506  av_log(s, AV_LOG_ERROR,
507  "Unsupported sample rate: %d\n", ea->sample_rate);
508  ea->audio_codec = 0;
509  return 1;
510  }
511  if (ea->bytes <= 0) {
512  av_log(s, AV_LOG_ERROR,
513  "Invalid number of bytes per sample: %d\n", ea->bytes);
515  return 1;
516  }
517 
518  /* initialize the audio decoder stream */
519  st = avformat_new_stream(s, NULL);
520  if (!st)
521  return AVERROR(ENOMEM);
522  avpriv_set_pts_info(st, 33, 1, ea->sample_rate);
524  st->codec->codec_id = ea->audio_codec;
525  st->codec->codec_tag = 0; /* no tag */
526  st->codec->channels = ea->num_channels;
527  st->codec->sample_rate = ea->sample_rate;
528  st->codec->bits_per_coded_sample = ea->bytes * 8;
529  st->codec->bit_rate = st->codec->channels *
530  st->codec->sample_rate *
531  st->codec->bits_per_coded_sample / 4;
532  st->codec->block_align = st->codec->channels *
534  ea->audio_stream_index = st->index;
535  st->start_time = 0;
536  }
537 
538  return 1;
539 }
540 
542 {
543  EaDemuxContext *ea = s->priv_data;
544  AVIOContext *pb = s->pb;
545  int partial_packet = 0;
546  unsigned int chunk_type, chunk_size;
547  int ret = 0, packet_read = 0, key = 0;
548  int av_uninit(num_samples);
549 
550  while (!packet_read || partial_packet) {
551  chunk_type = avio_rl32(pb);
552  chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
553  if (chunk_size <= 8)
554  return AVERROR_INVALIDDATA;
555  chunk_size -= 8;
556 
557  switch (chunk_type) {
558  /* audio data */
559  case ISNh_TAG:
560  /* header chunk also contains data; skip over the header portion */
561  if (chunk_size < 32)
562  return AVERROR_INVALIDDATA;
563  avio_skip(pb, 32);
564  chunk_size -= 32;
565  case ISNd_TAG:
566  case SCDl_TAG:
567  case SNDC_TAG:
568  case SDEN_TAG:
569  if (!ea->audio_codec) {
570  avio_skip(pb, chunk_size);
571  break;
572  } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR ||
573  ea->audio_codec == AV_CODEC_ID_MP3) {
574  num_samples = avio_rl32(pb);
575  avio_skip(pb, 8);
576  chunk_size -= 12;
577  }
578  if (partial_packet) {
579  avpriv_request_sample(s, "video header followed by audio packet");
580  av_free_packet(pkt);
581  partial_packet = 0;
582  }
583  ret = av_get_packet(pb, pkt, chunk_size);
584  if (ret < 0)
585  return ret;
586  pkt->stream_index = ea->audio_stream_index;
587 
588  switch (ea->audio_codec) {
594  if (pkt->size < 4) {
595  av_log(s, AV_LOG_ERROR, "Packet is too short\n");
596  av_free_packet(pkt);
597  return AVERROR_INVALIDDATA;
598  }
600  pkt->duration = AV_RB32(pkt->data);
601  else
602  pkt->duration = AV_RL32(pkt->data);
603  break;
605  pkt->duration = ret * 2 / ea->num_channels;
606  break;
608  case AV_CODEC_ID_MP3:
609  pkt->duration = num_samples;
610  break;
611  default:
612  pkt->duration = chunk_size / (ea->bytes * ea->num_channels);
613  }
614 
615  packet_read = 1;
616  break;
617 
618  /* ending tag */
619  case 0:
620  case ISNe_TAG:
621  case SCEl_TAG:
622  case SEND_TAG:
623  case SEEN_TAG:
624  ret = AVERROR(EIO);
625  packet_read = 1;
626  break;
627 
628  case MVIh_TAG:
629  case kVGT_TAG:
630  case pQGT_TAG:
631  case TGQs_TAG:
632  case MADk_TAG:
633  key = AV_PKT_FLAG_KEY;
634  case MVIf_TAG:
635  case fVGT_TAG:
636  case MADm_TAG:
637  case MADe_TAG:
638  avio_seek(pb, -8, SEEK_CUR); // include chunk preamble
639  chunk_size += 8;
640  goto get_video_packet;
641 
642  case mTCD_TAG:
643  avio_skip(pb, 8); // skip ea DCT header
644  chunk_size -= 8;
645  goto get_video_packet;
646 
647  case MV0K_TAG:
648  case MPCh_TAG:
649  case pIQT_TAG:
650  key = AV_PKT_FLAG_KEY;
651  case MV0F_TAG:
652 get_video_packet:
653  if (partial_packet) {
654  ret = av_append_packet(pb, pkt, chunk_size);
655  } else
656  ret = av_get_packet(pb, pkt, chunk_size);
657  if (ret < 0) {
658  packet_read = 1;
659  break;
660  }
661  partial_packet = chunk_type == MVIh_TAG;
662  pkt->stream_index = ea->video_stream_index;
663  pkt->flags |= key;
664  packet_read = 1;
665  break;
666 
667  default:
668  avio_skip(pb, chunk_size);
669  break;
670  }
671  }
672 
673  if (ret < 0 && partial_packet)
674  av_free_packet(pkt);
675  return ret;
676 }
677 
679  .name = "ea",
680  .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia"),
681  .priv_data_size = sizeof(EaDemuxContext),
682  .read_probe = ea_probe,
685 };