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
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
76
79
81
84
89
92
94 {
96 int i;
97 uint32_t word;
98
100
101 word = 0;
102 for (i = 0; i <
size; i++) {
104 word <<= 8;
106 }
107
108 return word;
109 }
110
112 {
115 int in_header = 1;
116 int compression_type = -1, revision = -1, revision2 = -1;
117
121
123 int in_subheader;
126
127 switch (byte) {
128 case 0xFD:
130 in_subheader = 1;
134
135 switch (subbyte) {
136 case 0x80:
139 "revision (element 0x80) set to 0x%08x\n", revision);
140 break;
141 case 0x82:
144 "num_channels (element 0x82) set to 0x%08x\n",
146 break;
147 case 0x83:
150 "compression_type (element 0x83) set to 0x%08x\n",
151 compression_type);
152 break;
153 case 0x84:
156 "sample_rate (element 0x84) set to %i\n",
158 break;
159 case 0x85:
162 "num_samples (element 0x85) set to 0x%08x\n",
164 break;
165 case 0x8A:
167 "element 0x%02x set to 0x%08"PRIx32"\n",
170 in_subheader = 0;
171 break;
172 case 0xA0:
175 "revision2 (element 0xA0) set to 0x%08x\n",
176 revision2);
177 break;
178 case 0xFF:
180 "end of header block reached (within audio subheader)\n");
181 in_subheader = 0;
182 in_header = 0;
183 break;
184 default:
186 "element 0x%02x set to 0x%08"PRIx32"\n",
188 break;
189 }
190 }
191 break;
192 case 0xFF:
194 in_header = 0;
195 break;
196 default:
198 "header element 0x%02x set to 0x%08"PRIx32"\n",
200 break;
201 }
202 }
203
204 switch (compression_type) {
205 case 0:
207 break;
208 case 7:
210 break;
211 case -1:
212 switch (revision) {
213 case 1:
215 break;
216 case 2:
218 break;
219 case 3:
221 break;
222 case -1:
223 break;
224 default:
226 return 0;
227 }
228 switch (revision2) {
229 case 8:
231 break;
232 case 10:
233 switch (revision) {
234 case -1:
237 default:
239 return 0;
240 }
241 break;
242 case 15:
243 case 16:
245 break;
246 case -1:
247 break;
248 default:
251 return 0;
252 }
253 break;
254 default:
256 "stream type; compression_type=%i",
257 compression_type);
258 return 0;
259 }
260
265
266 return 1;
267 }
268
270 {
273 int compression_type;
274
278 compression_type =
avio_r8(pb);
280
281 switch (compression_type) {
282 case 0:
284 case 1:
286 break;
287 case 2:
289 break;
290 }
291 break;
292 case 1:
295 break;
296 case 2:
298 break;
299 default:
301 "stream type; audio compression_type=%i",
302 compression_type);
303 }
304 }
305
307 {
310
315 }
316
318 {
325 }
326
328 {
330
339 }
341
342 return 1;
343 }
344
346 {
347 int fps;
348
351 if (fps)
354 }
355
356 /* Process EA file header.
357 * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
359 {
360 uint32_t blockid,
size = 0;
363 int i;
364
367 int err = 0;
368
371 if (i == 0)
375
376 if (size < 8) {
379 }
380
381 switch (blockid) {
385 return 0;
386 }
388 break;
389
395 }
else if ((blockid & 0xFF) != (
PT00_TAG & 0xFF)) {
397 }
398 ea->
platform = (blockid >> 16) & 0xFF;
400 break;
401
404 break;
405
408 break;
409
412 break;
413
416 break;
417
420 break;
421
426 break;
427
431 break;
432
437 break;
438
441 break;
442
445 break;
446 }
447
448 if (err < 0) {
450 return err;
451 }
452
453 avio_seek(pb, startpos + size, SEEK_SET);
454 }
455
457
458 return 1;
459 }
460
462 {
463 unsigned big_endian,
size;
464
476 break;
477 default:
478 return 0;
479 }
481 big_endian = size > 0x000FFFFF;
482 if (big_endian)
484 if (size > 0xfffff || size < 8)
485 return 0;
486
488 }
489
491 {
493
495 return 0;
496
497 /* initialize the video decoder stream */
499 if (!st)
504 // parsing is necessary to make FFmpeg generate correct timestamps
515 return 0;
516 }
517
519 {
522
525
528
532 "Unsupported number of channels: %d\n", ea->
num_channels);
534 return 1;
535 }
540 return 1;
541 }
544 "Invalid number of bytes per sample: %d\n", ea->
bytes);
546 return 1;
547 }
548
549 /* initialize the audio decoder stream */
551 if (!st)
567 }
568
569 return 1;
570 }
571
573 {
576 int partial_packet = 0;
577 unsigned int chunk_type, chunk_size;
578 int ret = 0, packet_read = 0,
key = 0;
580
581 while (!packet_read || partial_packet) {
584 if (chunk_size < 8)
586 chunk_size -= 8;
587
588 switch (chunk_type) {
589 /* audio data */
591 /* header chunk also contains data; skip over the header portion */
592 if (chunk_size < 32)
595 chunk_size -= 32;
602 break;
607 chunk_size -= 12;
610 chunk_size -= 8;
611 }
612
613 if (partial_packet) {
616 partial_packet = 0;
617 }
618
619 if (!chunk_size)
620 continue;
621
623 if (ret < 0)
624 return ret;
626
637 }
640 else
642 break;
645 break;
649 break;
652 break;
653 default:
655 }
656
657 packet_read = 1;
658 break;
659
660 /* ending tag */
661 case 0:
668
674 break;
675 }
676 }
679 packet_read = 1;
680 break;
681
692 avio_seek(pb, -8, SEEK_CUR);
// include chunk preamble
693 chunk_size += 8;
694 goto get_video_packet;
695
697 if (chunk_size < 8)
699
701 chunk_size -= 8;
702 goto get_video_packet;
703
711 get_video_packet:
712 if (!chunk_size)
713 continue;
714
715 if (partial_packet) {
717 } else
719 if (ret < 0) {
720 packet_read = 1;
721 break;
722 }
723 partial_packet = chunk_type ==
MVIh_TAG;
726 else
729 packet_read = 1;
730 break;
731
732 default:
734 break;
735 }
736 }
737
738 if (ret < 0 && partial_packet)
740 return ret;
741 }
742
750 };
static int process_ea_header(AVFormatContext *s)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
static uint32_t read_arbitrary(AVIOContext *pb)
static void process_video_header_cmv(AVFormatContext *s, VideoProperties *video)
#define AV_LOG_WARNING
Something somehow does not look correct.
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int index
stream index in AVFormatContext
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
enum AVCodecID audio_codec
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
unsigned int avio_rb32(AVIOContext *s)
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
enum AVStreamParseType need_parsing
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
static int init_video_stream(AVFormatContext *s, VideoProperties *video)
#define AVERROR_EOF
End of file.
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
AVCodecID
Identify the syntax and semantics of the bitstream.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
unsigned int avio_rl32(AVIOContext *s)
static int process_video_header_vp6(AVFormatContext *s, VideoProperties *video)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
preferred ID for decoding MPEG audio layer 1, 2 or 3
enum AVMediaType codec_type
General type of the encoded data.
AVRational avg_frame_rate
Average framerate.
int flags
A combination of AV_PKT_FLAG values.
int avio_r8(AVIOContext *s)
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
int block_align
Audio only.
static void process_audio_header_eacs(AVFormatContext *s)
static void process_video_header_mdec(AVFormatContext *s, VideoProperties *video)
static int process_audio_header_elements(AVFormatContext *s)
static int ea_read_header(AVFormatContext *s)
preferred ID for MPEG-1/2 video decoding
static int read_header(FFV1Context *f)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL byte
AVIOContext * pb
I/O context.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Rational number (pair of numerator and denominator).
This structure contains the data a format has to probe a file.
static int ea_probe(AVProbeData *p)
int64_t duration
Decoding: duration of the stream, in stream time base.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
int sample_rate
Audio only.
unsigned int avio_rl16(AVIOContext *s)
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base...
static void process_audio_header_sead(AVFormatContext *s)
int64_t nb_frames
number of frames in this stream if known or 0
void * priv_data
Format private data.
int bits_per_coded_sample
The number of bits per sample in the codedwords.
static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int avio_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
AVInputFormat ff_ea_demuxer
AVRational r_frame_rate
Real base framerate of the stream.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
This structure stores compressed data.