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