[MPlayer-dev-eng] [PATCH] fixing srate, channels etc.

Reimar Döffinger Reimar.Doeffinger at stud.uni-karlsruhe.de
Thu Jun 9 21:47:38 CEST 2005


Hi,
this is a patch I could need some help testing, since my last attempt
actually broke things even more...
First, it introduces a new option decchannels, since using the channels
for specifying both number of in- and output channels creates problems
with -af hrtf, -af pan etc.
With -channels 0 you can now e.g. let MPlayer automatically select the
number of channels, as the default is still 2 (also for decchannels).
It also removes some code duplication by doing preinit by calling init.
I guess the man page part could really be improved...

Greetings,
Reimar Döffinger
-------------- next part --------------
Index: cfg-common.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-common.h,v
retrieving revision 1.145
diff -u -r1.145 cfg-common.h
--- cfg-common.h	13 May 2005 14:45:28 -0000	1.145
+++ cfg-common.h	9 Jun 2005 19:15:40 -0000
@@ -142,7 +142,8 @@
 	// force video/audio rate:
 	{"fps", &force_fps, CONF_TYPE_FLOAT, CONF_MIN, 0, 0, NULL},
 	{"srate", &force_srate, CONF_TYPE_INT, CONF_RANGE, 1000, 8*48000, NULL},
-	{"channels", &audio_output_channels, CONF_TYPE_INT, CONF_RANGE, 1, 6, NULL},
+	{"channels", &audio_output_channels, CONF_TYPE_INT, CONF_RANGE, 0, 6, NULL},
+	{"decchannels", &audio_decode_channels, CONF_TYPE_INT, CONF_RANGE, 0, 6, NULL},
 	{"format", &audio_output_format, CONF_TYPE_AFMT, 0, 0, 0, NULL},
 	{"speed", &playback_speed, CONF_TYPE_FLOAT, CONF_RANGE, 0.01, 100.0, NULL},
 
@@ -308,6 +309,7 @@
 
 /* from dec_audio, currently used for ac3surround decoder only */
 extern int audio_output_channels;
+extern int audio_decode_channels;
 
 #ifdef MPLAYER_NETWORK
 /* defined in network.c */
Index: mencoder.c
===================================================================
RCS file: /cvsroot/mplayer/main/mencoder.c,v
retrieving revision 1.288
diff -u -r1.288 mencoder.c
--- mencoder.c	1 Jun 2005 09:01:41 -0000	1.288
+++ mencoder.c	9 Jun 2005 19:16:12 -0000
@@ -819,9 +819,9 @@
 
 mux_a->codec=out_audio_codec;
 
-ao_data.samplerate = force_srate ? force_srate : new_srate;
-ao_data.channels = audio_output_channels ? audio_output_channels : sh_audio->channels;
-ao_data.format = audio_output_format ? audio_output_format : sh_audio->sample_format;
+ao_data.samplerate = force_srate;
+ao_data.channels = audio_output_channels;
+ao_data.format = audio_output_format;
 if(!preinit_audio_filters(sh_audio,
    // input:
    new_srate,
@@ -833,7 +833,7 @@
    }
 
 aparams.channels = ao_data.channels;
-aparams.sample_rate = force_srate ? force_srate : ao_data.samplerate;
+aparams.sample_rate = ao_data.samplerate;
 aparams.audio_preload = 1000 * audio_preload;
 if(mux_a->codec != ACODEC_COPY) {
     aencoder = new_audio_encoder(mux_a, &aparams);
@@ -841,7 +841,7 @@
         mencoder_exit(1, NULL);
     if(!init_audio_filters(sh_audio, 
         new_srate, sh_audio->channels, sh_audio->sample_format,  
-        aparams.sample_rate, aparams.channels, aencoder->input_format, 
+        &aparams.sample_rate, &aparams.channels, &aencoder->input_format, 
         aencoder->min_buffer_size, aencoder->max_buffer_size)) {
       mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_NoMatchingFilter);
       mencoder_exit(1,NULL);
@@ -951,9 +951,9 @@
 	    new_srate,
 	    sh_audio->channels,
 	    sh_audio->sample_format,
-	    mux_a->wf->nSamplesPerSec,
-	    mux_a->wf->nChannels,
-	    out_format,
+	    &mux_a->wf->nSamplesPerSec,
+	    &mux_a->wf->nChannels,
+	    &out_format,
 	    out_minsize,
 	    out_maxsize))
 	{
Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.847
diff -u -r1.847 mplayer.c
--- mplayer.c	1 Jun 2005 09:01:41 -0000	1.847
+++ mplayer.c	9 Jun 2005 19:16:28 -0000
@@ -955,7 +955,7 @@
   }
   result =  init_audio_filters(sh_audio, new_srate,
            sh_audio->channels, sh_audio->sample_format,
-           ao_data->samplerate, ao_data->channels, ao_data->format,
+           &ao_data->samplerate, &ao_data->channels, &ao_data->format,
            ao_data->outburst * 4, ao_data->buffersize);
   mixer.afilter = sh_audio->afilter;
 #ifdef HAVE_NEW_GUI
