[FFmpeg-devel] [PATCH] Move audioconvert API from libavcodec to libavcore.
Stefano Sabatini
stefano.sabatini-lala
Sat Nov 20 19:17:11 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..a18ea84 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
More information about the ffmpeg-devel
mailing list