[PATCH] Move audioconvert API from libavcodec to libavcore.

Stefano Sabatini stefano.sabatini-lala
Sat Nov 20 19:07:38 CET 2010


---
 libavcodec/audioconvert.c |   74 ++++-----------------------------------
 libavcodec/audioconvert.h |    8 ++++
 libavcore/audioconvert.c  |   85 +++++++++++++++++++++++++++++++++++++++++++++
 libavcore/audioconvert.h  |   39 ++++++++++++++++++++
 4 files changed, 140 insertions(+), 66 deletions(-)

diff --git a/libavcodec/audioconvert.c b/libavcodec/audioconvert.c
index 609fd1c..5e8b19e 100644
--- a/libavcodec/audioconvert.c
+++ b/libavcodec/audioconvert.c
@@ -27,7 +27,7 @@
 
 #include "libavutil/avstring.h"
 #include "libavutil/libm.h"
-#include "libavcore/samplefmt.h"
+#include "libavcore/audioconvert.h"
 #include "avcodec.h"
 #include "audioconvert.h"
 
@@ -77,87 +77,29 @@ int avcodec_channel_layout_num_channels(int64_t channel_layout)
 {
     return av_get_channel_layout_nb_channels(channel_layout);
 }
-#endif
 
-struct AVAudioConvert {
-    int in_channels, out_channels;
-    int fmt_pair;
-};
+typedef AVAudioConvert AudioConvertContext;
 
 AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
                                        enum AVSampleFormat in_fmt, int in_channels,
                                        const float *matrix, int flags)
 {
-    AVAudioConvert *ctx;
-    if (in_channels!=out_channels)
-        return NULL;  /* FIXME: not supported */
-    ctx = av_malloc(sizeof(AVAudioConvert));
-    if (!ctx)
+    AVAudioConvert *ctx = NULL;
+    if (av_audio_convert_alloc2(&ctx, out_fmt, out_channels, in_fmt, in_channels, matrix, flags) < 0)
         return NULL;
-    ctx->in_channels = in_channels;
-    ctx->out_channels = out_channels;
-    ctx->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt;
+
     return ctx;
 }
 
 void av_audio_convert_free(AVAudioConvert *ctx)
 {
-    av_free(ctx);
+    av_audio_convert_free2(ctx);
 }
 
 int av_audio_convert(AVAudioConvert *ctx,
                            void * const out[6], const int out_stride[6],
                      const void * const  in[6], const int  in_stride[6], int len)
 {
-    int ch;
-
-    //FIXME optimize common cases
-
-    for(ch=0; ch<ctx->out_channels; ch++){
-        const int is=  in_stride[ch];
-        const int os= out_stride[ch];
-        const uint8_t *pi=  in[ch];
-        uint8_t *po= out[ch];
-        uint8_t *end= po + os*len;
-        if(!out[ch])
-            continue;
-
-#define CONV(ofmt, otype, ifmt, expr)\
-if(ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt){\
-    do{\
-        *(otype*)po = expr; pi += is; po += os;\
-    }while(po < end);\
-}
-
-//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
-//FIXME rounding ?
-
-             CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 ,  *(const uint8_t*)pi)
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi)
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi<<16)
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0 / (1<<15)))
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0 / (1<<15)))
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi>>16)
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi)
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0 / (1<<31)))
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0 / (1<<31)))
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(  lrintf(*(const float*)pi * (1<<7)) + 0x80))
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(  lrintf(*(const float*)pi * (1<<15))))
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_FLT, *(const float*)pi)
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
-        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(  lrint(*(const double*)pi * (1<<7)) + 0x80))
-        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(  lrint(*(const double*)pi * (1<<15))))
-        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
-        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_DBL, *(const double*)pi)
-        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
-        else return -1;
-    }
-    return 0;
+    return av_audio_convert2(ctx, out, out_stride, in, in_stride, len);
 }
+#endif /* FF_API_OLD_AUDIOCONVERT */
diff --git a/libavcodec/audioconvert.h b/libavcodec/audioconvert.h
index 66a12a6..7bd71dc 100644
--- a/libavcodec/audioconvert.h
+++ b/libavcodec/audioconvert.h
@@ -87,6 +87,7 @@ int avcodec_channel_layout_num_channels(int64_t channel_layout);
  */
 int64_t avcodec_guess_channel_layout(int nb_channels, enum CodecID codec_id, const char *fmt_name);
 
