00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #include "avformat.h"
00028
00029 #define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
00030 #define SEAD_TAG MKTAG('S', 'E', 'A', 'D')
00031 #define SNDC_TAG MKTAG('S', 'N', 'D', 'C')
00032 #define SEND_TAG MKTAG('S', 'E', 'N', 'D')
00033 #define ISNh_TAG MKTAG('1', 'S', 'N', 'h')
00034 #define EACS_TAG MKTAG('E', 'A', 'C', 'S')
00035 #define ISNd_TAG MKTAG('1', 'S', 'N', 'd')
00036 #define ISNe_TAG MKTAG('1', 'S', 'N', 'e')
00037 #define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
00038 #define GSTR_TAG MKTAG('G', 'S', 'T', 'R')
00039 #define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
00040 #define SCEl_TAG MKTAG('S', 'C', 'E', 'l')
00041 #define kVGT_TAG MKTAG('k', 'V', 'G', 'T')
00042 #define MADk_TAG MKTAG('M', 'A', 'D', 'k')
00043 #define MPCh_TAG MKTAG('M', 'P', 'C', 'h')
00044 #define MVhd_TAG MKTAG('M', 'V', 'h', 'd')
00045 #define MV0K_TAG MKTAG('M', 'V', '0', 'K')
00046 #define MV0F_TAG MKTAG('M', 'V', '0', 'F')
00047 #define MVIh_TAG MKTAG('M', 'V', 'I', 'h')
00048
00049 typedef struct EaDemuxContext {
00050 int big_endian;
00051
00052 int video_codec;
00053 AVRational time_base;
00054 int video_stream_index;
00055
00056 int audio_codec;
00057 int audio_stream_index;
00058 int audio_frame_counter;
00059
00060 int64_t audio_pts;
00061
00062 int bytes;
00063 int sample_rate;
00064 int num_channels;
00065 int num_samples;
00066 } EaDemuxContext;
00067
00068 static uint32_t read_arbitary(ByteIOContext *pb) {
00069 uint8_t size, byte;
00070 int i;
00071 uint32_t word;
00072
00073 size = get_byte(pb);
00074
00075 word = 0;
00076 for (i = 0; i < size; i++) {
00077 byte = get_byte(pb);
00078 word <<= 8;
00079 word |= byte;
00080 }
00081
00082 return word;
00083 }
00084
00085
00086
00087
00088
00089 static int process_audio_header_elements(AVFormatContext *s)
00090 {
00091 int inHeader = 1;
00092 EaDemuxContext *ea = s->priv_data;
00093 ByteIOContext *pb = &s->pb;
00094 int compression_type = -1, revision = -1;
00095
00096 ea->bytes = 2;
00097 ea->sample_rate = -1;
00098 ea->num_channels = 1;
00099
00100 while (inHeader) {
00101 int inSubheader;
00102 uint8_t byte;
00103 byte = get_byte(pb);
00104
00105 switch (byte) {
00106 case 0xFD:
00107 av_log (s, AV_LOG_INFO, "entered audio subheader\n");
00108 inSubheader = 1;
00109 while (inSubheader) {
00110 uint8_t subbyte;
00111 subbyte = get_byte(pb);
00112
00113 switch (subbyte) {
00114 case 0x80:
00115 revision = read_arbitary(pb);
00116 av_log (s, AV_LOG_INFO, "revision (element 0x80) set to 0x%08x\n", revision);
00117 break;
00118 case 0x82:
00119 ea->num_channels = read_arbitary(pb);
00120 av_log (s, AV_LOG_INFO, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels);
00121 break;
00122 case 0x83:
00123 compression_type = read_arbitary(pb);
00124 av_log (s, AV_LOG_INFO, "compression_type (element 0x83) set to 0x%08x\n", compression_type);
00125 break;
00126 case 0x84:
00127 ea->sample_rate = read_arbitary(pb);
00128 av_log (s, AV_LOG_INFO, "sample_rate (element 0x84) set to %i\n", ea->sample_rate);
00129 break;
00130 case 0x85:
00131 ea->num_samples = read_arbitary(pb);
00132 av_log (s, AV_LOG_INFO, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples);
00133 break;
00134 case 0x8A:
00135 av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
00136 av_log (s, AV_LOG_INFO, "exited audio subheader\n");
00137 inSubheader = 0;
00138 break;
00139 case 0xFF:
00140 av_log (s, AV_LOG_INFO, "end of header block reached (within audio subheader)\n");
00141 inSubheader = 0;
00142 inHeader = 0;
00143 break;
00144 default:
00145 av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb));
00146 break;
00147 }
00148 }
00149 break;
00150 case 0xFF:
00151 av_log (s, AV_LOG_INFO, "end of header block reached\n");
00152 inHeader = 0;
00153 break;
00154 default:
00155 av_log (s, AV_LOG_INFO, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb));
00156 break;
00157 }
00158 }
00159
00160 switch (compression_type) {
00161 case 0: ea->audio_codec = CODEC_ID_PCM_S16LE; break;
00162 case 7: ea->audio_codec = CODEC_ID_ADPCM_EA; break;
00163 case -1:
00164 switch (revision) {
00165 case 1: ea->audio_codec = CODEC_ID_ADPCM_EA_R1; break;
00166 case 2: ea->audio_codec = CODEC_ID_ADPCM_EA_R2; break;
00167 case 3: ea->audio_codec = CODEC_ID_ADPCM_EA_R3; break;
00168 default:
00169 av_log(s, AV_LOG_ERROR, "unsupported stream type; revision=%i\n", revision);
00170 return 0;
00171 }
00172 break;
00173 default:
00174 av_log(s, AV_LOG_ERROR, "unsupported stream type; compression_type=%i\n", compression_type);
00175 return 0;
00176 }
00177
00178 if (ea->sample_rate == -1)
00179 ea->sample_rate = revision==3 ? 48000 : 22050;
00180
00181 return 1;
00182 }
00183
00184
00185
00186
00187
00188 static int process_audio_header_eacs(AVFormatContext *s)
00189 {
00190 EaDemuxContext *ea = s->priv_data;
00191 ByteIOContext *pb = &s->pb;
00192 int compression_type;
00193
00194 ea->sample_rate = ea->big_endian ? get_be32(pb) : get_le32(pb);
00195 ea->bytes = get_byte(pb);
00196 ea->num_channels = get_byte(pb);
00197 compression_type = get_byte(pb);
00198 url_fskip(pb, 13);
00199
00200 switch (compression_type) {
00201 case 0:
00202 switch (ea->bytes) {
00203 case 1: ea->audio_codec = CODEC_ID_PCM_S8; break;
00204 case 2: ea->audio_codec = CODEC_ID_PCM_S16LE; break;
00205 }
00206 break;
00207 case 1: ea->audio_codec = CODEC_ID_PCM_MULAW; ea->bytes = 1; break;
00208 case 2: ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_EACS; break;
00209 default:
00210 av_log (s, AV_LOG_ERROR, "unsupported stream type; audio compression_type=%i\n", compression_type);
00211 }
00212
00213 return 1;
00214 }
00215
00216
00217
00218
00219
00220 static int process_audio_header_sead(AVFormatContext *s)
00221 {
00222 EaDemuxContext *ea = s->priv_data;
00223 ByteIOContext *pb = &s->pb;
00224
00225 ea->sample_rate = get_le32(pb);
00226 ea->bytes = get_le32(pb);
00227 ea->num_channels = get_le32(pb);
00228 ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_SEAD;
00229
00230 return 1;
00231 }
00232
00233 static int process_video_header_vp6(AVFormatContext *s)
00234 {
00235 EaDemuxContext *ea = s->priv_data;
00236 ByteIOContext *pb = &s->pb;
00237
00238 url_fskip(pb, 16);
00239 ea->time_base.den = get_le32(pb);
00240 ea->time_base.num = get_le32(pb);
00241 ea->video_codec = CODEC_ID_VP6;
00242
00243 return 1;
00244 }
00245
00246
00247
00248
00249
00250 static int process_ea_header(AVFormatContext *s) {
00251 uint32_t blockid, size = 0;
00252 EaDemuxContext *ea = s->priv_data;
00253 ByteIOContext *pb = &s->pb;
00254 int i;
00255
00256 for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) {
00257 unsigned int startpos = url_ftell(pb);
00258 int err = 0;
00259
00260 blockid = get_le32(pb);
00261 size = get_le32(pb);
00262 if (i == 0)
00263 ea->big_endian = size > 0x000FFFFF;
00264 if (ea->big_endian)
00265 size = bswap_32(size);
00266
00267 switch (blockid) {
00268 case ISNh_TAG:
00269 if (get_le32(pb) != EACS_TAG) {
00270 av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n");
00271 return 0;
00272 }
00273 err = process_audio_header_eacs(s);
00274 break;
00275
00276 case SCHl_TAG :
00277 blockid = get_le32(pb);
00278 if (blockid == GSTR_TAG) {
00279 url_fskip(pb, 4);
00280 } else if (blockid != PT00_TAG) {
00281 av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n");
00282 return 0;
00283 }
00284 err = process_audio_header_elements(s);
00285 break;
00286
00287 case SEAD_TAG:
00288 err = process_audio_header_sead(s);
00289 break;
00290
00291 case MVhd_TAG :
00292 err = process_video_header_vp6(s);
00293 break;
00294 }
00295
00296 if (err < 0) {
00297 av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err);
00298 return err;
00299 }
00300
00301 url_fseek(pb, startpos + size, SEEK_SET);
00302 }
00303
00304 url_fseek(pb, 0, SEEK_SET);
00305
00306 return 1;
00307 }
00308
00309
00310 static int ea_probe(AVProbeData *p)
00311 {
00312 switch (AV_RL32(&p->buf[0])) {
00313 case ISNh_TAG:
00314 case SCHl_TAG:
00315 case SEAD_TAG:
00316 case kVGT_TAG:
00317 case MADk_TAG:
00318 case MPCh_TAG:
00319 case MVhd_TAG:
00320 case MVIh_TAG:
00321 return AVPROBE_SCORE_MAX;
00322 }
00323 return 0;
00324 }
00325
00326 static int ea_read_header(AVFormatContext *s,
00327 AVFormatParameters *ap)
00328 {
00329 EaDemuxContext *ea = s->priv_data;
00330 AVStream *st;
00331
00332 if (!process_ea_header(s))
00333 return AVERROR(EIO);
00334
00335 if (ea->video_codec) {
00336
00337 st = av_new_stream(s, 0);
00338 if (!st)
00339 return AVERROR(ENOMEM);
00340 ea->video_stream_index = st->index;
00341 st->codec->codec_type = CODEC_TYPE_VIDEO;
00342 st->codec->codec_id = ea->video_codec;
00343 st->codec->codec_tag = 0;
00344 st->codec->time_base = ea->time_base;
00345 }
00346
00347 if (ea->audio_codec) {
00348
00349 st = av_new_stream(s, 0);
00350 if (!st)
00351 return AVERROR(ENOMEM);
00352 av_set_pts_info(st, 33, 1, ea->sample_rate);
00353 st->codec->codec_type = CODEC_TYPE_AUDIO;
00354 st->codec->codec_id = ea->audio_codec;
00355 st->codec->codec_tag = 0;
00356 st->codec->channels = ea->num_channels;
00357 st->codec->sample_rate = ea->sample_rate;
00358 st->codec->bits_per_sample = ea->bytes * 8;
00359 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
00360 st->codec->bits_per_sample / 4;
00361 st->codec->block_align = st->codec->channels*st->codec->bits_per_sample;
00362 ea->audio_stream_index = st->index;
00363 ea->audio_frame_counter = 0;
00364 }
00365
00366 return 1;
00367 }
00368
00369 static int ea_read_packet(AVFormatContext *s,
00370 AVPacket *pkt)
00371 {
00372 EaDemuxContext *ea = s->priv_data;
00373 ByteIOContext *pb = &s->pb;
00374 int ret = 0;
00375 int packet_read = 0;
00376 unsigned int chunk_type, chunk_size;
00377 int key = 0;
00378
00379 while (!packet_read) {
00380 chunk_type = get_le32(pb);
00381 chunk_size = (ea->big_endian ? get_be32(pb) : get_le32(pb)) - 8;
00382
00383 switch (chunk_type) {
00384
00385 case ISNh_TAG:
00386
00387 url_fskip(pb, 32);
00388 chunk_size -= 32;
00389 case ISNd_TAG:
00390 case SCDl_TAG:
00391 case SNDC_TAG:
00392 if (!ea->audio_codec) {
00393 url_fskip(pb, chunk_size);
00394 break;
00395 }
00396 ret = av_get_packet(pb, pkt, chunk_size);
00397 if (ret != chunk_size)
00398 ret = AVERROR(EIO);
00399 else {
00400 pkt->stream_index = ea->audio_stream_index;
00401 pkt->pts = 90000;
00402 pkt->pts *= ea->audio_frame_counter;
00403 pkt->pts /= ea->sample_rate;
00404
00405 switch (ea->audio_codec) {
00406 case CODEC_ID_ADPCM_EA:
00407
00408
00409 ea->audio_frame_counter += ((chunk_size - 12) * 2) /
00410 ea->num_channels;
00411 break;
00412 default:
00413 ea->audio_frame_counter += chunk_size /
00414 (ea->bytes * ea->num_channels);
00415 }
00416 }
00417
00418 packet_read = 1;
00419 break;
00420
00421
00422 case 0:
00423 case ISNe_TAG:
00424 case SCEl_TAG:
00425 case SEND_TAG:
00426 ret = AVERROR(EIO);
00427 packet_read = 1;
00428 break;
00429
00430 case MV0K_TAG:
00431 key = PKT_FLAG_KEY;
00432 case MV0F_TAG:
00433 ret = av_get_packet(pb, pkt, chunk_size);
00434 if (ret != chunk_size)
00435 ret = AVERROR_IO;
00436 else {
00437 pkt->stream_index = ea->video_stream_index;
00438 pkt->flags |= key;
00439 }
00440 packet_read = 1;
00441 break;
00442
00443 default:
00444 url_fseek(pb, chunk_size, SEEK_CUR);
00445 break;
00446 }
00447 }
00448
00449 return ret;
00450 }
00451
00452 AVInputFormat ea_demuxer = {
00453 "ea",
00454 "Electronic Arts Multimedia Format",
00455 sizeof(EaDemuxContext),
00456 ea_probe,
00457 ea_read_header,
00458 ea_read_packet,
00459 };