@@ -2129,10 +2129,11 @@
 if(sh_audio){
   //const ao_info_t *info=audio_out->info;
   current_module="af_preinit";
-  ao_data.samplerate=force_srate?force_srate:sh_audio->samplerate*playback_speed;
-  ao_data.channels=audio_output_channels?audio_output_channels:sh_audio->channels;
-  ao_data.format=audio_output_format?audio_output_format:sh_audio->sample_format;
+  ao_data.samplerate=force_srate;
+  ao_data.channels=audio_output_channels;
+  ao_data.format=audio_output_format;
 #if 1
+  // first init to detect best values
   if(!preinit_audio_filters(sh_audio,
         // input:
         (int)(sh_audio->samplerate*playback_speed),
Index: DOCS/man/en/mplayer.1
===================================================================
RCS file: /cvsroot/mplayer/main/DOCS/man/en/mplayer.1,v
retrieving revision 1.1003
diff -u -r1.1003 mplayer.1
--- DOCS/man/en/mplayer.1	8 Jun 2005 20:37:35 -0000	1.1003
+++ DOCS/man/en/mplayer.1	9 Jun 2005 19:17:05 -0000
@@ -847,6 +847,17 @@
 Specify the CD-ROM device (default: /dev/\:cdrom).
 .
 .TP
+.B \-decchannels <number>
+Change the number of decoding channels (default: 2).
+MPlayer asks the decoder to decode the audio into as many channels as
+specified.
+If the number of output channels is smaller than the number of input channels,
+results depend on the audio decoder (\-afm).
+This is usually only important when playing videos with AC3 audio (like DVDs).
+In that case liba52 does the decoding by default and correctly downmixes the
+audio into the requested number of channels.
+.
+.TP
 .B \-channels <number>
 Change the number of playback channels (default: 2).
 If the number of output channels is bigger than the number of input channels
@@ -854,16 +865,6 @@
 mixing from mono to stereo, then the mono channel is repeated in both
 output channels).
 The routing will be the default routing for the channels filter.
-If the number of output channels is smaller than the number of input channels,
-results depend on the audio decoder (\-afm).
-MPlayer asks the decoder to decode the audio into as many channels as
-specified.
-Now it's up to the decoder to fulfill the requirement.
-If the decoder outputs more channels than requested, the exceeding channels
-are truncated.
-This is usually only important when playing videos with AC3 audio (like DVDs).
-In that case liba52 does the decoding by default and correctly downmixes the
-audio into the requested number of channels.
 .br
 .I NOTE:
 This option is honored by codecs (AC3 only), filters (surround) and audio
Index: libaf/af.c
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af.c,v
retrieving revision 1.45
diff -u -r1.45 af.c
--- libaf/af.c	1 May 2005 09:23:31 -0000	1.45
+++ libaf/af.c	9 Jun 2005 19:17:16 -0000
@@ -329,12 +329,11 @@
    and output should contain the format of the current movie and the
    formate of the preferred output respectively. The function is
    reentrant i.e. if called with an already initialized stream the
-   stream will be reinitialized. If the binary parameter
-   "force_output" is set, the output format will be converted to the
-   format given in "s", otherwise the output fromat in the last filter
-   will be copied "s". The return value is 0 if success and -1 if
-   failure */
-int af_init(af_stream_t* s, int force_output)
+   stream will be reinitialized.
+   If one of the prefered output parameters is 0 the one that needs
+   no conversion is used (i.e. the output format in the last filter).
+   The return value is 0 if success and -1 if failure */
+int af_init(af_stream_t* s)
 {
   int i=0;
 
@@ -373,17 +372,11 @@
     if (!af_append(s,s->first,"dummy") || AF_OK != af_reinit(s,s->first))
       return -1;
 
-  // If force_output isn't set do not compensate for output format
-  if(!force_output){
-    memcpy(&s->output, s->last->data, sizeof(af_data_t));
-    return 0;
-  }
-
   // Check output format
   if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){
     af_instance_t* af = NULL; // New filter
     // Check output frequency if not OK fix with resample
-    if(s->last->data->rate!=s->output.rate){
+    if(s->output.rate && s->last->data->rate!=s->output.rate){
       // try to find a filter that can change samplrate
       af = af_control_any_rev(s, AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET,
                &(s->output.rate));
@@ -428,7 +421,7 @@
       
     // Check number of output channels fix if not OK
     // If needed always inserted last -> easy to screw up other filters
-    if(s->last->data->nch!=s->output.nch){
+    if(s->output.nch && s->last->data->nch!=s->output.nch){
       if(!strcmp(s->last->info->name,"format"))
 	af = af_prepend(s,s->last,"channels");
       else
@@ -441,7 +434,7 @@
     }
     
     // Check output format fix if not OK
-    if(s->last->data->format != s->output.format){
+    if(s->output.format && s->last->data->format != s->output.format){
       if(strcmp(s->last->info->name,"format"))
 	af = af_append(s,s->last,"format");
       else
@@ -458,6 +451,9 @@
     if(AF_OK != af_reinit(s,s->first))
       return -1;
 
+    if (!s->output.format) s->output.format = s->last->data->format;
+    if (!s->output.nch) s->output.nch = s->last->data->nch;
+    if (!s->output.rate) s->output.rate = s->last->data->rate;
     if((s->last->data->format != s->output.format) || 
        (s->last->data->nch    != s->output.nch)    || 
        (s->last->data->rate   != s->output.rate))  {
Index: libaf/af.h
===================================================================
RCS file: /cvsroot/mplayer/main/libaf/af.h,v
retrieving revision 1.26
diff -u -r1.26 af.h
--- libaf/af.h	1 Mar 2005 22:52:02 -0000	1.26
+++ libaf/af.h	9 Jun 2005 19:17:18 -0000
@@ -134,7 +134,7 @@
    format given in "s", otherwise the output fromat in the last filter
    will be copied "s". The return value is 0 if success and -1 if
    failure */
-int af_init(af_stream_t* s, int force_output);
+int af_init(af_stream_t* s);
 
 // Uninit and remove all filters
 void af_uninit(af_stream_t* s);
Index: libmpcodecs/ad_dmo.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ad_dmo.c,v
retrieving revision 1.4
diff -u -r1.4 ad_dmo.c
--- libmpcodecs/ad_dmo.c	23 May 2005 16:17:40 -0000	1.4
+++ libmpcodecs/ad_dmo.c	9 Jun 2005 19:17:57 -0000
@@ -28,13 +28,13 @@
   return 1;
 }
 
-extern int audio_output_channels;
+extern int audio_decode_channels;
 
 static int preinit(sh_audio_t *sh_audio)
 {
   DMO_AudioDecoder* ds_adec;
-  int chans=(audio_output_channels==sh_audio->wf->nChannels) ?
-      audio_output_channels : (sh_audio->wf->nChannels>=2 ? 2 : 1);
+  int chans=(audio_decode_channels==sh_audio->wf->nChannels) ?
+      audio_decode_channels : (sh_audio->wf->nChannels>=2 ? 2 : 1);
   if(!(ds_adec=DMO_AudioDecoder_Open(sh_audio->codec->dll,&sh_audio->codec->guid,sh_audio->wf,chans)))
   {
     mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_MissingDLLcodec,sh_audio->codec->dll);
Index: libmpcodecs/ad_faad.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ad_faad.c,v
retrieving revision 1.18
diff -u -r1.18 ad_faad.c
--- libmpcodecs/ad_faad.c	29 Mar 2005 17:59:08 -0000	1.18
+++ libmpcodecs/ad_faad.c	9 Jun 2005 19:17:58 -0000
@@ -66,7 +66,7 @@
   return pos;
 }
 	
-extern int audio_output_channels;
+extern int audio_decode_channels;
 static int init(sh_audio_t *sh)
 {
   unsigned long faac_samplerate;
@@ -91,7 +91,7 @@
     /* XXX: FAAD support FLOAT output, how do we handle
       * that (FAAD_FMT_FLOAT)? ::atmos
       */
-    if (audio_output_channels <= 2) faac_conf->downMatrix = 1;
+    if (audio_decode_channels <= 2) faac_conf->downMatrix = 1;
       switch(sh->samplesize){
 	case 1: // 8Bit
 	  mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: 8Bit samplesize not supported by FAAD, assuming 16Bit!\n");
@@ -132,7 +132,7 @@
 
   } else { // We have ES DS in codecdata
     faacDecConfigurationPtr faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
-    if (audio_output_channels <= 2) {
+    if (audio_decode_channels <= 2) {
         faac_conf->downMatrix = 1;
         faacDecSetConfiguration(faac_hdec, faac_conf);
     }
@@ -153,7 +153,7 @@
     mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
     mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %dHz  channels: %d\n", faac_samplerate, faac_channels);
     sh->channels = faac_channels;
-    if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
+    if (audio_decode_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
     sh->samplerate = faac_samplerate;
     sh->samplesize=2;
     //sh->o_bps = sh->samplesize*faac_channels*faac_samplerate;
Index: libmpcodecs/ad_liba52.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/ad_liba52.c,v
retrieving revision 1.18
diff -u -r1.18 ad_liba52.c
--- libmpcodecs/ad_liba52.c	24 May 2005 06:58:55 -0000	1.18
+++ libmpcodecs/ad_liba52.c	9 Jun 2005 19:18:00 -0000
@@ -52,7 +52,7 @@
 
 LIBAD_EXTERN(liba52)
 
-extern int audio_output_channels;
+extern int audio_decode_channels;
 
 int a52_fillbuff(sh_audio_t *sh_audio){
 int length=0;
@@ -127,7 +127,7 @@
   /* Dolby AC3 audio: */
   /* however many channels, 2 bytes in a word, 256 samples in a block, 6 blocks in a frame */
   if (sh->samplesize < 2) sh->samplesize = 2;
-  sh->audio_out_minsize=audio_output_channels*sh->samplesize*256*6;
+  sh->audio_out_minsize=audio_decode_channels*sh->samplesize*256*6;
   sh->audio_in_minsize=3840;
   a52_level = 1.0;
   return 1;
@@ -195,7 +195,7 @@
 
   /* 'a52 cannot upmix' hotfix:*/
   a52_printinfo(sh_audio);
-  sh_audio->channels=audio_output_channels;
+  sh_audio->channels=audio_decode_channels;
 while(sh_audio->channels>0){
   switch(sh_audio->channels){
 	    case 1: a52_flags=A52_MONO; break;
Index: libmpcodecs/dec_audio.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/dec_audio.c,v
retrieving revision 1.39
diff -u -r1.39 dec_audio.c
--- libmpcodecs/dec_audio.c	25 Feb 2005 11:17:43 -0000	1.39
+++ libmpcodecs/dec_audio.c	9 Jun 2005 19:18:02 -0000
@@ -27,6 +27,7 @@
 #endif
 /* used for ac3surround decoder - set using -channels option */
 int audio_output_channels = 2;
+int audio_decode_channels = 2;
 af_cfg_t af_cfg; // Configuration for audio filters
 
 void afm_help(){
@@ -258,6 +259,7 @@
     }
     if(sh_audio->a_out_buffer!=sh_audio->a_buffer) free(sh_audio->a_out_buffer);
     sh_audio->a_out_buffer=NULL;
+    sh_audio->a_out_buffer_size=0;
     if(sh_audio->a_buffer) free(sh_audio->a_buffer);
     sh_audio->a_buffer=NULL;
     if(sh_audio->a_in_buffer) free(sh_audio->a_in_buffer);
@@ -268,50 +270,14 @@
 int preinit_audio_filters(sh_audio_t *sh_audio, 
 	int in_samplerate, int in_channels, int in_format,
 	int* out_samplerate, int* out_channels, int* out_format){
-  af_stream_t* afs=malloc(sizeof(af_stream_t));
-  memset(afs,0,sizeof(af_stream_t));
-
-  // input format: same as codec's output format:
-  afs->input.rate   = in_samplerate;
-  afs->input.nch    = in_channels;
-  afs->input.format = in_format;
-  af_fix_parameters(&(afs->input));
-
-  // output format: same as ao driver's input format (if missing, fallback to input)
-  afs->output.rate   = *out_samplerate ? *out_samplerate : afs->input.rate;
-  afs->output.nch    = *out_channels ? *out_channels : afs->input.nch;
-  afs->output.format = *out_format ? *out_format : afs->input.format;
-  af_fix_parameters(&(afs->output));
-
-  // filter config:  
-  memcpy(&afs->cfg,&af_cfg,sizeof(af_cfg_t));
-  
-  mp_msg(MSGT_DECAUDIO, MSGL_INFO, "Checking audio filter chain for %dHz/%dch/%s -> %dHz/%dch/%s...\n",
-      afs->input.rate,afs->input.nch,af_fmt2str_short(afs->input.format),
-      afs->output.rate,afs->output.nch,af_fmt2str_short(afs->output.format));
-  
-  // let's autoprobe it!
-  if(0 != af_init(afs,0)){
-    free(afs);
-    return 0; // failed :(
-  }
-  
-  *out_samplerate=afs->output.rate;
-  *out_channels=afs->output.nch;
-  *out_format=afs->output.format;
-
-  mp_msg(MSGT_DECAUDIO, MSGL_INFO, "AF_pre: %dHz/%dch/%s\n",
-      afs->output.rate, afs->output.nch,
-      af_fmt2str_short(afs->output.format));
-  
-  sh_audio->afilter=(void*)afs;
-  return 1;
+  init_audio_filters(sh_audio, in_samplerate, in_channels, in_format,
+      out_samplerate, out_channels, out_format, 0, 0);
 }
 
  /* Init audio filters */
 int init_audio_filters(sh_audio_t *sh_audio, 
 	int in_samplerate, int in_channels, int in_format,
-	int out_samplerate, int out_channels, int out_format,
+	int *out_samplerate, int *out_channels, int *out_format,
 	int out_minsize, int out_maxsize){
   af_stream_t* afs=sh_audio->afilter;
   if(!afs){
@@ -326,9 +292,9 @@
   af_fix_parameters(&(afs->input));
 
   // output format: same as ao driver's input format (if missing, fallback to input)
-  afs->output.rate   = out_samplerate ? out_samplerate : afs->input.rate;
-  afs->output.nch    = out_channels ? out_channels : afs->input.nch;
-  afs->output.format = out_format ? out_format : afs->input.format;
+  afs->output.rate   = *out_samplerate;
+  afs->output.nch    = *out_channels;
+  afs->output.format = *out_format;
   af_fix_parameters(&(afs->output));
 
   // filter config:  
@@ -339,12 +305,17 @@
       afs->output.rate,afs->output.nch,af_fmt2str_short(afs->output.format));
   
   // let's autoprobe it!
-  if(0 != af_init(afs,1)){
+  if(0 != af_init(afs)){
     sh_audio->afilter=NULL;
     free(afs);
     return 0; // failed :(
   }
+
+  *out_samplerate=afs->output.rate;
+  *out_channels=afs->output.nch;
+  *out_format=afs->output.format;
   
+  if (out_maxsize || out_minsize) {
   // allocate the a_out_* buffers:
   if(out_maxsize<out_minsize) out_maxsize=out_minsize;
   if(out_maxsize<8192) out_maxsize=MAX_OUTBURST; // not sure this is ok
@@ -353,6 +324,7 @@
   sh_audio->a_out_buffer=malloc(sh_audio->a_out_buffer_size);
   memset(sh_audio->a_out_buffer,0,sh_audio->a_out_buffer_size);
   sh_audio->a_out_buffer_len=0;
+  }
   
   // ok!
   sh_audio->afilter=(void*)afs;
Index: libmpcodecs/dec_audio.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/dec_audio.h,v
retrieving revision 1.9
diff -u -r1.9 dec_audio.h
--- libmpcodecs/dec_audio.h	25 Feb 2005 11:11:07 -0000	1.9
+++ libmpcodecs/dec_audio.h	9 Jun 2005 19:18:02 -0000
@@ -12,7 +12,7 @@
 
 extern int init_audio_filters(sh_audio_t *sh_audio, 
 	int in_samplerate, int in_channels, int in_format,
-	int out_samplerate, int out_channels, int out_format,
+	int *out_samplerate, int *out_channels, int *out_format,
 	int out_minsize, int out_maxsize);
 extern int preinit_audio_filters(sh_audio_t *sh_audio,
         int in_samplerate, int in_channels, int in_format,


More information about the MPlayer-dev-eng mailing list