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
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
65
71
74
80
83 int i;
84 uint32_t word;
85
87
88 word = 0;
89 for (i = 0; i <
size; i++) {
91 word <<= 8;
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 */
103 {
104 int inHeader = 1;
107 int compression_type = -1, revision = -1, revision2 = -1;
108
112
114 int inSubheader;
117
118 switch (byte) {
119 case 0xFD:
121 inSubheader = 1;
122 while (!
url_feof(pb) && inSubheader) {
125
126 switch (subbyte) {
127 case 0x80:
130 break;
131 case 0x82:
134 break;
135 case 0x83:
137 av_log (s,
AV_LOG_DEBUG,
"compression_type (element 0x83) set to 0x%08x\n", compression_type);
138 break;
139 case 0x84:
142 break;
143 case 0x85:
146 break;
147 case 0x8A:
150 inSubheader = 0;
151 break;
152 case 0xA0:
155 break;
156 case 0xFF:
158 inSubheader = 0;
159 inHeader = 0;
160 break;
161 default:
163 break;
164 }
165 }
166 break;
167 case 0xFF:
169 inHeader = 0;
170 break;
171 default:
173 break;
174 }
175 }
176
177 switch (compression_type) {
180 case -1:
181 switch (revision) {
185 case -1: break;
186 default:
188 return 0;
189 }
190 switch (revision2) {
192 case 10:
193 switch (revision) {
194 case -1:
197 default:
199 return 0;
200 }
201 break;
203 case -1: break;
204 default:
207 return 0;
208 }
209 break;
210 default:
212 return 0;
213 }
214
217
218 return 1;
219 }
220
221 /*
222 * Process EACS sound header
223 * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
224 */
226 {
229 int compression_type;
230
234 compression_type =
avio_r8(pb);
236
237 switch (compression_type) {
238 case 0:
242 }
243 break;
246 default:
248 }
249
250 return 1;
251 }
252
253 /*
254 * Process SEAD sound header
255 * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
256 */
258 {
261
266
267 return 1;
268 }
269
271 {
279 return 1;
280 }
281
283 {
286
295 }
297
298 return 1;
299 }
300
302 {
304 int fps;
305
308 if (fps)
311
312 return 0;
313 }
314
315 /*
316 * Process EA file header
317 * Returns 1 if the EA file is valid and successfully opened, 0 otherwise
318 */
320 uint32_t blockid,
size = 0;
323 int i;
324
327 int err = 0;
328
331 if (i == 0)
335
336 switch (blockid) {
340 return 0;
341 }
343 break;
344
350 }
else if ((blockid & 0xFFFF)!=
PT00_TAG) {
352 return 0;
353 }
355 break;
356
359 break;
360
363 break;
364
367 break;
368
371 break;
372
375 break;
376
380 break;
381
384 break;
385
388 break;
389
392 break;
393 }
394
395 if (err < 0) {
397 return err;
398 }
399
400 avio_seek(pb, startpos + size, SEEK_SET);
401 }
402
404
405 return 1;
406 }
407
408
410 {
421 break;
422 default:
423 return 0;
424 }
426 return 0;
428 }
429
431 {
434
437
439 /* initialize the video decoder stream */
441 if (!st)
446 // parsing is necessary to make FFmpeg generate correct timestamps
457 }
458
463 return 1;
464 }
468 return 1;
469 }
470 if (ea->
bytes <= 0) {
473 return 1;
474 }
475
476 /* initialize the audio decoder stream */
478 if (!st)
492 }
493
494 return 1;
495 }
496
499 {
503 int packet_read = 0;
504 int partial_packet = 0;
505 unsigned int chunk_type, chunk_size;
506 int key = 0;
508
509 while (!packet_read || partial_packet) {
512 if (chunk_size <= 8)
514 chunk_size -= 8;
515
516 switch (chunk_type) {
517 /* audio data */
519 /* header chunk also contains data; skip over the header portion*/
520 if (chunk_size < 32)
523 chunk_size -= 32;
530 break;
535 chunk_size -= 12;
536 }
537 if (partial_packet) {
540 partial_packet = 0;
541 }
543 if (ret < 0)
546
554 break;
558 break;
561 break;
565 break;
566 default:
568 }
569
570 packet_read = 1;
571 break;
572
573 /* ending tag */
574 case 0:
580 packet_read = 1;
581 break;
582
593 avio_seek(pb, -8, SEEK_CUR);
// include chunk preamble
594 chunk_size += 8;
595 goto get_video_packet;
596
599 chunk_size -= 8;
600 goto get_video_packet;
601
607 get_video_packet:
608 if (partial_packet) {
610 } else
612 if (ret < 0) {
613 packet_read = 1;
614 break;
615 }
616 partial_packet = chunk_type ==
MVIh_TAG;
619 packet_read = 1;
620 break;
621
622 default:
624 break;
625 }
626 }
627
628 if (ret < 0 && partial_packet)
631 }
632
640 };