[PATCH] Move audioconvert API from libavcodec to libavcore.
Stefano Sabatini
stefano.sabatini-lala
Sun Nov 21 22:08:06 CET 2010
---
libavcodec/audioconvert.c | 74 +++----------------------------
libavcodec/audioconvert.h | 12 ++++-
libavcore/audioconvert.c | 106 +++++++++++++++++++++++++++++++++++++++++++++
libavcore/audioconvert.h | 41 +++++++++++++++++
4 files changed, 164 insertions(+), 69 deletions(-)
diff --git a/libavcodec/audioconvert.c b/libavcodec/audioconvert.c
index b29b030..4bfe396 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,27 @@ 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;
-};
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, NULL) < 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 be4867c..f79dc48 100644
--- a/libavcodec/audioconvert.h
+++ b/libavcodec/audioconvert.h
@@ -81,8 +81,9 @@ 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);
-struct AVAudioConvert;
-typedef struct AVAudioConvert AVAudioConvert;
+#if FF_API_OLD_AUDIOCONVERT
+
+#define AVAudioConvert AVAudioConvertContext
/**
* Create an audio sample format converter context
@@ -93,14 +94,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);
/**
@@ -110,9 +115,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..9a70beb 100644
--- a/libavcore/audioconvert.c
+++ b/libavcore/audioconvert.c
@@ -111,3 +111,109 @@ int av_get_channel_layout_nb_channels(int64_t channel_layout)
x &= x-1; // unset lowest set bit
return count;
}
+
+struct AVAudioConvertContext {
+ const AVClass *av_class;
+ void *log_ctx;
+ int log_level_offset;
+ int in_channels, out_channels;
+ int fmt_pair;
+};
+
+static const AVClass av_audio_convert_context_class = {
+ "AVAudioConvertContext",
+ av_default_item_name,
+ NULL,
+ LIBAVUTIL_VERSION_INT,
+ offsetof(AVAudioConvertContext, log_level_offset),
+ offsetof(AVAudioConvertContext, log_ctx)
+};
+
+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,
+ int log_level_offset, void *log_ctx)
+{
+ *ctx = av_malloc(sizeof(AVAudioConvertContext));
+ if (!*ctx)
+ return AVERROR(ENOMEM);
+ (*ctx)->av_class = &av_audio_convert_context_class;
+ (*ctx)->log_level_offset = log_level_offset;
+ (*ctx)->log_ctx = log_ctx;
+
+ if (in_channels != out_channels) { /* FIXME: not supported */
+ av_log(*ctx, AV_LOG_ERROR, "out_channels %d != in_channels %d is not supported\n",
+ out_channels, in_channels);
+ av_freep(ctx);
+ return AVERROR(EINVAL);
+ }
+
+ (*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 0c6b979..3099425 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
@@ -91,4 +92,44 @@ 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
+ * @param log_ctx parent log context, may be NULL
+ * @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,
+ int log_level_offset, void *log_ctx);
+
+/**
+ * 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.2.3
--1yeeQ81UyVL57Vl7--
More information about the ffmpeg-devel
mailing list