[FFmpeg-devel] [PATCH 4/6] Fix detecting ATRAC3 audio from MPS files

misty at brew.sh misty at brew.sh
Mon Dec 25 04:28:32 EET 2017


From: Misty De Meo <mistydemeo at gmail.com>

MPS files are MPEG files used on PSP Video discs. They lack
the PSMF header used by .pms files, and so the special casing
in the original patch fails to support their audio. This patch
fixes this by unconditionally reading a new byte for the startcode
for PRIVATE_STREAM_1 sections, and doing the comparison on that
to find ATRAC-3 streams. In my testing, it works fine for both MPS
and PSMF files.
---
 Changelog          |  1 +
 libavformat/mpeg.c | 38 ++++++++++++++------------------------
 libavformat/mpeg.h |  1 +
 3 files changed, 16 insertions(+), 24 deletions(-)

diff --git a/Changelog b/Changelog
index ee48876128..67f28ea839 100644
--- a/Changelog
+++ b/Changelog
@@ -27,6 +27,7 @@ version <next>:
 - video setrange filter
 - nsp demuxer
 - support LibreSSL (via libtls)
+- ATRAC-3 support for Sony PSP MPEG files
 
 
 version 3.4:
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 895c6fb231..a366ece0ed 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -128,7 +128,6 @@ typedef struct MpegDemuxContext {
     int sofdec;
     int dvd;
     int imkh_cctv;
-    int sony_psmf; // true if Play Station Movie file signature is present
 #if CONFIG_VOBSUB_DEMUXER
     AVFormatContext *sub_ctx;
     FFDemuxSubtitlesQueue q[32];
@@ -148,8 +147,6 @@ static int mpegps_read_header(AVFormatContext *s)
     avio_get_str(s->pb, 6, buffer, sizeof(buffer));
     if (!memcmp("IMKH", buffer, 4)) {
         m->imkh_cctv = 1;
-    } else if (!memcmp("PSMF00", buffer, 6)) {
-        m->sony_psmf = 1;
     } else if (!memcmp("Sofdec", buffer, 6)) {
         m->sofdec = 1;
     } else
@@ -444,7 +441,7 @@ redo:
         goto redo;
     }
 
-    if (startcode == PRIVATE_STREAM_1 && !m->sony_psmf) {
+    if (startcode == PRIVATE_STREAM_1) {
         startcode = avio_r8(s->pb);
         len--;
     }
@@ -544,28 +541,21 @@ redo:
         else
             request_probe= 1;
         type = AVMEDIA_TYPE_VIDEO;
-    } else if (startcode == PRIVATE_STREAM_1 && m->sony_psmf) {
-        uint8_t stream_id;
-
-        if (len < 2)
-            goto skip;
-        stream_id = avio_r8(s->pb);
+    // Sony PSP video with ATRAC-3 audio
+    } else if (!(startcode & STREAM_TYPE_AUDIO_ATRAC3)) {
         avio_r8(s->pb); // skip padding
-        len -= 2;
-        if (!(stream_id & 0xF0)) { // seems like we got an ATRAC stream
-            /* check if an appropriate stream already exists */
-            for (i = 0; i < s->nb_streams; i++) {
-                st = s->streams[i];
-                if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
-                    st->codec->codec_id == AV_CODEC_ID_ATRAC3P &&
-                    st->id - 0x1BD0 == (stream_id & 0xF))
-                    goto found;
-            }
-
-            startcode = 0x1BD0 + (stream_id & 0xF);
-            type      = AVMEDIA_TYPE_AUDIO;
-            codec_id  = AV_CODEC_ID_ATRAC3P;
+        len--;
+        for (i = 0; i < s->nb_streams; i++) {
+            st = s->streams[i];
+            if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+                st->codec->codec_id == AV_CODEC_ID_ATRAC3P &&
+                st->id - 0x1BD0 == (startcode & 0xF))
+                goto found;
         }
+
+        startcode = 0x1BD0 + (startcode & 0xF);
+        type      = AVMEDIA_TYPE_AUDIO;
+        codec_id  = AV_CODEC_ID_ATRAC3P;
     } else if (startcode == PRIVATE_STREAM_2) {
         type = AVMEDIA_TYPE_DATA;
         codec_id = AV_CODEC_ID_DVD_NAV;
diff --git a/libavformat/mpeg.h b/libavformat/mpeg.h
index 617e36cba8..efbadec8ba 100644
--- a/libavformat/mpeg.h
+++ b/libavformat/mpeg.h
@@ -58,6 +58,7 @@
 #define STREAM_TYPE_VIDEO_CAVS      0x42
 
 #define STREAM_TYPE_AUDIO_AC3       0x81
+#define STREAM_TYPE_AUDIO_ATRAC3    0xF0
 
 static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 };
 
-- 
2.15.1



More information about the ffmpeg-devel mailing list