[FFmpeg-devel] lavf/amr: Add amrnb and amrwb demuxers

Submitted by Carl Eugen Hoyos on Oct. 8, 2017, 10:24 p.m.

Details

Message ID CAB0OVGoqdVoJMLg0wGZwgt1fYpAcGrXmjLFrBUukuBFRpBMZDQ@mail.gmail.com
State Accepted
Headers show

Commit Message

Carl Eugen Hoyos Oct. 8, 2017, 10:24 p.m.
2017-10-07 16:51 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
> 2017-10-01 18:23 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>> 2017-09-27 18:08 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>
>>> The existing amr demuxer does not allow reading streams,
>>> it requires the 3GPP-conforming file header.
>>> Attached patch allows reading amrnb and amrwb from (live)
>>> streams, fixes ticket #6678.
>>
>> New patch with auto-detection attached, passes probecheck.
>
> Simplified patch attached that does not duplicate two small arrays
> in the object file that are already duplicated in the source code.
> The uninitialized variable is also fixed.

The last version triggered for repeated bytes (like adp),
new version attached.

Please comment, Carl Eugen

Comments

Carl Eugen Hoyos Nov. 5, 2017, 7:53 p.m.
2017-10-09 0:24 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
> 2017-10-07 16:51 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>> 2017-10-01 18:23 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>> 2017-09-27 18:08 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>>
>>>> The existing amr demuxer does not allow reading streams,
>>>> it requires the 3GPP-conforming file header.
>>>> Attached patch allows reading amrnb and amrwb from (live)
>>>> streams, fixes ticket #6678.
>>>
>>> New patch with auto-detection attached, passes probecheck.
>>
>> Simplified patch attached that does not duplicate two small arrays
>> in the object file that are already duplicated in the source code.
>> The uninitialized variable is also fixed.
>
> The last version triggered for repeated bytes (like adp),
> new version attached.

Patch applied.

Carl Eugen
Paul B Mahol Nov. 6, 2017, 10:50 a.m.
On 11/5/17, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
> 2017-10-09 0:24 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>> 2017-10-07 16:51 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>> 2017-10-01 18:23 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>>> 2017-09-27 18:08 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>>>
>>>>> The existing amr demuxer does not allow reading streams,
>>>>> it requires the 3GPP-conforming file header.
>>>>> Attached patch allows reading amrnb and amrwb from (live)
>>>>> streams, fixes ticket #6678.
>>>>
>>>> New patch with auto-detection attached, passes probecheck.
>>>
>>> Simplified patch attached that does not duplicate two small arrays
>>> in the object file that are already duplicated in the source code.
>>> The uninitialized variable is also fixed.
>>
>> The last version triggered for repeated bytes (like adp),
>> new version attached.
>
> Patch applied.

Please remove codec_tag line you set in those demuxers.
Codec tag makes sense to set only and only if container have such tag.
Raw containers nowhere stores tags so no reason to set it to .mov values
either.
Carl Eugen Hoyos Nov. 6, 2017, 12:46 p.m.
2017-11-06 11:50 GMT+01:00 Paul B Mahol <onemda@gmail.com>:
> On 11/5/17, Carl Eugen Hoyos <ceffmpeg@gmail.com> wrote:
>> 2017-10-09 0:24 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>> 2017-10-07 16:51 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>>> 2017-10-01 18:23 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>>>> 2017-09-27 18:08 GMT+02:00 Carl Eugen Hoyos <ceffmpeg@gmail.com>:
>>>>>
>>>>>> The existing amr demuxer does not allow reading streams,
>>>>>> it requires the 3GPP-conforming file header.
>>>>>> Attached patch allows reading amrnb and amrwb from (live)
>>>>>> streams, fixes ticket #6678.
>>>>>
>>>>> New patch with auto-detection attached, passes probecheck.
>>>>
>>>> Simplified patch attached that does not duplicate two small arrays
>>>> in the object file that are already duplicated in the source code.
>>>> The uninitialized variable is also fixed.
>>>
>>> The last version triggered for repeated bytes (like adp),
>>> new version attached.
>>
>> Patch applied.
>
> Please remove codec_tag line you set in those demuxers.

Done.

Carl Eugen

