From eafa2b600502f5e8b36b99a2737d6b3d3a58441f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Thu, 17 Nov 2011 15:06:35 +0100 Subject: [PATCH] swr: introduce a public function to customize the channel mapping. --- ffmpeg.c | 3 ++- ffplay.c | 2 +- libswresample/swresample.c | 11 ++++++++--- libswresample/swresample.h | 16 ++++++++++++---- libswresample/swresample_test.c | 4 ++-- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index b664339934..9895fb3970 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -894,8 +894,9 @@ need_realloc: ost->swr = swr_alloc_set_opts(ost->swr, enc->channel_layout, enc->sample_fmt, enc->sample_rate, dec->channel_layout, dec->sample_fmt, dec->sample_rate, - ost->audio_channels_mapped ? ost->audio_channels_map : NULL, 0, NULL); + if (ost->audio_channels_mapped) + swr_set_channel_mapping(ost->swr, ost->audio_channels_map); av_opt_set_double(ost->swr, "rmvol", ost->rematrix_volume, 0); if (ost->audio_channels_mapped) { av_opt_set_int(ost->swr, "icl", av_get_default_channel_layout(ost->audio_channels_mapped), 0); diff --git a/ffplay.c b/ffplay.c index 8022be504c..2ce7ea2047 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2079,7 +2079,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) is->swr_ctx = swr_alloc_set_opts(NULL, is->audio_tgt_channel_layout, is->audio_tgt_fmt, is->audio_tgt_freq, dec_channel_layout, dec->sample_fmt, dec->sample_rate, - NULL, 0, NULL); + 0, NULL); if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) { fprintf(stderr, "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n", dec->sample_rate, diff --git a/libswresample/swresample.c b/libswresample/swresample.c index a8576d4b1b..b0a00414bd 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -73,6 +73,13 @@ static const AVClass av_class = { static int resample(SwrContext *s, AudioData *out_param, int out_count, const AudioData * in_param, int in_count); +int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map){ + if(!s || s->in_convert) // s needs to be allocated but not initialized + return AVERROR(EINVAL); + s->channel_map = channel_map; + return 0; +} + struct SwrContext *swr_alloc(void){ SwrContext *s= av_mallocz(sizeof(SwrContext)); if(s){ @@ -85,7 +92,7 @@ struct SwrContext *swr_alloc(void){ struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, - const int *channel_map, int log_offset, void *log_ctx){ + int log_offset, void *log_ctx){ if(!s) s= swr_alloc(); if(!s) return NULL; @@ -101,8 +108,6 @@ struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, av_opt_set_int(s, "tsf", AV_SAMPLE_FMT_S16, 0); av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> in_ch_layout), 0); av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->out_ch_layout), 0); - - s->channel_map = channel_map; return s; } diff --git a/libswresample/swresample.h b/libswresample/swresample.h index 67845940ac..d7b55a0f70 100644 --- a/libswresample/swresample.h +++ b/libswresample/swresample.h @@ -30,7 +30,7 @@ #include "libavutil/samplefmt.h" #define LIBSWRESAMPLE_VERSION_MAJOR 0 -#define LIBSWRESAMPLE_VERSION_MINOR 3 +#define LIBSWRESAMPLE_VERSION_MINOR 4 #define LIBSWRESAMPLE_VERSION_MICRO 0 #define SWR_CH_MAX 16 ///< Maximum number of channels @@ -74,8 +74,6 @@ int swr_init(struct SwrContext *s); * @param in_ch_layout input channel layout (AV_CH_LAYOUT_*) * @param in_sample_fmt input sample format (AV_SAMPLE_FMT_*). Use +0x100 for planar audio * @param in_sample_rate input sample rate (frequency in Hz) - * @param channel_map customized input channel mapping (array of channel - * indexes, -1 for a muted channel), can be NULL * @param log_offset logging level offset * @param log_ctx parent logging context, can be NULL * @@ -85,7 +83,7 @@ int swr_init(struct SwrContext *s); struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate, int64_t in_ch_layout, enum AVSampleFormat in_sample_fmt, int in_sample_rate, - const int *channel_map, int log_offset, void *log_ctx); + int log_offset, void *log_ctx); /** * Free the given SwrContext and set the pointer to NULL. @@ -114,4 +112,14 @@ int swr_convert(struct SwrContext *s, uint8_t *out[SWR_CH_MAX], int out_count, */ void swr_compensate(struct SwrContext *s, int sample_delta, int compensation_distance); +/** + * Set a customized input channel mapping. + * + * @param s allocated Swr context, not yet initialized + * @param channel_map customized input channel mapping (array of channel + * indexes, -1 for a muted channel) + * @return AVERROR error code in case of failure. + */ +int swr_set_channel_mapping(struct SwrContext *s, const int *channel_map); + #endif diff --git a/libswresample/swresample_test.c b/libswresample/swresample_test.c index 321ce70df6..840c52cff3 100644 --- a/libswresample/swresample_test.c +++ b/libswresample/swresample_test.c @@ -132,10 +132,10 @@ int main(int argc, char **argv){ av_get_sample_fmt_name(in_sample_fmt), av_get_sample_fmt_name(out_sample_fmt)); forw_ctx = swr_alloc_set_opts(forw_ctx, out_ch_layout, out_sample_fmt+planar_out, out_sample_rate, in_ch_layout, in_sample_fmt+planar_in , in_sample_rate, - NULL, 0, 0); + 0, 0); backw_ctx = swr_alloc_set_opts(backw_ctx, in_ch_layout, in_sample_fmt, in_sample_rate, out_ch_layout, out_sample_fmt+planar_out, out_sample_rate, - NULL, 0, 0); + 0, 0); if(swr_init( forw_ctx) < 0) fprintf(stderr, "swr_init(->) failed\n"); if(swr_init(backw_ctx) < 0)