summaryrefslogtreecommitdiff
path: root/libavformat/electronicarts.c
diff options
context:
space:
mode:
authorAurelien Jacobs <aurel@gnuage.org>2007-10-25 20:38:49 +0000
committerAurelien Jacobs <aurel@gnuage.org>2007-10-25 20:38:49 +0000
commit98168220b0e35886260808587e408c82fd8f77c4 (patch)
tree77913d5f7e67cd2e7a86ffe9a9583ba1305fad49 /libavformat/electronicarts.c
parent63bb42fb36aca782136ce4a23d29ca6320d31c88 (diff)
add parsing of 1SNh header in the EA demuxer
Originally committed as revision 10859 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/electronicarts.c')
-rw-r--r--libavformat/electronicarts.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index b17f2825d8..bfa7ea838e 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -27,6 +27,10 @@
#include "avformat.h"
#define SCHl_TAG MKTAG('S', 'C', 'H', 'l')
+#define _SNh_TAG MKTAG('1', 'S', 'N', 'h') /* 1SNx header */
+#define EACS_TAG MKTAG('E', 'A', 'C', 'S')
+#define _SNd_TAG MKTAG('1', 'S', 'N', 'd') /* 1SNx data */
+#define _SNe_TAG MKTAG('1', 'S', 'N', 'e') /* 1SNx end */
#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0)
#define GSTR_TAG MKTAG('G', 'S', 'T', 'R')
#define SCDl_TAG MKTAG('S', 'C', 'D', 'l')
@@ -170,6 +174,37 @@ static int process_audio_header_elements(AVFormatContext *s)
return 1;
}
+/*
+ * Process EACS sound header
+ * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx
+ */
+static int process_audio_header_eacs(AVFormatContext *s)
+{
+ EaDemuxContext *ea = s->priv_data;
+ ByteIOContext *pb = &s->pb;
+ int compression_type;
+
+ ea->sample_rate = ea->big_endian ? get_be32(pb) : get_le32(pb);
+ ea->bytes = get_byte(pb); /* 1=8-bit, 2=16-bit */
+ ea->num_channels = get_byte(pb);
+ compression_type = get_byte(pb);
+ url_fskip(pb, 13);
+
+ switch (compression_type) {
+ case 0:
+ switch (ea->bytes) {
+ case 1: ea->audio_codec = CODEC_ID_PCM_S8; break;
+ case 2: ea->audio_codec = CODEC_ID_PCM_S16LE; break;
+ }
+ break;
+ case 1: ea->audio_codec = CODEC_ID_PCM_MULAW; ea->bytes = 1; break;
+ default:
+ av_log (s, AV_LOG_ERROR, "unsupported stream type; audio compression_type=%i\n", compression_type);
+ }
+
+ return 1;
+}
+
static int process_video_header_vp6(AVFormatContext *s)
{
EaDemuxContext *ea = s->priv_data;
@@ -205,6 +240,14 @@ static int process_ea_header(AVFormatContext *s) {
size = bswap_32(size);
switch (blockid) {
+ case _SNh_TAG:
+ if (get_le32(pb) != EACS_TAG) {
+ av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n");
+ return 0;
+ }
+ err = process_audio_header_eacs(s);
+ break;
+
case SCHl_TAG :
blockid = get_le32(pb);
if (blockid == GSTR_TAG) {
@@ -304,6 +347,11 @@ static int ea_read_packet(AVFormatContext *s,
switch (chunk_type) {
/* audio data */
+ case _SNh_TAG:
+ /* header chunk also contains data; skip over the header portion*/
+ url_fskip(pb, 32);
+ chunk_size -= 32;
+ case _SNd_TAG:
case SCDl_TAG:
if (!ea->audio_codec) {
url_fskip(pb, chunk_size);
@@ -336,6 +384,7 @@ static int ea_read_packet(AVFormatContext *s,
/* ending tag */
case 0:
+ case _SNe_TAG:
case SCEl_TAG:
ret = AVERROR(EIO);
packet_read = 1;