aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2015-10-21 22:59:08 +0200
committerPaul B Mahol <onemda@gmail.com>2015-10-22 11:01:00 +0200
commit0d7c0274833546bbbd243a109f266294d929ab38 (patch)
treecf8a7a8932cd4b99cdc7d1bdd3f057d0bbd91a95
parent7ebe12fc55591053cbd194ca6638e5c32beaee45 (diff)
downloadffmpeg-0d7c0274833546bbbd243a109f266294d929ab38.tar.gz
avformat/electronicarts: support ADPCM PSX
Signed-off-by: Paul B Mahol <onemda@gmail.com>
-rw-r--r--libavformat/electronicarts.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index 5d21d49c45..22a7bc501d 100644
--- a/libavformat/electronicarts.c
+++ b/libavformat/electronicarts.c
@@ -86,6 +86,8 @@ typedef struct EaDemuxContext {
int sample_rate;
int num_channels;
int num_samples;
+
+ int platform;
} EaDemuxContext;
static uint32_t read_arbitrary(AVIOContext *pb)
@@ -255,6 +257,8 @@ static int process_audio_header_elements(AVFormatContext *s)
return 0;
}
+ if (ea->audio_codec == AV_CODEC_ID_NONE && ea->platform == 0x01)
+ ea->audio_codec = AV_CODEC_ID_ADPCM_PSX;
if (ea->sample_rate == -1)
ea->sample_rate = revision == 3 ? 48000 : 22050;
@@ -387,10 +391,10 @@ static int process_ea_header(AVFormatContext *s)
blockid = avio_rl32(pb);
if (blockid == GSTR_TAG) {
avio_skip(pb, 4);
- } else if ((blockid & 0xFFFF) != PT00_TAG) {
- avpriv_request_sample(s, "unknown SCHl headerid");
- return 0;
+ } else if ((blockid & 0xFF) != (PT00_TAG & 0xFF)) {
+ blockid = avio_rl32(pb);
}
+ ea->platform = (blockid >> 16) & 0xFF;
err = process_audio_header_elements(s);
break;
@@ -600,6 +604,9 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
num_samples = avio_rl32(pb);
avio_skip(pb, 8);
chunk_size -= 12;
+ } else if (ea->audio_codec == AV_CODEC_ID_ADPCM_PSX) {
+ avio_skip(pb, 8);
+ chunk_size -= 8;
}
if (partial_packet) {
@@ -639,6 +646,9 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
case AV_CODEC_ID_MP3:
pkt->duration = num_samples;
break;
+ case AV_CODEC_ID_ADPCM_PSX:
+ pkt->duration = chunk_size / (16 * ea->num_channels) * 28;
+ break;
default:
pkt->duration = chunk_size / (ea->bytes * ea->num_channels);
}