ffmpeg: resurrect -map_channel.
authorClément Bœsch <ubitux@gmail.com>
Thu, 17 May 2012 17:31:35 +0000 (19:31 +0200)
committerClément Bœsch <ubitux@gmail.com>
Fri, 18 May 2012 21:40:03 +0000 (23:40 +0200)
ffmpeg.c
tests/Makefile

index a348624..bd7e6c1 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -49,6 +49,7 @@
 #include "libavutil/libm.h"
 #include "libavutil/imgutils.h"
 #include "libavutil/timestamp.h"
+#include "libavutil/bprint.h"
 #include "libavformat/os_support.h"
 #include "libswresample/swresample.h"
 
@@ -294,6 +295,10 @@ typedef struct OutputStream {
     int forced_kf_count;
     int forced_kf_index;
 
+    /* audio only */
+    int audio_channels_map[SWR_CH_MAX];  /* list of the channels id to pick from the source stream */
+    int audio_channels_mapped;           /* number of channels in audio_channels_map */
+
     FILE *logfile;
 
     OutputFilter *filter;
@@ -870,25 +875,46 @@ static int configure_audio_filters(FilterGraph *fg, AVFilterContext **in_filter,
         *out_filter = format;
     }
 
-    if (audio_volume != 256) {
-        AVFilterContext *volume;
-        char args[256];
+#define AUTO_INSERT_FILTER(opt_name, filter_name, arg) do {                 \
+    AVFilterContext *filt_ctx;                                              \
+                                                                            \
+    av_log(NULL, AV_LOG_WARNING, opt_name " has been deprecated. "          \
+           "Use the " filter_name " filter instead "                        \
+           "(-af " filter_name "=%s).\n", arg);                             \
+                                                                            \
+    ret = avfilter_graph_create_filter(&filt_ctx,                           \
+                                       avfilter_get_by_name(filter_name),   \
+                                       filter_name, arg, NULL, fg->graph);  \
+    if (ret < 0)                                                            \
+        return ret;                                                         \
+                                                                            \
+    ret = avfilter_link(*in_filter, 0, filt_ctx, 0);                        \
+    if (ret < 0)                                                            \
+        return ret;                                                         \
+                                                                            \
+    *in_filter = filt_ctx;                                                  \
+} while (0)
+
+    if (ost->audio_channels_mapped) {
+        int i;
+        AVBPrint pan_buf;
 
-        snprintf(args, sizeof(args), "%lf", audio_volume / 256.);
-        av_log(NULL, AV_LOG_WARNING, "-vol has been deprecated. Used the "
-               "volume audio filter instead (-af volume=%s).\n", args);
+        av_bprint_init(&pan_buf, 256, 8192);
+        av_bprintf(&pan_buf, "0x%"PRIx64,
+                   av_get_default_channel_layout(ost->audio_channels_mapped));
+        for (i = 0; i < ost->audio_channels_mapped; i++)
+            if (ost->audio_channels_map[i] != -1)
+                av_bprintf(&pan_buf, ":c%d=c%d", i, ost->audio_channels_map[i]);
 
-        ret = avfilter_graph_create_filter(&volume,
-                                           avfilter_get_by_name("volume"),
-                                           "volume", args, NULL, fg->graph);
-        if (ret < 0)
-            return ret;
+        AUTO_INSERT_FILTER("-map_channel", "pan", pan_buf.str);
+        av_bprint_finalize(&pan_buf, NULL);
+    }
 
-        ret = avfilter_link(*in_filter, 0, volume, 0);
-        if (ret < 0)
-            return ret;
+    if (audio_volume != 256) {
+        char args[256];
 
-        *in_filter = volume;
+        snprintf(args, sizeof(args), "%lf", audio_volume / 256.);
+        AUTO_INSERT_FILTER("-vol", "volume", args);
     }
 
     return 0;
@@ -4629,6 +4655,21 @@ static OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, in
         MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
         if (filters)
             ost->avfilter = av_strdup(filters);
+
+        /* check for channel mapping for this audio stream */
+        for (n = 0; n < o->nb_audio_channel_maps; n++) {
+            AudioChannelMap *map = &o->audio_channel_maps[n];
+            InputStream *ist = input_streams[ost->source_index];
+            if ((map->channel_idx == -1 || (ist->file_index == map->file_idx && ist->st->index == map->stream_idx)) &&
+                (map->ofile_idx   == -1 || ost->file_index == map->ofile_idx) &&
+                (map->ostream_idx == -1 || ost->st->index  == map->ostream_idx)) {
+                if (ost->audio_channels_mapped < FF_ARRAY_ELEMS(ost->audio_channels_map))
+                    ost->audio_channels_map[ost->audio_channels_mapped++] = map->channel_idx;
+                else
+                    av_log(NULL, AV_LOG_FATAL, "Max channel mapping for output %d.%d reached\n",
+                           ost->file_index, ost->st->index);
+            }
+        }
     }
 
     return ost;
index 8544193..a724e06 100644 (file)
@@ -55,7 +55,7 @@ include $(SRC_PATH)/tests/fate/image.mak
 include $(SRC_PATH)/tests/fate/indeo.mak
 include $(SRC_PATH)/tests/fate/libavcodec.mak
 include $(SRC_PATH)/tests/fate/libavutil.mak
-#include $(SRC_PATH)/tests/fate/mapchan.mak
+include $(SRC_PATH)/tests/fate/mapchan.mak
 include $(SRC_PATH)/tests/fate/lossless-audio.mak
 include $(SRC_PATH)/tests/fate/lossless-video.mak
 include $(SRC_PATH)/tests/fate/microsoft.mak