diff mbox

[FFmpeg-devel,3/3] sbc: add raw muxer and demuxer for SBC

Message ID 20171105233520.15856-4-aurel@gnuage.org
State New
Headers show

Commit Message

Aurelien Jacobs Nov. 5, 2017, 11:35 p.m. UTC
---
 doc/general.texi         |  1 +
 libavformat/Makefile     |  4 +++
 libavformat/allformats.c |  2 ++
 libavformat/rawenc.c     | 28 ++++++++++++++++++
 libavformat/sbcdec.c     | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
 libavformat/utils.c      |  1 +
 6 files changed, 112 insertions(+)
 create mode 100644 libavformat/sbcdec.c

Comments

Carl Eugen Hoyos Nov. 5, 2017, 11:48 p.m. UTC | #1
2017-11-06 0:35 GMT+01:00 Aurelien Jacobs <aurel@gnuage.org>:

> +static int sbc_probe(AVProbeData *p)
> +{
> +    int score = 0;

> +    int l = strlen(p->filename);
> +    if (l > 4 && !strcmp(&p->filename[l-4], ".sbc"))
> +        score = AVPROBE_SCORE_EXTENSION;

This may make sense but we don't do it for any
other demuxer and if we want it it should imo be
done for all demuxers.

> +    if (p->buf[0] == SBC_SYNCWORD)
> +        score++;

Am I correct that the syncword is repeated
throughout the file? If yes, the probing can
be significantly improved (and would not
depend on the suffix).
Additionally, it is a little better not to return
a positive score - not even 1 - for eight bits
conformance.

Thank you!

Carl Eugen
Aurelien Jacobs Nov. 6, 2017, 12:31 a.m. UTC | #2
On Mon, Nov 06, 2017 at 12:48:32AM +0100, Carl Eugen Hoyos wrote:
> 2017-11-06 0:35 GMT+01:00 Aurelien Jacobs <aurel@gnuage.org>:
> 
> > +static int sbc_probe(AVProbeData *p)
> > +{
> > +    int score = 0;
> 
> > +    int l = strlen(p->filename);
> > +    if (l > 4 && !strcmp(&p->filename[l-4], ".sbc"))
> > +        score = AVPROBE_SCORE_EXTENSION;
> 
> This may make sense but we don't do it for any
> other demuxer and if we want it it should imo be
> done for all demuxers.
> 
> > +    if (p->buf[0] == SBC_SYNCWORD)
> > +        score++;
> 
> Am I correct that the syncword is repeated
> throughout the file? If yes, the probing can
> be significantly improved (and would not
> depend on the suffix).

Indeed it is repeated, and indeed the probing could
be improved by looking at several syncwords.
The problem is that they are not repeated at fixed
intervals, and that the offset to the next one is
not simply encoded in the stream.
So basically, the same process as the parser should
be used to find where is the next syncword. This
seems a bit to much for my taste for a simple probing
function.

> Additionally, it is a little better not to return
> a positive score - not even 1 - for eight bits
> conformance.

Well, the best might be to just remove this probing
function. SBC is not usually stored in files AFAIK
(it is streamed over bluetooth), so this demuxer is
mostly for testing purpose.
Relying on extension autodetection should be good
enough for testing.
Does this sound OK ?

Thanks for the review.
--
Aurel
Carl Eugen Hoyos Nov. 6, 2017, 12:41 a.m. UTC | #3
2017-11-06 1:31 GMT+01:00 Aurelien Jacobs <aurel@gnuage.org>:

> Well, the best might be to just remove this probing
> function.

+1

Merci, Carl Eugen
diff mbox

Patch

diff --git a/doc/general.texi b/doc/general.texi
index baaa308dcf..74f72be69a 100644
--- a/doc/general.texi
+++ b/doc/general.texi
@@ -462,6 +462,7 @@  library:
 @item raw NULL                  @tab X @tab
 @item raw video                 @tab X @tab X
 @item raw id RoQ                @tab X @tab
+@item raw SBC                   @tab X @tab X
 @item raw Shorten               @tab   @tab X
 @item raw TAK                   @tab   @tab X
 @item raw TrueHD                @tab X @tab X
diff --git a/libavformat/Makefile b/libavformat/Makefile
index caebe5b146..0dff981c01 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -442,6 +442,10 @@  OBJS-$(CONFIG_S337M_DEMUXER)             += s337m.o spdif.o
 OBJS-$(CONFIG_SAMI_DEMUXER)              += samidec.o subtitles.o
 OBJS-$(CONFIG_SAP_DEMUXER)               += sapdec.o
 OBJS-$(CONFIG_SAP_MUXER)                 += sapenc.o
+OBJS-$(CONFIG_SBC_DEMUXER)               += sbcdec.o rawdec.o
+OBJS-$(CONFIG_SBC_MUXER)                 += rawenc.o
+OBJS-$(CONFIG_MSBC_DEMUXER)              += sbcdec.o rawdec.o
+OBJS-$(CONFIG_MSBC_MUXER)                += rawenc.o
 OBJS-$(CONFIG_SBG_DEMUXER)               += sbgdec.o
 OBJS-$(CONFIG_SCC_DEMUXER)               += sccdec.o subtitles.o
 OBJS-$(CONFIG_SCC_MUXER)                 += sccenc.o subtitles.o
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index 405ddb5ad9..a7109d5abb 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -208,6 +208,7 @@  static void register_all(void)
     REGISTER_MUXDEMUX(MPJPEG,           mpjpeg);
     REGISTER_DEMUXER (MPL2,             mpl2);
     REGISTER_DEMUXER (MPSUB,            mpsub);
+    REGISTER_MUXDEMUX(MSBC,             msbc);
     REGISTER_DEMUXER (MSF,              msf);
     REGISTER_DEMUXER (MSNWC_TCP,        msnwc_tcp);
     REGISTER_DEMUXER (MTAF,             mtaf);
@@ -273,6 +274,7 @@  static void register_all(void)
     REGISTER_DEMUXER (S337M,            s337m);
     REGISTER_DEMUXER (SAMI,             sami);
     REGISTER_MUXDEMUX(SAP,              sap);
+    REGISTER_MUXDEMUX(SBC,              sbc);
     REGISTER_DEMUXER (SBG,              sbg);
     REGISTER_MUXDEMUX(SCC,              scc);
     REGISTER_DEMUXER (SDP,              sdp);
diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c
index f640121cb4..ac0119489c 100644
--- a/libavformat/rawenc.c
+++ b/libavformat/rawenc.c
@@ -413,6 +413,34 @@  AVOutputFormat ff_rawvideo_muxer = {
 };
 #endif
 
+#if CONFIG_SBC_MUXER
+AVOutputFormat ff_sbc_muxer = {
+    .name              = "sbc",
+    .long_name         = NULL_IF_CONFIG_SMALL("raw SBC"),
+    .mime_type         = "audio/x-sbc",
+    .extensions        = "sbc",
+    .audio_codec       = AV_CODEC_ID_SBC,
+    .video_codec       = AV_CODEC_ID_NONE,
+    .write_header      = force_one_stream,
+    .write_packet      = ff_raw_write_packet,
+    .flags             = AVFMT_NOTIMESTAMPS,
+};
+#endif
+
+#if CONFIG_MSBC_MUXER
+AVOutputFormat ff_msbc_muxer = {
+    .name              = "msbc",
+    .long_name         = NULL_IF_CONFIG_SMALL("raw mSBC"),
+    .mime_type         = "audio/x-msbc",
+    .extensions        = "msbc",
+    .audio_codec       = AV_CODEC_ID_MSBC,
+    .video_codec       = AV_CODEC_ID_NONE,
+    .write_header      = force_one_stream,
+    .write_packet      = ff_raw_write_packet,
+    .flags             = AVFMT_NOTIMESTAMPS,
+};
+#endif
+
 #if CONFIG_TRUEHD_MUXER
 AVOutputFormat ff_truehd_muxer = {
     .name              = "truehd",
diff --git a/libavformat/sbcdec.c b/libavformat/sbcdec.c
new file mode 100644
index 0000000000..1eb99bae03
--- /dev/null
+++ b/libavformat/sbcdec.c
@@ -0,0 +1,76 @@ 
+/*
+ * RAW SBC demuxer
+ * Copyright (C) 2017  Aurelien Jacobs <aurel@gnuage.org>
+ *
+ * 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 "avformat.h"
+#include "rawdec.h"
+
+#define SBC_SYNCWORD   0x9C
+#define MSBC_SYNCWORD  0xAD
+
+#if CONFIG_SBC_DEMUXER
+static int sbc_probe(AVProbeData *p)
+{
+    int score = 0;
+    int l = strlen(p->filename);
+    if (l > 4 && !strcmp(&p->filename[l-4], ".sbc"))
+        score = AVPROBE_SCORE_EXTENSION;
+    if (p->buf[0] == SBC_SYNCWORD)
+        score++;
+    return score;
+}
+
+AVInputFormat ff_sbc_demuxer = {
+    .name           = "sbc",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw SBC (low-complexity subband codec)"),
+    .extensions     = "sbc",
+    .raw_codec_id   = AV_CODEC_ID_SBC,
+    .read_probe     = sbc_probe,
+    .read_header    = ff_raw_audio_read_header,
+    .read_packet    = ff_raw_read_partial_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+};
+#endif
+
+#if CONFIG_MSBC_DEMUXER
+static int msbc_probe(AVProbeData *p)
+{
+    int score = 0;
+    int l = strlen(p->filename);
+    if (l > 5 && !strcmp(&p->filename[l-5], ".msbc"))
+        score = AVPROBE_SCORE_EXTENSION;
+    else if (l > 4 && !strcmp(&p->filename[l-4], ".sbc"))
+        score = AVPROBE_SCORE_EXTENSION;
+    if (p->buf[0] == MSBC_SYNCWORD)
+        score++;
+    return score;
+}
+
+AVInputFormat ff_msbc_demuxer = {
+    .name           = "msbc",
+    .long_name      = NULL_IF_CONFIG_SMALL("raw mSBC (wideband speech mono SBC)"),
+    .extensions     = "msbc",
+    .raw_codec_id   = AV_CODEC_ID_MSBC,
+    .read_probe     = msbc_probe,
+    .read_header    = ff_raw_audio_read_header,
+    .read_packet    = ff_raw_read_partial_packet,
+    .flags          = AVFMT_GENERIC_INDEX,
+};
+#endif
diff --git a/libavformat/utils.c b/libavformat/utils.c
index cbfb78bf4d..dedabee642 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -335,6 +335,7 @@  static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st,
         { "mjpeg_2000",AV_CODEC_ID_JPEG2000,   AVMEDIA_TYPE_VIDEO },
         { "mp3",       AV_CODEC_ID_MP3,        AVMEDIA_TYPE_AUDIO },
         { "mpegvideo", AV_CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
+        { "sbc",       AV_CODEC_ID_SBC,        AVMEDIA_TYPE_AUDIO },
         { "truehd",    AV_CODEC_ID_TRUEHD,     AVMEDIA_TYPE_AUDIO },
         { 0 }
     };