#include "avformat.h"Go to the source code of this file.
Data Structures | |
| struct | EaDemuxContext |
Defines | |
| #define | SCHl_TAG MKTAG('S', 'C', 'H', 'l') |
| #define | SEAD_TAG MKTAG('S', 'E', 'A', 'D') |
| #define | SNDC_TAG MKTAG('S', 'N', 'D', 'C') |
| #define | SEND_TAG MKTAG('S', 'E', 'N', 'D') |
| #define | ISNh_TAG MKTAG('1', 'S', 'N', 'h') |
| #define | EACS_TAG MKTAG('E', 'A', 'C', 'S') |
| #define | ISNd_TAG MKTAG('1', 'S', 'N', 'd') |
| #define | ISNe_TAG MKTAG('1', 'S', 'N', 'e') |
| #define | PT00_TAG MKTAG('P', 'T', 0x0, 0x0) |
| #define | GSTR_TAG MKTAG('G', 'S', 'T', 'R') |
| #define | SCDl_TAG MKTAG('S', 'C', 'D', 'l') |
| #define | SCEl_TAG MKTAG('S', 'C', 'E', 'l') |
| #define | kVGT_TAG MKTAG('k', 'V', 'G', 'T') |
| #define | MADk_TAG MKTAG('M', 'A', 'D', 'k') |
| #define | MPCh_TAG MKTAG('M', 'P', 'C', 'h') |
| #define | MVhd_TAG MKTAG('M', 'V', 'h', 'd') |
| #define | MV0K_TAG MKTAG('M', 'V', '0', 'K') |
| #define | MV0F_TAG MKTAG('M', 'V', '0', 'F') |
| #define | MVIh_TAG MKTAG('M', 'V', 'I', 'h') |
| #define | MVIf_TAG MKTAG('M', 'V', 'I', 'f') |
Functions | |
| static uint32_t | read_arbitary (ByteIOContext *pb) |
| static int | process_audio_header_elements (AVFormatContext *s) |
| static int | process_audio_header_eacs (AVFormatContext *s) |
| static int | process_audio_header_sead (AVFormatContext *s) |
| static int | process_video_header_vp6 (AVFormatContext *s) |
| static int | process_ea_header (AVFormatContext *s) |
| static int | ea_probe (AVProbeData *p) |
| static int | ea_read_header (AVFormatContext *s, AVFormatParameters *ap) |
| static int | ea_read_packet (AVFormatContext *s, AVPacket *pkt) |
Variables | |
| AVInputFormat | ea_demuxer |
Definition in file electronicarts.c.
| #define EACS_TAG MKTAG('E', 'A', 'C', 'S') |
| #define ISNd_TAG MKTAG('1', 'S', 'N', 'd') |
| #define ISNe_TAG MKTAG('1', 'S', 'N', 'e') |
| #define ISNh_TAG MKTAG('1', 'S', 'N', 'h') |
Definition at line 34 of file electronicarts.c.
Referenced by ea_probe(), ea_read_packet(), and process_ea_header().
| #define kVGT_TAG MKTAG('k', 'V', 'G', 'T') |
| #define MADk_TAG MKTAG('M', 'A', 'D', 'k') |
| #define MPCh_TAG MKTAG('M', 'P', 'C', 'h') |
| #define MV0F_TAG MKTAG('M', 'V', '0', 'F') |
| #define MV0K_TAG MKTAG('M', 'V', '0', 'K') |
| #define MVhd_TAG MKTAG('M', 'V', 'h', 'd') |
| #define MVIf_TAG MKTAG('M', 'V', 'I', 'f') |
| #define MVIh_TAG MKTAG('M', 'V', 'I', 'h') |
Definition at line 48 of file electronicarts.c.
| #define PT00_TAG MKTAG('P', 'T', 0x0, 0x0) |
| #define SCDl_TAG MKTAG('S', 'C', 'D', 'l') |
| #define SCEl_TAG MKTAG('S', 'C', 'E', 'l') |
| #define SCHl_TAG MKTAG('S', 'C', 'H', 'l') |
| #define SEAD_TAG MKTAG('S', 'E', 'A', 'D') |
| #define SEND_TAG MKTAG('S', 'E', 'N', 'D') |
| #define SNDC_TAG MKTAG('S', 'N', 'D', 'C') |
| static int ea_probe | ( | AVProbeData * | p | ) | [static] |
Definition at line 328 of file electronicarts.c.
References AV_RL32, AVPROBE_SCORE_MAX, AVProbeData::buf, ISNh_TAG, kVGT_TAG, MADk_TAG, MPCh_TAG, MVhd_TAG, MVIh_TAG, SCHl_TAG, and SEAD_TAG.
00329 { 00330 switch (AV_RL32(&p->buf[0])) { 00331 case ISNh_TAG: 00332 case SCHl_TAG: 00333 case SEAD_TAG: 00334 case kVGT_TAG: 00335 case MADk_TAG: 00336 case MPCh_TAG: 00337 case MVhd_TAG: 00338 case MVIh_TAG: 00339 return AVPROBE_SCORE_MAX; 00340 } 00341 return 0; 00342 }
| static int ea_read_header | ( | AVFormatContext * | s, | |
| AVFormatParameters * | ap | |||
| ) | [static] |
Definition at line 344 of file electronicarts.c.
References EaDemuxContext::audio_codec, EaDemuxContext::audio_frame_counter, EaDemuxContext::audio_stream_index, av_new_stream(), av_set_pts_info(), AVERROR, AVCodecContext::bit_rate, AVCodecContext::bits_per_sample, AVCodecContext::block_align, EaDemuxContext::bytes, AVCodecContext::channels, AVStream::codec, AVCodecContext::codec_id, AVCodecContext::codec_tag, AVCodecContext::codec_type, CODEC_TYPE_AUDIO, CODEC_TYPE_VIDEO, AVStream::index, EaDemuxContext::num_channels, AVFormatContext::priv_data, process_ea_header(), AVCodecContext::sample_rate, EaDemuxContext::sample_rate, EaDemuxContext::time_base, AVCodecContext::time_base, EaDemuxContext::video_codec, and EaDemuxContext::video_stream_index.
00346 { 00347 EaDemuxContext *ea = s->priv_data; 00348 AVStream *st; 00349 00350 if (!process_ea_header(s)) 00351 return AVERROR(EIO); 00352 00353 if (ea->video_codec) { 00354 /* initialize the video decoder stream */ 00355 st = av_new_stream(s, 0); 00356 if (!st) 00357 return AVERROR(ENOMEM); 00358 ea->video_stream_index = st->index; 00359 st->codec->codec_type = CODEC_TYPE_VIDEO; 00360 st->codec->codec_id = ea->video_codec; 00361 st->codec->codec_tag = 0; /* no fourcc */ 00362 st->codec->time_base = ea->time_base; 00363 } 00364 00365 if (ea->audio_codec) { 00366 /* initialize the audio decoder stream */ 00367 st = av_new_stream(s, 0); 00368 if (!st) 00369 return AVERROR(ENOMEM); 00370 av_set_pts_info(st, 33, 1, ea->sample_rate); 00371 st->codec->codec_type = CODEC_TYPE_AUDIO; 00372 st->codec->codec_id = ea->audio_codec; 00373 st->codec->codec_tag = 0; /* no tag */ 00374 st->codec->channels = ea->num_channels; 00375 st->codec->sample_rate = ea->sample_rate; 00376 st->codec->bits_per_sample = ea->bytes * 8; 00377 st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 00378 st->codec->bits_per_sample / 4; 00379 st->codec->block_align = st->codec->channels*st->codec->bits_per_sample; 00380 ea->audio_stream_index = st->index; 00381 ea->audio_frame_counter = 0; 00382 } 00383 00384 return 1; 00385 }
| static int ea_read_packet | ( | AVFormatContext * | s, | |
| AVPacket * | pkt | |||
| ) | [static] |
Definition at line 387 of file electronicarts.c.
References EaDemuxContext::audio_codec, EaDemuxContext::audio_frame_counter, EaDemuxContext::audio_stream_index, av_get_packet(), AVERROR, AVERROR_IO, EaDemuxContext::big_endian, EaDemuxContext::bytes, CODEC_ID_ADPCM_EA, CODEC_ID_PCM_S16LE_PLANAR, AVPacket::flags, get_be32(), get_le32(), ISNd_TAG, ISNe_TAG, ISNh_TAG, MV0F_TAG, MV0K_TAG, MVIf_TAG, MVIh_TAG, EaDemuxContext::num_channels, AVFormatContext::pb, PKT_FLAG_KEY, AVFormatContext::priv_data, AVPacket::pts, EaDemuxContext::sample_rate, SCDl_TAG, SCEl_TAG, SEND_TAG, SNDC_TAG, AVPacket::stream_index, url_fseek(), url_fskip(), and EaDemuxContext::video_stream_index.
00389 { 00390 EaDemuxContext *ea = s->priv_data; 00391 ByteIOContext *pb = s->pb; 00392 int ret = 0; 00393 int packet_read = 0; 00394 unsigned int chunk_type, chunk_size; 00395 int key = 0; 00396 00397 while (!packet_read) { 00398 chunk_type = get_le32(pb); 00399 chunk_size = (ea->big_endian ? get_be32(pb) : get_le32(pb)) - 8; 00400 00401 switch (chunk_type) { 00402 /* audio data */ 00403 case ISNh_TAG: 00404 /* header chunk also contains data; skip over the header portion*/ 00405 url_fskip(pb, 32); 00406 chunk_size -= 32; 00407 case ISNd_TAG: 00408 case SCDl_TAG: 00409 case SNDC_TAG: 00410 if (!ea->audio_codec) { 00411 url_fskip(pb, chunk_size); 00412 break; 00413 } else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR) { 00414 url_fskip(pb, 12); /* planar header */ 00415 chunk_size -= 12; 00416 } 00417 ret = av_get_packet(pb, pkt, chunk_size); 00418 if (ret != chunk_size) 00419 ret = AVERROR(EIO); 00420 else { 00421 pkt->stream_index = ea->audio_stream_index; 00422 pkt->pts = 90000; 00423 pkt->pts *= ea->audio_frame_counter; 00424 pkt->pts /= ea->sample_rate; 00425 00426 switch (ea->audio_codec) { 00427 case CODEC_ID_ADPCM_EA: 00428 /* 2 samples/byte, 1 or 2 samples per frame depending 00429 * on stereo; chunk also has 12-byte header */ 00430 ea->audio_frame_counter += ((chunk_size - 12) * 2) / 00431 ea->num_channels; 00432 break; 00433 default: 00434 ea->audio_frame_counter += chunk_size / 00435 (ea->bytes * ea->num_channels); 00436 } 00437 } 00438 00439 packet_read = 1; 00440 break; 00441 00442 /* ending tag */ 00443 case 0: 00444 case ISNe_TAG: 00445 case SCEl_TAG: 00446 case SEND_TAG: 00447 ret = AVERROR(EIO); 00448 packet_read = 1; 00449 break; 00450 00451 case MVIh_TAG: 00452 key = PKT_FLAG_KEY; 00453 case MVIf_TAG: 00454 url_fseek(pb, -8, SEEK_CUR); // include chunk preamble 00455 chunk_size += 8; 00456 goto get_video_packet; 00457 00458 case MV0K_TAG: 00459 key = PKT_FLAG_KEY; 00460 case MV0F_TAG: 00461 get_video_packet: 00462 ret = av_get_packet(pb, pkt, chunk_size); 00463 if (ret != chunk_size) 00464 ret = AVERROR_IO; 00465 else { 00466 pkt->stream_index = ea->video_stream_index; 00467 pkt->flags |= key; 00468 } 00469 packet_read = 1; 00470 break; 00471 00472 default: 00473 url_fseek(pb, chunk_size, SEEK_CUR); 00474 break; 00475 } 00476 } 00477 00478 return ret; 00479 }
| static int process_audio_header_eacs | ( | AVFormatContext * | s | ) | [static] |
Definition at line 201 of file electronicarts.c.
References EaDemuxContext::audio_codec, av_log(), AV_LOG_ERROR, EaDemuxContext::big_endian, EaDemuxContext::bytes, CODEC_ID_ADPCM_IMA_EA_EACS, CODEC_ID_PCM_MULAW, CODEC_ID_PCM_S16LE, CODEC_ID_PCM_S8, get_be32(), get_byte(), get_le32(), EaDemuxContext::num_channels, AVFormatContext::pb, AVFormatContext::priv_data, EaDemuxContext::sample_rate, and url_fskip().
Referenced by process_ea_header().
00202 { 00203 EaDemuxContext *ea = s->priv_data; 00204 ByteIOContext *pb = s->pb; 00205 int compression_type; 00206 00207 ea->sample_rate = ea->big_endian ? get_be32(pb) : get_le32(pb); 00208 ea->bytes = get_byte(pb); /* 1=8-bit, 2=16-bit */ 00209 ea->num_channels = get_byte(pb); 00210 compression_type = get_byte(pb); 00211 url_fskip(pb, 13); 00212 00213 switch (compression_type) { 00214 case 0: 00215 switch (ea->bytes) { 00216 case 1: ea->audio_codec = CODEC_ID_PCM_S8; break; 00217 case 2: ea->audio_codec = CODEC_ID_PCM_S16LE; break; 00218 } 00219 break; 00220 case 1: ea->audio_codec = CODEC_ID_PCM_MULAW; ea->bytes = 1; break; 00221 case 2: ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_EACS; break; 00222 default: 00223 av_log (s, AV_LOG_ERROR, "unsupported stream type; audio compression_type=%i\n", compression_type); 00224 } 00225 00226 return 1; 00227 }
| static int process_audio_header_elements | ( | AVFormatContext * | s | ) | [static] |
Definition at line 91 of file electronicarts.c.
References EaDemuxContext::audio_codec, av_log(), AV_LOG_ERROR, AV_LOG_INFO, EaDemuxContext::bytes, CODEC_ID_ADPCM_EA, CODEC_ID_ADPCM_EA_R1, CODEC_ID_ADPCM_EA_R2, CODEC_ID_ADPCM_EA_R3, CODEC_ID_PCM_S16LE, CODEC_ID_PCM_S16LE_PLANAR, get_byte(), EaDemuxContext::num_channels, EaDemuxContext::num_samples, AVFormatContext::pb, AVFormatContext::priv_data, read_arbitary(), and EaDemuxContext::sample_rate.
Referenced by process_ea_header().
00092 { 00093 int inHeader = 1; 00094 EaDemuxContext *ea = s->priv_data; 00095 ByteIOContext *pb = s->pb; 00096 int compression_type = -1, revision = -1, revision2 = -1; 00097 00098 ea->bytes = 2; 00099 ea->sample_rate = -1; 00100 ea->num_channels = 1; 00101 00102 while (inHeader) { 00103 int inSubheader; 00104 uint8_t byte; 00105 byte = get_byte(pb); 00106 00107 switch (byte) { 00108 case 0xFD: 00109 av_log (s, AV_LOG_INFO, "entered audio subheader\n"); 00110 inSubheader = 1; 00111 while (inSubheader) { 00112 uint8_t subbyte; 00113 subbyte = get_byte(pb); 00114 00115 switch (subbyte) { 00116 case 0x80: 00117 revision = read_arbitary(pb); 00118 av_log (s, AV_LOG_INFO, "revision (element 0x80) set to 0x%08x\n", revision); 00119 break; 00120 case 0x82: 00121 ea->num_channels = read_arbitary(pb); 00122 av_log (s, AV_LOG_INFO, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels); 00123 break; 00124 case 0x83: 00125 compression_type = read_arbitary(pb); 00126 av_log (s, AV_LOG_INFO, "compression_type (element 0x83) set to 0x%08x\n", compression_type); 00127 break; 00128 case 0x84: 00129 ea->sample_rate = read_arbitary(pb); 00130 av_log (s, AV_LOG_INFO, "sample_rate (element 0x84) set to %i\n", ea->sample_rate); 00131 break; 00132 case 0x85: 00133 ea->num_samples = read_arbitary(pb); 00134 av_log (s, AV_LOG_INFO, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples); 00135 break; 00136 case 0x8A: 00137 av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); 00138 av_log (s, AV_LOG_INFO, "exited audio subheader\n"); 00139 inSubheader = 0; 00140 break; 00141 case 0xA0: 00142 revision2 = read_arbitary(pb); 00143 av_log (s, AV_LOG_INFO, "revision2 (element 0xA0) set to 0x%08x\n", revision2); 00144 break; 00145 case 0xFF: 00146 av_log (s, AV_LOG_INFO, "end of header block reached (within audio subheader)\n"); 00147 inSubheader = 0; 00148 inHeader = 0; 00149 break; 00150 default: 00151 av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); 00152 break; 00153 } 00154 } 00155 break; 00156 case 0xFF: 00157 av_log (s, AV_LOG_INFO, "end of header block reached\n"); 00158 inHeader = 0; 00159 break; 00160 default: 00161 av_log (s, AV_LOG_INFO, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb)); 00162 break; 00163 } 00164 } 00165 00166 switch (compression_type) { 00167 case 0: ea->audio_codec = CODEC_ID_PCM_S16LE; break; 00168 case 7: ea->audio_codec = CODEC_ID_ADPCM_EA; break; 00169 case -1: 00170 switch (revision) { 00171 case 1: ea->audio_codec = CODEC_ID_ADPCM_EA_R1; break; 00172 case 2: ea->audio_codec = CODEC_ID_ADPCM_EA_R2; break; 00173 case 3: ea->audio_codec = CODEC_ID_ADPCM_EA_R3; break; 00174 case -1: break; 00175 default: 00176 av_log(s, AV_LOG_ERROR, "unsupported stream type; revision=%i\n", revision); 00177 return 0; 00178 } 00179 switch (revision2) { 00180 case 8: ea->audio_codec = CODEC_ID_PCM_S16LE_PLANAR; break; 00181 default: 00182 av_log(s, AV_LOG_ERROR, "unsupported stream type; revision2=%i\n", revision2); 00183 return 0; 00184 } 00185 break; 00186 default: 00187 av_log(s, AV_LOG_ERROR, "unsupported stream type; compression_type=%i\n", compression_type); 00188 return 0; 00189 } 00190 00191 if (ea->sample_rate == -1) 00192 ea->sample_rate = revision==3 ? 48000 : 22050; 00193 00194 return 1; 00195 }
| static int process_audio_header_sead | ( | AVFormatContext * | s | ) | [static] |
Definition at line 233 of file electronicarts.c.
References EaDemuxContext::audio_codec, EaDemuxContext::bytes, CODEC_ID_ADPCM_IMA_EA_SEAD, get_le32(), EaDemuxContext::num_channels, AVFormatContext::pb, AVFormatContext::priv_data, and EaDemuxContext::sample_rate.
Referenced by process_ea_header().
00234 { 00235 EaDemuxContext *ea = s->priv_data; 00236 ByteIOContext *pb = s->pb; 00237 00238 ea->sample_rate = get_le32(pb); 00239 ea->bytes = get_le32(pb); /* 1=8-bit, 2=16-bit */ 00240 ea->num_channels = get_le32(pb); 00241 ea->audio_codec = CODEC_ID_ADPCM_IMA_EA_SEAD; 00242 00243 return 1; 00244 }
| static int process_ea_header | ( | AVFormatContext * | s | ) | [static] |
Definition at line 263 of file electronicarts.c.
References EaDemuxContext::audio_codec, av_log(), AV_LOG_ERROR, EaDemuxContext::big_endian, bswap_32(), CODEC_ID_CMV, EACS_TAG, get_le32(), GSTR_TAG, ISNh_TAG, MVhd_TAG, MVIh_TAG, AVFormatContext::pb, AVFormatContext::priv_data, process_audio_header_eacs(), process_audio_header_elements(), process_audio_header_sead(), process_video_header_vp6(), PT00_TAG, SCHl_TAG, SEAD_TAG, size, EaDemuxContext::time_base, url_fseek(), url_fskip(), url_ftell(), and EaDemuxContext::video_codec.
Referenced by ea_read_header().
00263 { 00264 uint32_t blockid, size = 0; 00265 EaDemuxContext *ea = s->priv_data; 00266 ByteIOContext *pb = s->pb; 00267 int i; 00268 00269 for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) { 00270 unsigned int startpos = url_ftell(pb); 00271 int err = 0; 00272 00273 blockid = get_le32(pb); 00274 size = get_le32(pb); 00275 if (i == 0) 00276 ea->big_endian = size > 0x000FFFFF; 00277 if (ea->big_endian) 00278 size = bswap_32(size); 00279 00280 switch (blockid) { 00281 case ISNh_TAG: 00282 if (get_le32(pb) != EACS_TAG) { 00283 av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n"); 00284 return 0; 00285 } 00286 err = process_audio_header_eacs(s); 00287 break; 00288 00289 case SCHl_TAG : 00290 blockid = get_le32(pb); 00291 if (blockid == GSTR_TAG) { 00292 url_fskip(pb, 4); 00293 } else if (blockid != PT00_TAG) { 00294 av_log (s, AV_LOG_ERROR, "unknown SCHl headerid\n"); 00295 return 0; 00296 } 00297 err = process_audio_header_elements(s); 00298 break; 00299 00300 case SEAD_TAG: 00301 err = process_audio_header_sead(s); 00302 break; 00303 00304 case MVIh_TAG : 00305 ea->video_codec = CODEC_ID_CMV; 00306 ea->time_base = (AVRational){0,0}; 00307 break; 00308 00309 case MVhd_TAG : 00310 err = process_video_header_vp6(s); 00311 break; 00312 } 00313 00314 if (err < 0) { 00315 av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err); 00316 return err; 00317 } 00318 00319 url_fseek(pb, startpos + size, SEEK_SET); 00320 } 00321 00322 url_fseek(pb, 0, SEEK_SET); 00323 00324 return 1; 00325 }
| static int process_video_header_vp6 | ( | AVFormatContext * | s | ) | [static] |
Definition at line 246 of file electronicarts.c.
References CODEC_ID_VP6, AVRational::den, get_le32(), AVRational::num, AVFormatContext::pb, AVFormatContext::priv_data, EaDemuxContext::time_base, url_fskip(), and EaDemuxContext::video_codec.
Referenced by process_ea_header().
00247 { 00248 EaDemuxContext *ea = s->priv_data; 00249 ByteIOContext *pb = s->pb; 00250 00251 url_fskip(pb, 16); 00252 ea->time_base.den = get_le32(pb); 00253 ea->time_base.num = get_le32(pb); 00254 ea->video_codec = CODEC_ID_VP6; 00255 00256 return 1; 00257 }
| static uint32_t read_arbitary | ( | ByteIOContext * | pb | ) | [static] |
Definition at line 70 of file electronicarts.c.
References get_byte(), and size.
Referenced by process_audio_header_elements().
00070 { 00071 uint8_t size, byte; 00072 int i; 00073 uint32_t word; 00074 00075 size = get_byte(pb); 00076 00077 word = 0; 00078 for (i = 0; i < size; i++) { 00079 byte = get_byte(pb); 00080 word <<= 8; 00081 word |= byte; 00082 } 00083 00084 return word; 00085 }
Initial value:
{
"ea",
NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia Format"),
sizeof(EaDemuxContext),
ea_probe,
ea_read_header,
ea_read_packet,
}
Definition at line 481 of file electronicarts.c.
1.5.1