changeset 32272:fd4cd29b6121

Automatic downmix using the pan filter when the requested channel count is 2 and the codec does not support it natively. Patch by Clment Bsch, ubitux gmail com
author cigaes
date Sun, 26 Sep 2010 08:45:40 +0000
parents 563b35a003b8
children 96aa67fb9a63
files libaf/af.c
diffstat 1 files changed, 24 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af.c	Sun Sep 26 01:36:16 2010 +0000
+++ b/libaf/af.c	Sun Sep 26 08:45:40 2010 +0000
@@ -21,6 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "osdep/strsep.h"
+#include "libmpcodecs/dec_audio.h"
 
 #include "af.h"
 
@@ -412,6 +413,26 @@
     return AF_OK;
 }
 
+/**
+ * Automatic downmix to stereo in case the codec does not implement it.
+ */
+static void af_downmix(af_stream_t* s)
+{
+    static const char * const downmix_strs[AF_NCH + 1] = {
+        /*                FL       FR       RL       RR          FC          LF         AL      AR */
+        [3] = "pan=2:" "0.6:0:" "0:0.6:"                     "0.4:0.4",
+        [4] = "pan=2:" "0.6:0:" "0:0.6:" "0.4:0:"  "0:0.4",
+        [5] = "pan=2:" "0.5:0:" "0:0.5:" "0.2:0:"  "0:0.2:"  "0.3:0.3",
+        [6] = "pan=2:" "0.4:0:" "0:0.4:" "0.2:0:"  "0:0.2:"  "0.3:0.3:"   "0.1:0.1",
+        [7] = "pan=2:" "0.4:0:" "0:0.4:" "0.2:0:"  "0:0.2:"  "0.3:0.3:"              "0.1:0:" "0:0.1",
+        [8] = "pan=2:" "0.4:0:" "0:0.4:" "0.15:0:" "0:0.15:" "0.25:0.25:" "0.1:0.1:" "0.1:0:" "0:0.1",
+    };
+    const char *af_pan_str = downmix_strs[s->input.nch];
+
+    if (af_pan_str)
+        af_append(s, s->first, af_pan_str);
+}
+
 /* Initialize the stream "s". This function creates a new filter list
    if necessary according to the values set in input and output. Input
    and output should contain the format of the current movie and the
@@ -438,6 +459,9 @@
 
   // Check if this is the first call
   if(!s->first){
+    // Append a downmix pan filter at the beginning of the chain if needed
+    if (s->input.nch != audio_output_channels && audio_output_channels == 2)
+      af_downmix(s);
     // Add all filters in the list (if there are any)
     if (s->cfg.list) {
       while(s->cfg.list[i]){