[FFmpeg-devel] [PATCH 3/4] lavd/alsa: move channels reordering in a separate file.

Nicolas George nicolas.george at normalesup.org
Sat Feb 2 17:42:24 CET 2013


Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
---
 libavdevice/Makefile            |    3 +-
 libavdevice/alsa-audio-common.c |  106 ++------------------------------
 libavdevice/alsa-audio.h        |    3 +-
 libavdevice/alsa_reorder.c      |  126 +++++++++++++++++++++++++++++++++++++++
 libavdevice/alsa_reorder.h      |   44 ++++++++++++++
 5 files changed, 178 insertions(+), 104 deletions(-)
 create mode 100644 libavdevice/alsa_reorder.c
 create mode 100644 libavdevice/alsa_reorder.h

diff --git a/libavdevice/Makefile b/libavdevice/Makefile
index efffa8b..515742d 100644
--- a/libavdevice/Makefile
+++ b/libavdevice/Makefile
@@ -14,7 +14,8 @@ OBJS    = alldevices.o                                                  \
 OBJS-$(CONFIG_ALSA_INDEV)                += alsa-audio-common.o \
                                             alsa-audio-dec.o timefilter.o
 OBJS-$(CONFIG_ALSA_OUTDEV)               += alsa-audio-common.o \
-                                            alsa-audio-enc.o
+                                            alsa-audio-enc.o \
+                                            alsa_reorder.o
 OBJS-$(CONFIG_BKTR_INDEV)                += bktr.o
 OBJS-$(CONFIG_CACA_OUTDEV)               += caca.o
 OBJS-$(CONFIG_DSHOW_INDEV)               += dshow.o dshow_enummediatypes.o \
diff --git a/libavdevice/alsa-audio-common.c b/libavdevice/alsa-audio-common.c
index 47ef3c5..03b4c44 100644
--- a/libavdevice/alsa-audio-common.c
+++ b/libavdevice/alsa-audio-common.c
@@ -62,105 +62,6 @@ static av_cold snd_pcm_format_t codec_id_to_pcm_format(int codec_id)
     }
 }
 
-#define MAKE_REORDER_FUNC(NAME, TYPE, CHANNELS, LAYOUT, MAP)                \
-static void alsa_reorder_ ## NAME ## _ ## LAYOUT(const void *in_v,          \
-                                                 void *out_v,               \
-                                                 int n)                     \
-{                                                                           \
-    const TYPE *in = in_v;                                                  \
-    TYPE      *out = out_v;                                                 \
-                                                                            \
-    while (n-- > 0) {                                                       \
-        MAP                                                                 \
-        in  += CHANNELS;                                                    \
-        out += CHANNELS;                                                    \
-    }                                                                       \
-}
-
-#define MAKE_REORDER_FUNCS(CHANNELS, LAYOUT, MAP) \
-    MAKE_REORDER_FUNC(int8,  int8_t,  CHANNELS, LAYOUT, MAP) \
-    MAKE_REORDER_FUNC(int16, int16_t, CHANNELS, LAYOUT, MAP) \
-    MAKE_REORDER_FUNC(int32, int32_t, CHANNELS, LAYOUT, MAP) \
-    MAKE_REORDER_FUNC(f64,   double,  CHANNELS, LAYOUT, MAP)
-
-MAKE_REORDER_FUNCS(5, out_50, \
-        out[0] = in[0]; \
-        out[1] = in[1]; \
-        out[2] = in[3]; \
-        out[3] = in[4]; \
-        out[4] = in[2]; \
-        );
-
-MAKE_REORDER_FUNCS(6, out_51, \
-        out[0] = in[0]; \
-        out[1] = in[1]; \
-        out[2] = in[4]; \
-        out[3] = in[5]; \
-        out[4] = in[2]; \
-        out[5] = in[3]; \
-        );
-
-MAKE_REORDER_FUNCS(8, out_71, \
-        out[0] = in[0]; \
-        out[1] = in[1]; \
-        out[2] = in[4]; \
-        out[3] = in[5]; \
-        out[4] = in[2]; \
-        out[5] = in[3]; \
-        out[6] = in[6]; \
-        out[7] = in[7]; \
-        );
-
-#define PICK_REORDER(layout)\
-switch(size) {\
-    case 1: s->reorder_func = alsa_reorder_int8_out_ ##layout;  break;\
-    case 2: s->reorder_func = alsa_reorder_int16_out_ ##layout; break;\
-    case 4: s->reorder_func = alsa_reorder_int32_out_ ##layout; break;\
-    case 8: s->reorder_func = alsa_reorder_f64_out_ ##layout;   break;\
-}
-
-static av_cold int find_reorder_func(AlsaData *s, int codec_id, uint64_t layout, int out)
-{
-    int size;
-
-    /* reordering input is not currently supported */
-    if (!out)
-        return AVERROR(ENOSYS);
-
-    /* reordering is not needed for QUAD or 2_2 layout */
-    if (layout == AV_CH_LAYOUT_QUAD || layout == AV_CH_LAYOUT_2_2)
-        return 0;
-
-    switch (codec_id) {
-    case AV_CODEC_ID_PCM_S8:
-    case AV_CODEC_ID_PCM_U8:
-    case AV_CODEC_ID_PCM_ALAW:
-    case AV_CODEC_ID_PCM_MULAW: size = 1;  break;
-    case AV_CODEC_ID_PCM_S16LE:
-    case AV_CODEC_ID_PCM_S16BE:
-    case AV_CODEC_ID_PCM_U16LE:
-    case AV_CODEC_ID_PCM_U16BE: size = 2; break;
-    case AV_CODEC_ID_PCM_S32LE:
-    case AV_CODEC_ID_PCM_S32BE:
-    case AV_CODEC_ID_PCM_U32LE:
-    case AV_CODEC_ID_PCM_U32BE:
-    case AV_CODEC_ID_PCM_F32LE:
-    case AV_CODEC_ID_PCM_F32BE: size = 4; break;
-    case AV_CODEC_ID_PCM_F64LE:
-    case AV_CODEC_ID_PCM_F64BE: size = 8; break;
-    default:                 return AVERROR(ENOSYS);
-    }
-
-    if      (layout == AV_CH_LAYOUT_5POINT0_BACK || layout == AV_CH_LAYOUT_5POINT0)
-        PICK_REORDER(50)
-    else if (layout == AV_CH_LAYOUT_5POINT1_BACK || layout == AV_CH_LAYOUT_5POINT1)
-        PICK_REORDER(51)
-    else if (layout == AV_CH_LAYOUT_7POINT1)
-        PICK_REORDER(71)
-
-    return s->reorder_func ? 0 : AVERROR(ENOSYS);
-}
-
 av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
                          unsigned int *sample_rate,
                          int channels, enum AVCodecID *codec_id)