+#if FF_API_OLD_AUDIOCONVERT
 struct AVAudioConvert;
 typedef struct AVAudioConvert AVAudioConvert;
 
@@ -99,14 +100,18 @@ typedef struct AVAudioConvert AVAudioConvert;
  * @param[in] matrix Channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore.
  * @param flags See AV_CPU_FLAG_xx
  * @return NULL on error
+ * @deprecated Use av_audio_convert_alloc2() instead.
  */
+attribute_deprecated
 AVAudioConvert *av_audio_convert_alloc(enum AVSampleFormat out_fmt, int out_channels,
                                        enum AVSampleFormat in_fmt, int in_channels,
                                        const float *matrix, int flags);
 
 /**
  * Free audio sample format converter context
+ * @deprecated Use av_audio_convert_free2() instead.
  */
+attribute_deprecated
 void av_audio_convert_free(AVAudioConvert *ctx);
 
 /**
@@ -116,9 +121,12 @@ void av_audio_convert_free(AVAudioConvert *ctx);
  * @param[in] in array of input buffers for each channel
  * @param[in] in_stride distance between consecutive input samples (measured in bytes)
  * @param len length of audio frame size (measured in samples)
+ * @deprecated Use av_audio_convert2() instead.
  */
+attribute_deprecated
 int av_audio_convert(AVAudioConvert *ctx,
                            void * const out[6], const int out_stride[6],
                      const void * const  in[6], const int  in_stride[6], int len);
+#endif
 
 #endif /* AVCODEC_AUDIOCONVERT_H */
diff --git a/libavcore/audioconvert.c b/libavcore/audioconvert.c
index 171d6b1..8c21dd8 100644
--- a/libavcore/audioconvert.c
+++ b/libavcore/audioconvert.c
@@ -111,3 +111,88 @@ int av_get_channel_layout_nb_channels(int64_t channel_layout)
         x &= x-1; // unset lowest set bit
     return count;
 }
