diff mbox

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

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

Commit Message

misty@brew.sh Dec. 31, 2017, 9:46 a.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

Michael Niedermayer Jan. 2, 2018, 9:31 p.m. UTC | #1
On Sun, Dec 31, 2017 at 05:46:05PM +0800, misty@brew.sh wrote:
> 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(-)
> 
> 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)) {

this looks a bit odd
shouldnt this test more than 4 bits of startcode ?

[...]
misty@brew.sh Jan. 5, 2018, 11:34 a.m. UTC | #2
From: Misty De Meo <mistydemeo@gmail.com>

> this looks a bit odd
> shouldnt this test more than 4 bits of startcode ?

Yeah, that was a misreading on my part of the original patch. I need
a different approach.

I think I've found something that should work, though. I was talking to
Jan about this in IRC, and vgmtoolbox came up. It detects ATRAC audio
in MPEG files by checking for magic bytes in the PES private data:
https://sourceforge.net/p/vgmtoolbox/code/HEAD/tree/format/VGMToolbox/format/SonyPmfStream.cs#l19
I've updated the patch to set the sony_psmf flag if those bytes are
detected, and interpret all streams under 0x20 as ATRAC when that flag
is set. That's worked for all of the samples we have, both PSM and MPS,
and also works for a newer PS3 sample that Jan had. The fate MPEG tests
still pass, so I'm hopeful this doesn't introduce any false positives.

I've included an updated version of the full patchset.

Maxim Poliakovski (1):
  mpeg: add experimental support for PSMF audio.

Misty De Meo (5):
  fate: add atrac3p conversion test
  oma: move some constants into libavcodec
  Fix detecting ATRAC3 audio from MPS files
  mpeg: fix use of deprecated struct
  psmf: add FATE tests

 Changelog                             |   1 +
 libavcodec/Makefile                   |   1 +
 libavcodec/allcodecs.c                |   1 +
 libavcodec/atrac3plus_parser.c        | 170 ++++++++++++++++++++++++++++++++++
 libavformat/oma.c => libavcodec/oma.h |  27 +++---
 libavcodec/version.h                  |   2 +-
 libavformat/Makefile                  |   4 +-
 libavformat/mpeg.c                    |  29 ++++++
 libavformat/mpeg.h                    |   1 +
 libavformat/oma.h                     |  21 ++---
 libavformat/omadec.c                  |  13 +--
 libavformat/omaenc.c                  |   7 +-
 libavformat/version.h                 |   2 +-
 tests/Makefile                        |   1 +
 tests/fate/atrac.mak                  |   4 +
 tests/fate/psmf.mak                   |  23 +++++
 16 files changed, 268 insertions(+), 39 deletions(-)
 create mode 100644 libavcodec/atrac3plus_parser.c
 rename libavformat/oma.c => libavcodec/oma.h (65%)
 create mode 100644 tests/fate/psmf.mak
diff mbox

Patch

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 };