Re: [FFmpeg-devel] [PATCH] PSMF audio support, trac ticket #3233

2014-12-02 Thread Maxim Polijakowski

+#include "libavformat/oma.h"

libavformat can use things from libavcodec but
libavcodec cannot use things from libavformat as it doesnt depend on
it, libavcodec can be used alone without libavformat
so some things may need to be moved to libavcodec in a seperate patch
before this

The four oma tables could be moved to the header, or their prefix changed to 
avpriv_.
They are small enough that the former is probably a better option, though.


Moving these tables to the header will probably cause multiply 
definition. They are currently declared in oma.h but their content is 
defined in oma.c...

I'll try to move them to atrac3plus.h/atrac3plus.c...

Best regards
Maxim
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] PSMF audio support, trac ticket #3233

2014-12-02 Thread Maxim Polijakowski



+avctx->sample_rate= ctx->sample_rate;
+avctx->block_align= ctx->frame_size;
+avctx->bit_rate   = ctx->sample_rate * ctx->frame_size * 8 / 2048;
+avctx->channels   = ff_oma_chid_to_num_channels[ctx->channel_id - 
1];
+avctx->channel_layout = ff_oma_chid_to_native_layout[ctx->channel_id - 
1];

if you set these from the parser instead of the decoder then you
must be a bit careful as the decoder can run in a seperate thread as
the parser so the parser cannot change anything midstream it could
only set the parameters once before the decoder can start
(that is when the parameters where not set before)


Ok, I see. The problem is that ATRAC3+ streams will be added dynamically 
in the demuxer. Stream parameters like frame_size or sample_rate seem to 
be sent along with packets. I don't know whether they are available in 
headers or not.


For the case I won't find any stream configuration before dealing with 
packets, what's the right way to supply stream parameters to the decoder?
The whole parser thingy seems to be poorly documented so I don't know 
where to proceed...


Best regards
Maxim
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] PSMF audio support, trac ticket #3233

2014-12-01 Thread Maxim Polijakowski

Hello crews,

attached patch enables PSMF audio demuxing/decoding. As suggested by 
Carl Eugen Hoyos, mpeg.c has been extended to identify ATRAC3+ streams 
inside of PSMF files. Additionally, a ATRAC3+ parser has been 
implemented in order to extract Atrac3+ frames from PRIVATE_STREAM_1 
packets.


It works well for these samples: http://samples.ffmpeg.org/PSMF

The code is not perfect and can be surely improved a lot. I hope though 
that my work goes in the right direction :))


Best regards
Maxim
>From 9fef4512d8e5e7e8cc93a8c108d67811931cc05c Mon Sep 17 00:00:00 2001
From: Maxim Poliakovski 
Date: Mon, 24 Nov 2014 01:20:21 +0100
Subject: [PATCH 2/2] mpeg: add experimental support for PSMF audio.

---
 libavcodec/Makefile|   1 +
 libavcodec/allcodecs.c |   1 +
 libavcodec/atrac3plus_parser.c | 153 +
 libavformat/mpeg.c |  27 +++-
 4 files changed, 181 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/atrac3plus_parser.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index fa0f53d..c9520d7 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -775,6 +775,7 @@ OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o
 OBJS-$(CONFIG_AC3_PARSER)  += ac3_parser.o ac3tab.o \
   aac_ac3_parser.o
 OBJS-$(CONFIG_ADX_PARSER)  += adx_parser.o adx.o
+OBJS-$(CONFIG_ATRAC3P_PARSER)  += atrac3plus_parser.o
 OBJS-$(CONFIG_BMP_PARSER)  += bmp_parser.o
 OBJS-$(CONFIG_CAVSVIDEO_PARSER)+= cavs_parser.o
 OBJS-$(CONFIG_COOK_PARSER) += cook_parser.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 0d39d33..a5a44af 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -544,6 +544,7 @@ void avcodec_register_all(void)
 REGISTER_PARSER(AAC_LATM,   aac_latm);
 REGISTER_PARSER(AC3,ac3);
 REGISTER_PARSER(ADX,adx);
+REGISTER_PARSER(ATRAC3P,atrac3p);
 REGISTER_PARSER(BMP,bmp);
 REGISTER_PARSER(CAVSVIDEO,  cavsvideo);
 REGISTER_PARSER(COOK,   cook);
