[MPlayer-dev-eng] [PATCH] liba52 problems with 2-ch vob, 6-ch output

eric at lammerts.org eric at lammerts.org
Thu Dec 27 03:30:04 CET 2001


Hello,
I was trying out the new liba52 with some vobs (with -channels 6).
It works great with vobs that have 5+1 channels.

The problem:
Some of the vobs have ac3 sound with only 2 channels (A52_DOLBY format).
Liba52 does not "upmix" the output to 5+1 channels, so this causes a lot of
garbage in the sound output (this is described in liba52.txt).

Patch below adjusts the number of output channels if the ac3 input has less
channels than the user-specified number of channels. It's against the latest
CVS. With this my vobs play perfectly.

By the way, my soundcard is a Cmedia 8738-6ch-LX (only $12 :-)), which works
great with 2, 4 or 6 channels (using the oss driver of Linux 2.4.x). Maybe
you could add this to the soundcard list.

cheers,
Eric

Index: dec_audio.c
===================================================================
RCS file: /cvsroot/mplayer/main/dec_audio.c,v
retrieving revision 1.59
diff -u -r1.59 dec_audio.c
--- dec_audio.c	26 Dec 2001 06:13:17 -0000	1.59
+++ dec_audio.c	27 Dec 2001 02:31:36 -0000
@@ -131,7 +131,7 @@
 #endif
 
 
-static int a52_fillbuff(sh_audio_t *sh_audio){
+static int a52_fillbuff(sh_audio_t *sh_audio, int channel_init){
 int length=0;
 int flags=0;
 int sample_rate=0;
@@ -156,6 +156,38 @@
     }
     sh_audio->samplerate=sample_rate;
     sh_audio->i_bps=bit_rate/8;
+
+    if(channel_init) {
+	int channels = 0;
+
+	/* treat the mono cases like stereo because liba52 will always
+	   provide >=2 channels */
+	switch(flags & A52_CHANNEL_MASK) {
+	    case A52_MONO:
+	    case A52_CHANNEL1:
+	    case A52_CHANNEL2:
+	    case A52_CHANNEL:
+	    case A52_STEREO:
+	    case A52_DOLBY:
+	    	channels = 2; break;
+	    case A52_3F:
+	    case A52_2F1R:
+	    	channels = 3; break;
+	    case A52_3F1R:
+	    case A52_2F2R:
+	    	channels = 4; break;
+	    case A52_3F2R:
+	    	channels = 5; break;
+	}
+	if(sh_audio->channels == 6 && (flags & A52_LFE)) channels++;
+
+	if(channels < sh_audio->channels) {
+	    mp_msg(MSGT_DECAUDIO,MSGL_STATUS,"a52: channels changed from %d to %d\n",
+    		sh_audio->channels, channels);
+    	    sh_audio->channels = channels;
+    	}
+    }
+
     demux_read_data(sh_audio->ds,sh_audio->a_in_buffer+7,length-7);
     return length;
 }
@@ -409,11 +441,11 @@
    sh_audio->a_in_buffer_size=3840;
    sh_audio->a_in_buffer=malloc(sh_audio->a_in_buffer_size);
    sh_audio->a_in_buffer_len=0;
-  if(a52_fillbuff(sh_audio)<0){
+  sh_audio->channels = audio_output_channels;
+  if(a52_fillbuff(sh_audio,1)<0){
 	mp_msg(MSGT_DECAUDIO,MSGL_ERR,"A52 sync failed\n");
 	driver=0;break;
   }
-  sh_audio->channels=audio_output_channels;
   break;
 }
 case AFM_HWAC3: {
@@ -933,7 +965,7 @@
 	int i;
 	sample_t level=1, bias=384;
         if(!sh_audio->a_in_buffer_len) 
-	    if(a52_fillbuff(sh_audio)<0) break; // EOF
+	    if(a52_fillbuff(sh_audio, 0)<0) break; // EOF
 	switch(sh_audio->channels){
 	    case 1: flags=A52_MONO; break;
 //	    case 2: flags=A52_STEREO; break;
@@ -1088,7 +1120,7 @@
               switch(sh_audio->codec->driver){
                 case AFM_MPEG: MP3_DecodeFrame(NULL,-2);break; // skip MPEG frame
                 case AFM_AC3: sh_audio->ac3_frame=ac3_decode_frame();break; // skip AC3 frame
-                case AFM_A52: a52_fillbuff(sh_audio);break; // skip AC3 frame
+                case AFM_A52: a52_fillbuff(sh_audio, 0);break; // skip AC3 frame
 		case AFM_ACM:
 		case AFM_DSHOW: {
 		    int skip=sh_audio->wf->nBlockAlign;



More information about the MPlayer-dev-eng mailing list