Hey folks,

I've been tacking this bug with mr_spuck on IRC, here come the result of
the bug tracking ;)

I was merging using avimerge (1.03) an XVid with an AC3 track
([EMAIL PROTECTED]/sec). Once the merged was finished, I looked at the
informations of the generated avi.

The "file" command said it was an AC3 with 3channels. I was very
suprised because the AC3 track is 5.1.

After a while and reading the spec from
http://www.atsc.org/standards/a_52b.pdf I found there is a
mis-alignement of data making the code reading the wrong value.

So I fixed two things in the attached patch:

- get_ac3_nfchans now receive in parameter the first byte of the BSI.
This make the code easiest to read because we must take informations
from the 3 msb bits of the 2nd char. It now return the "right" value.

- Then I added the reading the state of the LFE. As said in the spec : 
"The total number of channels, nchans, is equal to nfchans if the lfe
channel is off, and is equal to 1 + nfchans if the lfe channel is on."

So using the patch I'm joining to this mail, the number of channels
available in the generated avi is now correctly set. I tried on many
files, the resultat looks good for me.

I hope this patch could be integrated in transcode. If you have some
questions, let me know.

Erwan,
--- tools/aud_scan.c.old	2005-07-04 09:23:03.000000000 +0200
+++ tools/aud_scan.c	2007-05-06 23:17:02.000000000 +0200
@@ -214,18 +214,26 @@
   return(frmsizecod_tbl[frmsizecod].frm_size[fscod]);
 }
 
-// tibit
+// We try to find the number of chans in the ac3 header (BSI)
 int get_ac3_nfchans(unsigned char *buf) 
 {
   int acmod = 0;
 
-  // skip syncinfo (size = 5bytes);
-  // skip to acmod
-  acmod = buf[6]>>5;
+  /* lfe is off */
+  int lfe = 0;
+
+  /* acmod is located on the 3 msb of the second char of the BSI */
+  acmod = buf[1]>>5;
+  
+  /* LFE is the 2nd msb bit (0x40) of the 3rd char of the BSI */
+  if ((buf[2] & 0x40) == 0x40) {
+  	  /* LFE flags is on, we have one more channel */
+	  lfe=1;
+  }
 
   if (acmod < 0 || acmod > 11) return -1;
 
-  return(nfchans[acmod]);
+  return(nfchans[acmod]+lfe);
 }
 
 
@@ -285,13 +293,15 @@
       sync_word = (sync_word << 8) + (uint8_t) buffer[i]; 
       if(sync_word == 0x0b77) break;
   }
-    
   if(sync_word != 0x0b77) return(-1);
 
   if (srate) *srate = get_ac3_samplerate(&buffer[i+1]);
   if (bitrate) *bitrate = get_ac3_bitrate(&buffer[i+1]);  
-  nfchans = get_ac3_nfchans(&buffer[i+1]);
+
+  /* We give the first byte of the BSI to get_ac3_nfchans*/
+  nfchans = get_ac3_nfchans(&buffer[i+4]);
   if (chans) *chans = nfchans;
+
   fsize = 2*get_ac3_framesize(&buffer[i+1]);
   
   if(j<0 || bitrate <0) return(-1);

Reply via email to