Message ID | 20171231094607.68768-5-misty@brew.sh |
---|---|
State | Superseded |
Headers | show |
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 ? [...]
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 --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 };
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(-)