[MPlayer-dev-eng] [PATCH] Automatic downmix

Clément Bœsch ubitux at gmail.com
Sat Sep 25 13:37:53 CEST 2010


On Sat, Sep 25, 2010 at 12:54:16PM +0200, Reimar Döffinger wrote:
> On Sat, Sep 25, 2010 at 11:57:21AM +0200, Clément Bœsch wrote:
> > On Fri, Sep 24, 2010 at 07:20:32PM +0200, Reimar Döffinger wrote:
> > > On Thu, Sep 23, 2010 at 11:57:26PM +0200, Clément Bœsch wrote:
> > > > +    static char * const downmix_strs[AF_NCH + 1] = {
> > > 
> > > static const char * const
> > > 
> > > > +    char *af_pan_str = downmix_strs[s->first->data->nch];
> > > 
> > > const char *
> > > 
> > 
> > That would require a modification of the prototypes of af_{ap,pre}pend
> > first, should I include it in the patch?
> 
> Already applied.

I saw it on IRC, thanks :)

> Just not adding const here is very much the wrong solution,
> if af_append/af_prepend actually modified it, this way would
> still crash.
> 

Sure.

> > > Wouldn't it make more sense to move this into the existing
> > > > if(!s->first)
> > > above,
> > 
> > I thought about that, but I'm not sure we enter in that condition
> > everytime; the first "if(!s->first)" condition seems the more reliable
> > "first call" condition. I don't understand what the second one is for
> > (what is AF_DETACH?).
> 
> I meant the first one.

Oh ok, makes more sense.

> And AF_DETACH allows a filter to remove itself if it thinks it serves
> no purpose (e.g. a resampling filter with the same input and output
> sample rate).
> 

Ok.

> > > use af_append to put it first in the chain
> > 
> > Append? why?
> 
> Because all of the code around there uses af_append
> and builds the filter chain front to end. Adding a
> single case where it does things the other way can't
> do any good.

Ok, changed.

New patch attached: I re-run the previous tests and got the same results
with that version. I also dropped the af_reinit call since it's done
anyway after the if(!s->first). I can then change the prototype of
af_downmix to void, but I'm not sure it's harmless to keep it.

Regards,

-- 
Clément B.
-------------- next part --------------
Index: libaf/af.c
===================================================================
--- libaf/af.c	(revision 32346)
+++ libaf/af.c	(working copy)
@@ -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,24 @@
     return AF_OK;
 }
 
+/**
+ * Automatic downmix to stereo in case the codec does not implement it.
+ */
+static af_instance_t *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];
+    return af_pan_str ? af_append(s, s->first, af_pan_str) : NULL;
+}
+
 /* 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 +457,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){      // To make automatic format conversion work
       if(!af_append(s,s->first,"dummy"))


More information about the MPlayer-dev-eng mailing list