diff mbox

[FFmpeg-devel,4/5] Fix detecting ATRAC3 audio from MPS files

Message ID 20171222143512.92271-5-misty@brew.sh
State Superseded
Headers show

Commit Message

misty@brew.sh Dec. 22, 2017, 2:35 p.m. UTC
From: Misty De Meo <mistydemeo@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(-)

Comments

Moritz Barsnick Dec. 23, 2017, 1:11 p.m. UTC | #1
On Fri, Dec 22, 2017 at 22:35:11 +0800, misty@brew.sh wrote:
> 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.

I think this might be worth a small fate test, assuming small samples
can be found and shared.

Moritz
misty@brew.sh Dec. 24, 2017, 8:48 a.m. UTC | #2
From: Misty De Meo <mistydemeo@gmail.com>

> I think this might be worth a small fate test, assuming small samples
> can be found and shared.

Good idea. I've added a fate test, using one PSMF sample and one
MPS sample. Here are URLs to the files:

https://public.drac.at/00006.MPS
http://samples.ffmpeg.org/PSMF/EV01_01_0500D.PMF

Misty De Meo (1):
  psmf: add FATE tests

 tests/Makefile      |  1 +
 tests/fate/psmf.mak | 23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+)
 create mode 100644 tests/fate/psmf.mak
diff mbox

Patch

diff --git a/Changelog b/Changelog
index 31e720091c..65c437c247 100644
--- a/Changelog
+++ b/Changelog
@@ -28,6 +28,7 @@  version <next>:
 - nsp demuxer
 - support LibreSSL (via libtls)
 - Move some OMA constants from libavformat into libavcodec
+- 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 };