[MEncoder-users] 5.1 sound

Dominik 'Rathann' Mierzejewski dominik at rangers.eu.org
Wed Nov 7 00:17:07 CET 2007


On Tuesday, 06 November 2007 at 23:39, RC wrote:
> On Tue, 06 Nov 2007 21:41:48 +0100
> Sergio <scostas at det.uvigo.es> wrote:
> 
> > And is there a way to automagically fix it?
> 
> Nope.  Figure out what mapping the codecs in question use, and write a
> nice long, complex -af pan filter string to fix it...

Or use the attached patch to do it automagically.

R.

-- 
MPlayer developer and RPMs maintainer: http://mplayerhq.hu http://rpm.livna.org
There should be a science of discontent. People need hard times and
oppression to develop psychic muscles.
	-- from "Collected Sayings of Muad'Dib" by the Princess Irulan
-------------- next part --------------
Index: libmpcodecs/ad_pcm.c
===================================================================
--- libmpcodecs/ad_pcm.c	(revision 20547)
+++ libmpcodecs/ad_pcm.c	(working copy)
@@ -22,6 +22,21 @@
   WAVEFORMATEX *h=sh_audio->wf;
   sh_audio->i_bps=h->nAvgBytesPerSec;
   sh_audio->channels=h->nChannels;
+  /* re-map channels */
+  switch (sh_audio->channels) {
+    case 1: /* no action needed */
+    case 2: /* no action needed */
+    /* more mappings should be added when documentation or samples are found */
+    case 3: /* unknown? */
+    case 4: /* unknown? */
+    case 5: /* unknown? */
+      break;
+    case 6:
+      sh_audio->chan_map = "00" "11" "24" "35" "42" "53";
+      break;
+    default:
+      break;
+  }
   sh_audio->samplerate=h->nSamplesPerSec;
   sh_audio->samplesize=(h->wBitsPerSample+7)/8;
   sh_audio->sample_format=AF_FORMAT_S16_LE; // default
Index: libmpcodecs/ad_faad.c
===================================================================
--- libmpcodecs/ad_faad.c	(revision 20547)
+++ libmpcodecs/ad_faad.c	(working copy)
@@ -152,6 +152,23 @@
     mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %ldHz  channels: %d\n", faac_samplerate, faac_channels);
     sh->channels = faac_channels;
     if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
+    
+    /* re-map channels */
+    switch (sh->channels) {
+      default:
+      case 1: /* no action needed */
+      case 2: /* no action needed */
+      case 3: /* no suitable default behavior? */
+      case 4: /* no suitable default behavior? */
+        break;
+      case 5: /* mplayer treats this like 6-channel */
+      case 6:
+        sh->chan_map = "04" "10" "21" "32" "43" "55";
+        break;
+      case 7: /* not supported by mplayer? */
+        break;
+    }
+    
     sh->samplerate = faac_samplerate;
     sh->samplesize=2;
     //sh->o_bps = sh->samplesize*faac_channels*faac_samplerate;
Index: libmpcodecs/ad_dmo.c
===================================================================
--- libmpcodecs/ad_dmo.c	(revision 20547)
+++ libmpcodecs/ad_dmo.c	(working copy)
@@ -40,6 +40,21 @@
   }
     sh_audio->i_bps=sh_audio->wf->nAvgBytesPerSec;
     sh_audio->channels=chans;
+    /* re-map channels */
+    switch (chans) {
+      case 1: /* no action needed */
+      case 2: /* no action needed */
+      /* more mappings should be added when documentation or samples are found */
+      case 3: /* unknown? */
+      case 4: /* unknown? */
+      case 5: /* unknown? */
+        break;
+      case 6:
+        sh_audio->chan_map = "00" "11" "24" "35" "42" "53";
+        break;
+      default:
+        break;
+    }
     sh_audio->samplerate=sh_audio->wf->nSamplesPerSec;
     sh_audio->samplesize=2;
     sh_audio->audio_in_minsize=4*sh_audio->wf->nBlockAlign;
Index: libmpcodecs/dec_audio.c
===================================================================
--- libmpcodecs/dec_audio.c	(revision 20547)
+++ libmpcodecs/dec_audio.c	(working copy)
@@ -311,6 +311,7 @@
 
   // filter config:  
   memcpy(&afs->cfg,&af_cfg,sizeof(af_cfg_t));