Patch hide | download patch | download mbox

From f3697957b54bef4a7718144df07877394bd5d941 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <ceffmpeg@gmail.com>
Date: Mon, 9 Oct 2017 00:21:23 +0200
Subject: [PATCH] lavf/amr: Add amrnb and amrwb demuxers.

Fixes ticket #6678.
---
 Changelog                |    1 +
 libavformat/Makefile     |    2 +
 libavformat/allformats.c |    2 +
 libavformat/amr.c        |  134 ++++++++++++++++++++++++++++++++++++++++++----
 libavformat/version.h    |    4 +-
 5 files changed, 131 insertions(+), 12 deletions(-)

diff --git a/Changelog b/Changelog
index d6ec4ad..94e33a2 100644
--- a/Changelog
+++ b/Changelog
@@ -53,6 +53,7 @@  version <next>:
 - Rockchip MPP hardware decoding
 - vmafmotion video filter
 - use MIME type "G726" for little-endian G.726, "AAL2-G726" for big-endian G.726
+- auto-detect amr-nb and amr-wb streams
 
 
 version 3.3:
diff --git a/libavformat/Makefile b/libavformat/Makefile
index df709c29..c4c8713 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -87,6 +87,8 @@  OBJS-$(CONFIG_AIFF_MUXER)                += aiffenc.o id3v2enc.o
 OBJS-$(CONFIG_AIX_DEMUXER)               += aixdec.o
 OBJS-$(CONFIG_AMR_DEMUXER)               += amr.o
 OBJS-$(CONFIG_AMR_MUXER)                 += amr.o
+OBJS-$(CONFIG_AMRNB_DEMUXER)             += amr.o
+OBJS-$(CONFIG_AMRWB_DEMUXER)             += amr.o
 OBJS-$(CONFIG_ANM_DEMUXER)               += anm.o
 OBJS-$(CONFIG_APC_DEMUXER)               += apc.o
 OBJS-$(CONFIG_APE_DEMUXER)               += ape.o apetag.o img2.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 405ddb5..dc8984e 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -63,6 +63,8 @@  static void register_all(void)
     REGISTER_MUXDEMUX(AIFF,             aiff);
     REGISTER_DEMUXER (AIX,              aix);
     REGISTER_MUXDEMUX(AMR,              amr);
+    REGISTER_DEMUXER (AMRNB,            amrnb);
+    REGISTER_DEMUXER (AMRWB,            amrwb);
     REGISTER_DEMUXER (ANM,              anm);
     REGISTER_DEMUXER (APC,              apc);
     REGISTER_DEMUXER (APE,              ape);