+
+struct AVAudioConvertContext {
+    int in_channels, out_channels;
+    int fmt_pair;
+};
+
+int av_audio_convert_alloc2(AVAudioConvertContext **ctx,
+                            enum AVSampleFormat out_fmt, int out_channels,
+                            enum AVSampleFormat in_fmt, int in_channels,
+                            const float *matrix, int flags)
+{
+    *ctx = NULL;
+
+    if (in_channels != out_channels)
+        return AVERROR(EINVAL);  /* FIXME: not supported */
+    *ctx = av_malloc(sizeof(AVAudioConvertContext));
+    if (!*ctx)
+        return AVERROR(ENOMEM);
+    (*ctx)->in_channels  = in_channels;
+    (*ctx)->out_channels = out_channels;
+    (*ctx)->fmt_pair = out_fmt + AV_SAMPLE_FMT_NB*in_fmt;
+    return 0;
+}
+
+void av_audio_convert_free2(AVAudioConvertContext *ctx)
+{
+    av_free(ctx);
+}
+
+int av_audio_convert2(AVAudioConvertContext *ctx,
+                           void * const out[8], const int out_stride[8],
+                     const void * const  in[8], const int  in_stride[8], int len)
+{
+    int ch;
+
+    //FIXME optimize common cases
+
+    for (ch = 0; ch < ctx->out_channels; ch++) {
+        const int is =  in_stride[ch];
+        const int os = out_stride[ch];
+        const uint8_t *pi=  in[ch];
+        uint8_t *po  = out[ch];
+        uint8_t *end = po + os*len;
+        if (!out[ch])
+            continue;
+
+#define CONV(ofmt, otype, ifmt, expr)\
+if (ctx->fmt_pair == ofmt + AV_SAMPLE_FMT_NB*ifmt) {\
+    do {\
+        *(otype*)po = expr; pi += is; po += os;\
+    } while (po < end);\
+}
+
+//FIXME put things below under ifdefs so we do not waste space for cases no codec will need
+//FIXME rounding ?
+
+             CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_U8 ,  *(const uint8_t*)pi)
+        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<8)
+        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)<<24)
+        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
+        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_U8 , (*(const uint8_t*)pi - 0x80)*(1.0 / (1<<7)))
+        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S16, (*(const int16_t*)pi>>8) + 0x80)
+        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi)
+        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S16,  *(const int16_t*)pi<<16)
+        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0 / (1<<15)))
+        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S16,  *(const int16_t*)pi*(1.0 / (1<<15)))
+        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_S32, (*(const int32_t*)pi>>24) + 0x80)
+        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi>>16)
+        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_S32,  *(const int32_t*)pi)
+        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0 / (1<<31)))
+        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_S32,  *(const int32_t*)pi*(1.0 / (1<<31)))
+        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(  lrintf(*(const float*)pi * (1<<7)) + 0x80))
+        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(  lrintf(*(const float*)pi * (1<<15))))
+        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float*)pi * (1U<<31))))
+        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_FLT, *(const float*)pi)
+        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_FLT, *(const float*)pi)
+        else CONV(AV_SAMPLE_FMT_U8 , uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(  lrint(*(const double*)pi * (1<<7)) + 0x80))
+        else CONV(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(  lrint(*(const double*)pi * (1<<15))))
+        else CONV(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double*)pi * (1U<<31))))
+        else CONV(AV_SAMPLE_FMT_FLT, float  , AV_SAMPLE_FMT_DBL, *(const double*)pi)
+        else CONV(AV_SAMPLE_FMT_DBL, double , AV_SAMPLE_FMT_DBL, *(const double*)pi)
+        else return AVERROR(EINVAL);
+    }
+    return 0;
+}
diff --git a/libavcore/audioconvert.h b/libavcore/audioconvert.h
index 43402b3..39bdae5 100644
--- a/libavcore/audioconvert.h
+++ b/libavcore/audioconvert.h
@@ -28,6 +28,7 @@
  */
 
 #include "avcore.h"
+#include "samplefmt.h"
 
 /* Audio channel masks */
 #define AV_CH_FRONT_LEFT             0x00000001
@@ -97,4 +98,42 @@ void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, int6
  */
 int av_get_channel_layout_nb_channels(int64_t channel_layout);
 
+typedef struct AVAudioConvertContext AVAudioConvertContext;
+
+/**
+ * Create an audio sample format converter context.
+ *
+ * @param ctx pointer where to put the created converter context, it
+ * is set to NULL in case of failure
+ * @param out_fmt output sample format
+ * @param out_nb_channels number of output channels
+ * @param in_fmt input sample format
+ * @param in_nb_channels number of input channels
+ * @param[in] matrix channel mixing matrix (of dimension in_channel*out_channels). Set to NULL to ignore.
+ * @param flags see AV_CPU_FLAG_xx
+ * @return 0 in case of success, a negative AVERROR code otherwise
+ */
+int av_audio_convert_alloc2(AVAudioConvertContext **ctx,
+                            enum AVSampleFormat out_fmt, int out_nb_channels,
+                            enum AVSampleFormat in_fmt, int in_nb_channels,
+                            const float *matrix, int flags);
+
+/**
+ * Free audio sample format converter context
+ */
+void av_audio_convert_free2(AVAudioConvertContext *ctx);
+
+/**
+ * Convert between audio sample formats.
+ *
+ * @param[in] out array of output buffers for each channel. set to NULL to ignore processing of the given channel.
+ * @param[in] out_stride distance between consecutive output samples (measured in bytes)
+ * @param[in] in array of input buffers for each channel
+ * @param[in] in_stride distance between consecutive input samples (measured in bytes)
+ * @param len length of audio frame size (measured in samples)
+ */
+int av_audio_convert2(AVAudioConvertContext *ctx,
+                            void * const out[8], const int out_stride[8],
+                      const void * const  in[8], const int  in_stride[8], int len);
+
 #endif /* AVCORE_AUDIOCONVERT_H */
-- 
1.7.1


--0OAP2g/MAC+5xKAE--



More information about the ffmpeg-devel mailing list