[FFmpeg-devel] [PATCH] avformat/electronicarts: support ADPCM PSX

Paul B Mahol onemda at gmail.com
Wed Oct 21 23:14:02 CEST 2015


Signed-off-by: Paul B Mahol <onemda at gmail.com>
---
 libavformat/electronicarts.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c
index c0b6d6e..12eec80 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,10 @@ 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) {
+                num_samples = avio_rl32(pb);
+                avio_skip(pb, 4);
+                chunk_size -= 8;
             }
 
             if (partial_packet) {
@@ -639,6 +647,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);
             }
@@ -653,7 +664,7 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
         case SEND_TAG:
         case SEEN_TAG:
             while (!avio_feof(pb)) {
-                if (avio_rl32(pb)) {
+                if (avio_rl32(pb) == SCHl_TAG) {
                     avio_skip(pb, -4);
                     break;
                 }
-- 
1.9.1



More information about the ffmpeg-devel mailing list