>From b3013e56b0251d7e1a04191dfaa60ded3431bb23 Mon Sep 17 00:00:00 2001
From: Maxim Poliakovski <maximumspat...@googlemail.com>
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       = sample_rate * frame_size * 8 / 2048;
+                st->codec->channels       = ff_oma_chid_to_num_channels[channel_id - 1];
+                st->codec->channel_layout = ff_oma_chid_to_native_layout[channel_id - 1];
+                goto found;
+            }
+            goto skip;
+        }
     } else if (startcode == PRIVATE_STREAM_2) {
         type = AVMEDIA_TYPE_DATA;
         codec_id = AV_CODEC_ID_DVD_NAV;
-- 
1.9.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to