@@ -268,8 +169,10 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
 
     snd_pcm_hw_params_free(hw_params);
 
-    if (channels > 2 && layout) {
-        if (find_reorder_func(s, *codec_id, layout, mode == SND_PCM_STREAM_PLAYBACK) < 0) {
+    res = ff_alsa_reorder_find(&s->reorder_func, *codec_id, channels, layout,
+                               mode == SND_PCM_STREAM_PLAYBACK);
+    /* TODO reindent */
+        if (res < 0) {
             char name[128];
             av_get_channel_layout_string(name, sizeof(name), channels, layout);
             av_log(ctx, AV_LOG_WARNING, "ALSA channel layout unknown or unimplemented for %s %s.\n",
@@ -281,7 +184,6 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
             if (!s->reorder_buf)
                 goto fail1;
         }
-    }
 
     s->h = h;
     return 0;
diff --git a/libavdevice/alsa-audio.h b/libavdevice/alsa-audio.h
index 44b7c72..a7783bd 100644
--- a/libavdevice/alsa-audio.h
+++ b/libavdevice/alsa-audio.h
@@ -35,6 +35,7 @@
 #include "libavutil/log.h"
 #include "timefilter.h"
 #include "avdevice.h"
+#include "alsa_reorder.h"
 
 /* XXX: we make the assumption that the soundcard accepts this format */
 /* XXX: find better solution with "preinit" method, needed also in
@@ -54,7 +55,7 @@ typedef struct AlsaData {
     int channels;    ///< number of channels set by user
     int last_period;
     TimeFilter *timefilter;
-    void (*reorder_func)(const void *, void *, int);
+    FFAlsaReorderFunc reorder_func;
     void *reorder_buf;
     int reorder_buf_size; ///< in frames
 } AlsaData;
diff --git a/libavdevice/alsa_reorder.c b/libavdevice/alsa_reorder.c
new file mode 100644
index 0000000..768601e
--- /dev/null
+++ b/libavdevice/alsa_reorder.c
@@ -0,0 +1,126 @@
+/*
+ * ALSA channels reordering
+ * Copyright (c) 2013 Nicolas George
+ *
+ * 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 "libavutil/avassert.h"
+#include "alsa_reorder.h"
+
+#define MAKE_REORDER_FUNC(NAME, TYPE, CHANNELS, LAYOUT, MAP)                \
+static void alsa_reorder_ ## NAME ## _ ## LAYOUT(const void *in_v,          \
+                                                 void *out_v,               \
+                                                 int n)                     \
+{                                                                           \
+    const TYPE *in = in_v;                                                  \
+    TYPE      *out = out_v;                                                 \
+                                                                            \
+    while (n-- > 0) {                                                       \
+        MAP                                                                 \
+        in  += CHANNELS;                                                    \
+        out += CHANNELS;                                                    \
+    }                                                                       \
+}
+
+#define MAKE_REORDER_FUNCS(CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(int8,  int8_t,  CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(int16, int16_t, CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(int32, int32_t, CHANNELS, LAYOUT, MAP) \
+    MAKE_REORDER_FUNC(f64,   double,  CHANNELS, LAYOUT, MAP)
+
+MAKE_REORDER_FUNCS(5, out_50, \
+        out[0] = in[0]; \
+        out[1] = in[1]; \
+        out[2] = in[3]; \
+        out[3] = in[4]; \
+        out[4] = in[2]; \
+        );
+
+MAKE_REORDER_FUNCS(6, out_51, \
+        out[0] = in[0]; \
+        out[1] = in[1]; \
+        out[2] = in[4]; \
+        out[3] = in[5]; \
+        out[4] = in[2]; \
+        out[5] = in[3]; \
+        );
+
+MAKE_REORDER_FUNCS(8, out_71, \
+        out[0] = in[0]; \
+        out[1] = in[1]; \
+        out[2] = in[4]; \
+        out[3] = in[5]; \
+        out[4] = in[2]; \
+        out[5] = in[3]; \
+        out[6] = in[6]; \
+        out[7] = in[7]; \
+        );
+
+#define PICK_REORDER(layout)\
+switch(size) {\
+    case 1: *rf = alsa_reorder_int8_out_ ##layout;  break;\
+    case 2: *rf = alsa_reorder_int16_out_ ##layout; break;\
+    case 4: *rf = alsa_reorder_int32_out_ ##layout; break;\
+    case 8: *rf = alsa_reorder_f64_out_ ##layout;   break;\
+}
+
+int ff_alsa_reorder_find(FFAlsaReorderFunc *rf, enum AVCodecID codec,
+                         int channels, uint64_t layout, int output)
+{
+    int size;
+
+    if (channels <= 2 || !layout)
+        return 0;
+
+    /* reordering input is not currently supported */
+    if (!output)
+        return AVERROR(ENOSYS);
+
+    /* reordering is not needed for QUAD or 2_2 layout */
+    if (layout == AV_CH_LAYOUT_QUAD || layout == AV_CH_LAYOUT_2_2)
+        return 0;
+
+    switch (codec) {
+    case AV_CODEC_ID_PCM_S8:
+    case AV_CODEC_ID_PCM_U8:
+    case AV_CODEC_ID_PCM_ALAW:
+    case AV_CODEC_ID_PCM_MULAW: size = 1;  break;
+    case AV_CODEC_ID_PCM_S16LE:
+    case AV_CODEC_ID_PCM_S16BE:
+    case AV_CODEC_ID_PCM_U16LE:
+    case AV_CODEC_ID_PCM_U16BE: size = 2; break;
+    case AV_CODEC_ID_PCM_S32LE:
+    case AV_CODEC_ID_PCM_S32BE:
+    case AV_CODEC_ID_PCM_U32LE:
+    case AV_CODEC_ID_PCM_U32BE:
+    case AV_CODEC_ID_PCM_F32LE:
+    case AV_CODEC_ID_PCM_F32BE: size = 4; break;
+    case AV_CODEC_ID_PCM_F64LE:
+    case AV_CODEC_ID_PCM_F64BE: size = 8; break;
+    default:                 return AVERROR(ENOSYS);
+    }
+
+    if      (layout == AV_CH_LAYOUT_5POINT0_BACK || layout == AV_CH_LAYOUT_5POINT0)
+        PICK_REORDER(50)
+    else if (layout == AV_CH_LAYOUT_5POINT1_BACK || layout == AV_CH_LAYOUT_5POINT1)
+        PICK_REORDER(51)
+    else if (layout == AV_CH_LAYOUT_7POINT1)
+        PICK_REORDER(71)
+
+    return *rf ? 0 : AVERROR(ENOSYS);
+}
diff --git a/libavdevice/alsa_reorder.h b/libavdevice/alsa_reorder.h
new file mode 100644
index 0000000..96502b2
--- /dev/null
+++ b/libavdevice/alsa_reorder.h
@@ -0,0 +1,44 @@
+/*
+ * ALSA channels reordering
+ * Copyright (c) 2013 Nicolas George
+ *
+ * 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
+ */
+
+#ifndef AVDEVICE_ALSA_REORDER_H
+#define AVDEVICE_ALSA_REORDER_H
+
+#include "libavcodec/avcodec.h"
+
+typedef void (*FFAlsaReorderFunc)(const void *, void *, int);
+
+/**
+ * Init a reorder context.
+ *
+ * @param rf          reorder function
+ * @param codec       PCM codec id of the data
+ * @param channels    number of channels
+ * @param layout      channel layout, either 0 or compatible with channels
+ * @param output      1 if reordering for output, 0 for input
+ * @param buf_size    initial buffer size, in samples
+ * @param frame_size  size of a single sample frame, in bytes
+ * @return  0 for success, or <0 error code
+ */
+int ff_alsa_reorder_find(FFAlsaReorderFunc *rf, enum AVCodecID codec,
+                         int channels, uint64_t layout, int output);
+
+#endif /* AVDEVICE_ALSA_REORDER_H */
-- 
1.7.10.4



More information about the ffmpeg-devel mailing list