+  afs->chan_map = sh_audio->chan_map;
   
   mp_msg(MSGT_DECAUDIO, MSGL_V, MSGTR_BuildingAudioFilterChain,
       afs->input.rate,afs->input.nch,af_fmt2str_short(afs->input.format),
Index: libmpdemux/stheader.h
===================================================================
--- libmpdemux/stheader.h	(revision 20547)
+++ libmpdemux/stheader.h	(working copy)
@@ -19,6 +19,7 @@
   int samplerate;
   int samplesize;
   int channels;
+  char *chan_map;
   int o_bps; // == samplerate*samplesize*channels   (uncompr. bytes/sec)
   int i_bps; // == bitrate  (compressed bytes/sec)
   // in buffers:
Index: libaf/af.c
===================================================================
--- libaf/af.c	(revision 20547)
+++ libaf/af.c	(working copy)
@@ -359,17 +359,47 @@
 
   // Check if this is the first call
   if(!s->first){
+
+    /* remap channels if the codec/demuxer provides a channel map */
+    if (s->chan_map) {
+      int *routes;
+      af_instance_t *af = NULL;
+      af_control_ext_t arg;
+      arg.ch = s->input.nch;
+      af = af_append(s, s->first, "channels");
+      /* check/set up the routes */
+      if (! (routes = af_set_channel_map(s->input.nch, s->chan_map)) )
+        return -1;
+      /* set up af_channels to route */
+      if (!af || (AF_OK != af->control(af, AF_CONTROL_CHANNELS_ROUTER, &s->input.nch)))
+        return -1;
+      if (!af || (AF_OK != af->control(af, AF_CONTROL_CHANNELS_NR, &s->input.nch)))
+        return -1;
+      /* pass each route to af_channels */
+      for (arg.ch = 0; arg.ch < s->input.nch; ++arg.ch) {
+        arg.arg = routes + 2*arg.ch; /* two by two... */
+        if (!af || (AF_OK != af->control(af, AF_CONTROL_CHANNELS_ROUTING, &arg)))
+          return -1;
+      }
+      /* try it! */
+      if (!af || (AF_OK != af->control(af, AF_CONTROL_CHANNELS, &s->input.nch)))
+        return -1;
+      if (AF_OK != af_reinit(s,af))
+        return -1;
+    }
+
     // 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")) 
-	return -1; 
-    }
-    else{
+    if (s->cfg.list) {
       while(s->cfg.list[i]){
 	if(!af_append(s,s->last,s->cfg.list[i++]))
 	  return -1;
       }
     }
+    // To make automatic format conversion work
+    if (!s->first){
+      if(!af_append(s,s->first,"dummy")) 
+	return -1; 
+    }
   }
 
   // Init filters 
@@ -709,3 +739,22 @@
 {
     data->bps = af_fmt2bits(data->format)/8;
 }
+
+int *af_set_channel_map(int channels, char *chan_map){
+  int *routes, *ptr;
+  if (strlen(chan_map) != 2*channels) {
+    af_msg(AF_MSG_ERROR, "channel map: incorrect num. of routes in channel map\n");
+    return NULL;
+  }
+  ptr = routes = malloc(2 * channels * sizeof(int));
+  if (!chan_map) {
+    mp_msg(MSGT_DEMUX, MSGL_ERR, "set_channel_map: cannot malloc for %d channels\n", channels);
+    return 0;
+  }
+  while (channels-- > 0) {
+    /* two by two... */
+    *ptr++ = *chan_map++ - '0';
+    *ptr++ = *chan_map++ - '0';
+  }
+  return routes;
+}
Index: libaf/af.h
===================================================================
--- libaf/af.h	(revision 20547)
+++ libaf/af.h	(working copy)
@@ -104,6 +104,7 @@
   af_data_t output;
   // Configuration for this stream
   af_cfg_t cfg;
+  char *chan_map;
 }af_stream_t;
 
 /*********************************************
@@ -329,6 +330,17 @@
  */
 void af_fix_parameters(af_data_t *data);
 
+/**
+ * \brief set up channel remapping
+ * \param number of output channels
+ * \param string of from-to routes
+ * \return int array of routes, NULL if error
+ *
+ * Makes an int array from a string of provided routes.
+ * Checks that number of routes matches channels.
+ */
+int *af_set_channel_map(int channels, char *chan_map);
+
 /** Memory reallocation macro: if a local buffer is used (i.e. if the
    filter doesn't operate on the incoming buffer this macro must be
    called to ensure the buffer is big enough.


More information about the MEncoder-users mailing list