1
/* Electronic Arts Multimedia File Demuxer
2
* Copyright (c) 2004 The ffmpeg Project
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
* @file electronicarts.c
21
* Electronic Arts Multimedia file demuxer (WVE/UV2/etc.)
22
* by Robin Kay (komadori at gekkou.co.uk)
27
#define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
28
#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
29
#define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
30
#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T')
31
#define SCEl_TAG MKTAG('S', 'C', 'E', 'l')
32
#define _TAG MKTAG('', '', '', '')
34
#define EA_SAMPLE_RATE 22050
35
#define EA_BITS_PER_SAMPLE 16
36
#define EA_PREAMBLE_SIZE 8
38
typedef struct EaDemuxContext {
41
int video_stream_index;
44
int audio_stream_index;
45
int audio_frame_counter;
57
static uint32_t read_arbitary(ByteIOContext *pb) {
65
for (i = 0; i < size; i++) {
75
* Process WVE file header
76
* Returns 1 if the WVE file is valid and successfully opened, 0 otherwise
78
static int process_ea_header(AVFormatContext *s) {
80
uint32_t blockid, size;
81
EaDemuxContext *ea = (EaDemuxContext *)s->priv_data;
82
ByteIOContext *pb = &s->pb;
84
if (get_buffer(pb, (void*)&blockid, 4) != 4) {
87
if (le2me_32(blockid) != SCHl_TAG) {
91
if (get_buffer(pb, (void*)&size, 4) != 4) {
94
size = le2me_32(size);
96
if (get_buffer(pb, (void*)&blockid, 4) != 4) {
99
if (le2me_32(blockid) != PT00_TAG) {
100
av_log (s, AV_LOG_ERROR, "PT header missing\n");
108
byte = get_byte(pb) & 0xFF;
112
av_log (s, AV_LOG_INFO, "entered audio subheader\n");
114
while (inSubheader) {
116
subbyte = get_byte(pb) & 0xFF;
120
ea->num_channels = read_arbitary(pb);
121
av_log (s, AV_LOG_INFO, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels);
124
ea->compression_type = read_arbitary(pb);
125
av_log (s, AV_LOG_INFO, "compression_type (element 0x83) set to 0x%08x\n", ea->compression_type);
128
ea->num_samples = read_arbitary(pb);
129
av_log (s, AV_LOG_INFO, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples);
132
av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
133
av_log (s, AV_LOG_INFO, "exited audio subheader\n");
137
av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
143
av_log (s, AV_LOG_INFO, "end of header block reached\n");
147
av_log (s, AV_LOG_INFO, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb));
152
if ((ea->num_channels != 2) || (ea->compression_type != 7)) {
153
av_log (s, AV_LOG_ERROR, "unsupported stream type\n");
157
/* skip to the start of the data */
158
url_fseek(pb, size, SEEK_SET);
164
static int ea_probe(AVProbeData *p)
169
if (LE_32(&p->buf[0]) != SCHl_TAG)
172
return AVPROBE_SCORE_MAX;
175
static int ea_read_header(AVFormatContext *s,
176
AVFormatParameters *ap)
178
EaDemuxContext *ea = (EaDemuxContext *)s->priv_data;
181
if (!process_ea_header(s))
185
/* initialize the video decoder stream */
186
st = av_new_stream(s, 0);
188
return AVERROR_NOMEM;
189
av_set_pts_info(st, 33, 1, 90000);
190
ea->video_stream_index = st->index;
191
st->codec->codec_type = CODEC_TYPE_VIDEO;
192
st->codec->codec_id = CODEC_ID_EA_MJPEG;
193
st->codec->codec_tag = 0; /* no fourcc */
196
/* initialize the audio decoder stream */
197
st = av_new_stream(s, 0);
199
return AVERROR_NOMEM;
200
av_set_pts_info(st, 33, 1, EA_SAMPLE_RATE);
201
st->codec->codec_type = CODEC_TYPE_AUDIO;
202
st->codec->codec_id = CODEC_ID_ADPCM_EA;
203
st->codec->codec_tag = 0; /* no tag */
204
st->codec->channels = ea->num_channels;
205
st->codec->sample_rate = EA_SAMPLE_RATE;
206
st->codec->bits_per_sample = EA_BITS_PER_SAMPLE;
207
st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
208
st->codec->bits_per_sample / 4;
209
st->codec->block_align = st->codec->channels * st->codec->bits_per_sample;
211
ea->audio_stream_index = st->index;
212
ea->audio_frame_counter = 0;
217
static int ea_read_packet(AVFormatContext *s,
220
EaDemuxContext *ea = s->priv_data;
221
ByteIOContext *pb = &s->pb;
224
unsigned char preamble[EA_PREAMBLE_SIZE];
225
unsigned int chunk_type, chunk_size;
227
while (!packet_read) {
229
if (get_buffer(pb, preamble, EA_PREAMBLE_SIZE) != EA_PREAMBLE_SIZE)
231
chunk_type = LE_32(&preamble[0]);
232
chunk_size = LE_32(&preamble[4]) - EA_PREAMBLE_SIZE;
234
switch (chunk_type) {
237
ret = av_get_packet(pb, pkt, chunk_size);
238
if (ret != chunk_size)
241
pkt->stream_index = ea->audio_stream_index;
243
pkt->pts *= ea->audio_frame_counter;
244
pkt->pts /= EA_SAMPLE_RATE;
246
/* 2 samples/byte, 1 or 2 samples per frame depending
247
* on stereo; chunk also has 12-byte header */
248
ea->audio_frame_counter += ((chunk_size - 12) * 2) /
262
url_fseek(pb, chunk_size, SEEK_CUR);
267
if (chunk_type == SCEl_TAG) {
274
static int ea_read_close(AVFormatContext *s)
276
// EaDemuxContext *ea = (EaDemuxContext *)s->priv_data;
281
static AVInputFormat ea_iformat = {
283
"Electronic Arts Multimedia Format",
284
sizeof(EaDemuxContext),
293
av_register_input_format(&ea_iformat);