diff --git a/libavformat/amr.c b/libavformat/amr.c
index b5194a2..0043faf 100644
--- a/libavformat/amr.c
+++ b/libavformat/amr.c
@@ -38,6 +38,14 @@  typedef struct {
 static const char AMR_header[]   = "#!AMR\n";
 static const char AMRWB_header[] = "#!AMR-WB\n";
 
+static const uint8_t amrnb_packed_size[16] = {
+    13, 14, 16, 18, 20, 21, 27, 32, 6, 1, 1, 1, 1, 1, 1, 1
+};
+static const uint8_t amrwb_packed_size[16] = {
+    18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 1, 1, 1, 1, 1, 1
+};
+
+
 #if CONFIG_AMR_MUXER
 static int amr_write_header(AVFormatContext *s)
 {
@@ -126,17 +134,9 @@  static int amr_read_packet(AVFormatContext *s, AVPacket *pkt)
     mode = (toc >> 3) & 0x0F;
 
     if (par->codec_id == AV_CODEC_ID_AMR_NB) {
-        static const uint8_t packed_size[16] = {
-            12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0
-        };
-
-        size = packed_size[mode] + 1;
+        size = amrnb_packed_size[mode];
     } else if (par->codec_id == AV_CODEC_ID_AMR_WB) {
-        static const uint8_t packed_size[16] = {
-            18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1
-        };
-
-        size = packed_size[mode];
+        size = amrwb_packed_size[mode];
     }
 
     if (!size || av_new_packet(pkt, size))
@@ -176,6 +176,120 @@  AVInputFormat ff_amr_demuxer = {
 };
 #endif
 
+#if CONFIG_AMRNB_DEMUXER
+static int amrnb_probe(AVProbeData *p)
+{
+    int mode, i = 0, valid = 0;
+    const uint8_t *b = p->buf;
+
+    while (i < p->buf_size) {
+        mode = b[i] >> 3 & 0x0F;
+        if (mode < 9 && (b[i] & 0x4) == 0x4) {
+            uint8_t last = mode;
+            int size = amrnb_packed_size[mode];
+            while (size--) {
+                if (b[++i] != last)
+                    break;
+                last = b[i];
+            }
+            if (size > 0) {
+                valid++;
+                i += size;
+            }
+        } else {
+            valid = 0;
+            i++;
+        }
+    }
+    if (valid > 100)
+        return AVPROBE_SCORE_EXTENSION / 2 + 1;
+    return 0;
+}
+
+static int amrnb_read_header(AVFormatContext *s)
+{
+    AVStream *st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codecpar->codec_tag      = MKTAG('s', 'a', 'm', 'r');
+    st->codecpar->codec_id       = AV_CODEC_ID_AMR_NB;
+    st->codecpar->sample_rate    = 8000;
+    st->codecpar->channels       = 1;
+    st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
+    st->codecpar->codec_type     = AVMEDIA_TYPE_AUDIO;
+    avpriv_set_pts_info(st, 64, 1, 8000);
+
+    return 0;
+}
+
+AVInputFormat ff_amrnb_demuxer = {
+    .name           = "amrnb",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw AMR-NB"),
+    .priv_data_size = sizeof(AMRContext),
+    .read_probe     = amrnb_probe,
+    .read_header    = amrnb_read_header,
+    .read_packet    = amr_read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+};
+#endif
+
+#if CONFIG_AMRWB_DEMUXER
+static int amrwb_probe(AVProbeData *p)
+{
+    int mode, i = 0, valid = 0;
+    const uint8_t *b = p->buf;
+
+    while (i < p->buf_size) {
+        mode = b[i] >> 3 & 0x0F;
+        if (mode < 10 && (b[i] & 0x4) == 0x4) {
+            uint8_t last = mode;
+            int size = amrwb_packed_size[mode];
+            while (size--) {
+                if (b[++i] != last)
+                    break;
+                last = b[i];
+            }
+            if (size > 0) {
+                valid++;
+                i += size;
+            }
+        } else {
+            valid = 0;
+            i++;
+        }
+    }
+    if (valid > 100)
+        return AVPROBE_SCORE_EXTENSION / 2 - 1;
+    return 0;
+}
+
+static int amrwb_read_header(AVFormatContext *s)
+{
+    AVStream *st = avformat_new_stream(s, NULL);
+    if (!st)
+        return AVERROR(ENOMEM);
+    st->codecpar->codec_tag      = MKTAG('s', 'a', 'w', 'b');
+    st->codecpar->codec_id       = AV_CODEC_ID_AMR_WB;
+    st->codecpar->sample_rate    = 16000;
+    st->codecpar->channels       = 1;
+    st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
+    st->codecpar->codec_type     = AVMEDIA_TYPE_AUDIO;
+    avpriv_set_pts_info(st, 64, 1, 16000);
+
+    return 0;
+}
+
+AVInputFormat ff_amrwb_demuxer = {
+    .name           = "amrwb",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw AMR-WB"),
+    .priv_data_size = sizeof(AMRContext),
+    .read_probe     = amrwb_probe,
+    .read_header    = amrwb_read_header,
+    .read_packet    = amr_read_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+};
+#endif
+
 #if CONFIG_AMR_MUXER
 AVOutputFormat ff_amr_muxer = {
     .name              = "amr",
diff --git a/libavformat/version.h b/libavformat/version.h
index caf85e8..878917d 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,8 +32,8 @@ 
 // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
 // Also please add any ticket numbers that you believe might be affected here
 #define LIBAVFORMAT_VERSION_MAJOR  57
-#define LIBAVFORMAT_VERSION_MINOR  82
-#define LIBAVFORMAT_VERSION_MICRO 104
+#define LIBAVFORMAT_VERSION_MINOR  83
+#define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \
-- 
1.7.10.4