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 MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */
63 #define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV I-frame */
64
67
73
76
82
84 {
86 int i;
87 uint32_t word;
88
90
91 word = 0;
92 for (i = 0; i <
size; i++) {
94 word <<= 8;
96 }
97
98 return word;
99 }
100
102 {
105 int in_header = 1;
106 int compression_type = -1, revision = -1, revision2 = -1;
107
111
113 int in_subheader;
116
117 switch (byte) {
118 case 0xFD:
120 in_subheader = 1;
124
125 switch (subbyte) {
126 case 0x80:
129 "revision (element 0x80) set to 0x%08x\n", revision);
130 break;
131 case 0x82:
134 "num_channels (element 0x82) set to 0x%08x\n",
136 break;
137 case 0x83:
140 "compression_type (element 0x83) set to 0x%08x\n",
141 compression_type);
142 break;
143 case 0x84:
146 "sample_rate (element 0x84) set to %i\n",
148 break;
149 case 0x85:
152 "num_samples (element 0x85) set to 0x%08x\n",
154 break;
155 case 0x8A:
157 "element 0x%02x set to 0x%08"PRIx32"\n",
160 in_subheader = 0;
161 break;
162 case 0xA0:
165 "revision2 (element 0xA0) set to 0x%08x\n",
166 revision2);
167 break;
168 case 0xFF:
170 "end of header block reached (within audio subheader)\n");
171 in_subheader = 0;
172 in_header = 0;
173 break;
174 default:
176 "element 0x%02x set to 0x%08"PRIx32"\n",
178 break;
179 }
180 }
181 break;
182 case 0xFF:
184 in_header = 0;
185 break;
186 default:
188 "header element 0x%02x set to 0x%08"PRIx32"\n",
190 break;
191 }
192 }
193
194 switch (compression_type) {
195 case 0:
197 break;
198 case 7:
200 break;
201 case -1:
202 switch (revision) {
203 case 1:
205 break;
206 case 2:
208 break;
209 case 3:
211 break;
212 case -1:
213 break;
214 default:
216 return 0;
217 }
218 switch (revision2) {
219 case 8:
221 break;
222 case 10:
223 switch (revision) {
224 case -1:
227 default:
229 return 0;
230 }
231 break;
232 case 16:
234 break;
235 case -1:
236 break;
237 default:
240 return 0;
241 }
242 break;
243 default:
245 "stream type; compression_type=%i",
246 compression_type);
247 return 0;
248 }
249
252
253 return 1;
254 }
255
257 {
260 int compression_type;
261
265 compression_type =
avio_r8(pb);
267
268 switch (compression_type) {
269 case 0:
271 case 1:
273 break;
274 case 2:
276 break;
277 }
278 break;
279 case 1:
282 break;
283 case 2:
285 break;
286 default:
288 "stream type; audio compression_type=%i",
289 compression_type);
290 }
291 }
292
294 {
297
302 }
303
305 {
313 }
314
316 {
319
328 }
330
331 return 1;
332 }
333
335 {
337 int fps;
338
341 if (fps)
344 }
345
346 /* Process EA file header.
347 * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
349 {
350 uint32_t blockid,
size = 0;
353 int i;
354
357 int err = 0;
358
361 if (i == 0)
365
366 if (size < 8) {
369 }
370
371 switch (blockid) {
375 return 0;
376 }
378 break;
379
385 }
else if ((blockid & 0xFFFF) !=
PT00_TAG) {
387 return 0;
388 }
390 break;
391
394 break;
395
398 break;
399
402 break;
403
406 break;
407
410 break;
411
416 break;
417
421 break;
422
427 break;
428
431 break;
432 }
433
434 if (err < 0) {
436 return err;
437 }
438
439 avio_seek(pb, startpos + size, SEEK_SET);
440 }
441
443
444 return 1;
445 }
446
448 {
449 unsigned big_endian,
size;
450
461 break;
462 default:
463 return 0;
464 }
466 big_endian = size > 0x000FFFFF;
467 if (big_endian)
469 if (size > 0xfffff || size < 8)
470 return 0;
471
473 }
474
476 {
479
482
484 /* initialize the video decoder stream */
486 if (!st)
491 // parsing is necessary to make FFmpeg generate correct timestamps
502 }
503
507 "Unsupported number of channels: %d\n", ea->
num_channels);
509 return 1;
510 }
515 return 1;
516 }
517 if (ea->
bytes <= 0) {
519 "Invalid number of bytes per sample: %d\n", ea->
bytes);
521 return 1;
522 }
523
524 /* initialize the audio decoder stream */
526 if (!st)
542 }
543
544 return 1;
545 }
546
548 {
551 int partial_packet = 0;
552 unsigned int chunk_type, chunk_size;
553 int ret = 0, packet_read = 0, key = 0;
555
556 while (!packet_read || partial_packet) {
559 if (chunk_size < 8)
561 chunk_size -= 8;
562
563 switch (chunk_type) {
564 /* audio data */
566 /* header chunk also contains data; skip over the header portion */
567 if (chunk_size < 32)
570 chunk_size -= 32;
577 break;
582 chunk_size -= 12;
583 }
584
585 if (partial_packet) {
588 partial_packet = 0;
589 }
590
591 if (!chunk_size)
592 continue;
593
595 if (ret < 0)
598
609 }
612 else
614 break;
617 break;
621 break;
622 default:
624 }
625
626 packet_read = 1;
627 break;
628
629 /* ending tag */
630 case 0:
636 packet_read = 1;
637 break;
638
649 avio_seek(pb, -8, SEEK_CUR);
// include chunk preamble
650 chunk_size += 8;
651 goto get_video_packet;
652
654 if (chunk_size < 8)
656
658 chunk_size -= 8;
659 goto get_video_packet;
660
666 get_video_packet:
667 if (!chunk_size)
668 continue;
669
670 if (partial_packet) {
672 } else
674 if (ret < 0) {
675 packet_read = 1;
676 break;
677 }
678 partial_packet = chunk_type ==
MVIh_TAG;
681 packet_read = 1;
682 break;
683
684 default:
686 break;
687 }
688 }
689
690 if (ret < 0 && partial_packet)
693 }
694
702 };