[FFmpeg-devel] [PATCH 1/2] swr: introduce a public function to customize the channel mapping.

Clément Bœsch ubitux at gmail.com
Thu Nov 17 18:01:09 CET 2011


---
 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 b664339..9895fb3 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 8022be5..2ce7ea2 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 a8576d4..b0a0041 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 6784594..d7b55a0 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 321ce70..840c52c 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)
-- 
1.7.7.3



More information about the ffmpeg-devel mailing list