diff --git a/libavcodec/atrac3plus_parser.c b/libavcodec/atrac3plus_parser.c
new file mode 100644
index 000..01fcad4
--- /dev/null
+++ b/libavcodec/atrac3plus_parser.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2014 Maxim Poliakovski
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "parser.h"
+#include "get_bits.h"
+#include "libavformat/oma.h"
+
+typedef struct Atrac3PlusParseContext {
+ParseContext pc;
+uint8_t hdr[8];
+int hdr_bytes_needed, got_bytes;
+int sample_rate, channel_id, frame_size;
+} Atrac3PlusParseContext;
+
+static int parse_sound_frame_header(Atrac3PlusParseContext *c,
+const uint8_t *buf)
+{
+uint16_t atrac_config;
+
+if (AV_RB16(buf) != 0x0FD0)
+return AVERROR_INVALIDDATA;
+
+atrac_config = AV_RB16(&buf[2]);
+c->sample_rate = ff_oma_srate_tab[(atrac_config >> 13) & 7] * 100;
+c->channel_id  = (atrac_config >> 10) & 7;
+c->frame_size  = ((atrac_config & 0x3FF) * 8) + 8;
+
+if (!c->channel_id || !c->sample_rate || !c->frame_size)
+return AVERROR_INVALIDDATA;
+
+return 0;
+}
+
+static int ff_atrac3p_parse(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size)
+{
+Atrac3PlusParseContext *ctx = s->priv_data;
+const uint8_t *hdr_buf = buf;
+size_t bytes_remain;
+int frame_size, hdr_bytes = 8;
+int next = 0;
+
+if (s->flags & PARSER_FLAG_COMPLETE_FRAMES || !buf_size) {
+next = buf_size;
+} else {
+if (buf_size >= 2) {
+bytes_remain = AV_RB16(buf);
+
+if (bytes_remain != 0xFD0) {
+next += 2;
+buf  += 2;
+buf_size -= 2;
+hdr_buf = buf;
+
+if (bytes_remain && !ctx->pc.index && !ctx->hdr_bytes_needed) {
+av_log(avctx, AV_LOG_ERROR,
+   "2nd frame portion found but the 1st one is missing!\n");
+

[FFmpeg-devel] [DISCUSSION] Atrac3+ streams inside PSMF

2014-11-25 Thread Maxim Polijakowski
It looks like my previous email has been scrubbed. Therefore, I resubmit 
it in another thread. Sorry for that!


--

Hello crews,
I would like to have a support for decoding/demuxing Atrac3+ streams 
from PSMF (Playstation movie format).
Although decoding/demuxing of video streams currently does currently 
work, audio streams stay still unaccesible. I'm ready to undertake this 
task but I need a liitle bit help (see below).

PSMF BACKGROUND:
PSMF container can be seen as an extension of MPEG-TS, see here: 
http://wiki.multimedia.cx/index.php?title=PSMF 

In the current FFMpeg, PSMF will be (mis)-identified as MPEG-TS stream. 
Atrac Audio is carried out in PRIVATE_STREAM_1 packets. Their format is 
proprietary but rather simple to understand.
Atrac3+ audio streams are delivered inside of packets of the same size, 
usually 2048 bytes. They usually contain several audio frames. Frames 
can be splitted across two packets and need to be stitched together in 
the demuxer.

Now my questions:
1) what's the proper code to be extended? I attached a very draft patch 
that extends the MPEG demuxer. Is it the right place or should I look 
for any other?
2) how to deal with multiply frames in a packet? Could you point me to a 
working example?
3) audio frames can be splitted into two parts and sent with two 
different packets in the case audio frame size is not an integral of 
2048 bytes. It means the demuxer should save the first part in a 
temporary location, wait for the 2nd part and then concatenate these two 
parts together. Is there any API or working examples doing that I could 
look into?
I did never implemented a demuxer of such a complexity so I would 
greatly appreciate any help.

Thank you in advance!
Best regards
Maxim
>From b3013e56b0251d7e1a04191dfaa60ded3431bb23 Mon Sep 17 00:00:00 2001
From: Maxim Poliakovski 
Date: Mon, 24 Nov 2014 01:20:21 +0100
Subject: [PATCH 2/2] mpeg: add experimental support for PSMF audio.

---
 libavformat/mpeg.c | 61 ++
 1 file changed, 57 insertions(+), 4 deletions(-)

diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 827a3c2..fbd5a25 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -22,6 +22,7 @@
 #include "avformat.h"
 #include "internal.h"
 #include "mpeg.h"
+#include "oma.h"
 
 #if CONFIG_VOBSUB_DEMUXER
 # include "subtitles.h"
@@ -434,10 +435,10 @@ redo:
 goto redo;
 }
 
-if (startcode == PRIVATE_STREAM_1) {
-startcode = avio_r8(s->pb);
-len--;
-}
+//if (startcode == PRIVATE_STREAM_1) {
+//startcode = avio_r8(s->pb);
+//len--;
+//}
 if (len < 0)
 goto error_redo;
 if (dts != AV_NOPTS_VALUE && ppos) {
@@ -534,6 +535,58 @@ redo:
 else
 request_probe= 1;
 type = AVMEDIA_TYPE_VIDEO;
+} else if (startcode == PRIVATE_STREAM_1) {
+if (len < 4)
+goto skip;
+uint8_t stream_id = avio_r8(s->pb);
+avio_r8(s->pb); // skip padding
+size_t bytes_remain = avio_rb16(s->pb);
+len -= 4;
+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;
+}
+
+if (len < (bytes_remain + 8))
+goto skip;
+
+if (bytes_remain)
+avio_skip(s->pb, bytes_remain);
+
+uint16_t hdr_id = avio_rb16(s->pb);
+uint16_t atrac_config = avio_rb16(s->pb);
+avio_skip(s->pb, 4); // skip padding bytes
+len -= 8;
+
+if (hdr_id == 0x0FD0) {
+int sample_rate = ff_oma_srate_tab[(atrac_config >> 13) & 7] * 100;
+int channel_id  = (atrac_config >> 10) & 7;
+int frame_size  = ((atrac_config & 0x3FF) * 8) + 8;
+
+if (!channel_id || !sample_rate || !frame_size) {
+av_log(s, AV_LOG_ERROR, "Invalid ATRAC packet!\n");
+return AVERROR_INVALIDDATA;
+}
+
+/* add a new ATRAC audio stream */
+st = avformat_new_stream(s, NULL);
+if (!st)
+goto skip;
+st->id= 0x1BD0 + (stream_id & 0xF);
+st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+st->codec->codec_id   = AV_CODEC_ID_ATRAC3P;
+st->codec->sample_rate= sample_rate;
+st->codec->block_align= frame_size;
+st->codec->bit_rate