]> git.sesse.net Git - vlc/blobdiff - src/ac3_decoder/ac3_parse.c
* Totally rewrote the video decoder (inspired by walken's mpeg2dec), implying :
[vlc] / src / ac3_decoder / ac3_parse.c
index e55c3b3e6de2bf121be27e224901a012cc25f090..e6d1c06d13569dbee2085790bbe5f3c801adf5e3 100644 (file)
@@ -1,40 +1,66 @@
 /*****************************************************************************
  * ac3_parse.c: ac3 parsing procedures
  *****************************************************************************
- * Copyright (C) 1999, 2000 VideoLAN
+ * Copyright (C) 1999, 2000, 2001 VideoLAN
+ * $Id: ac3_parse.c,v 1.24 2001/08/22 17:21:45 massiot Exp $
  *
- * Authors:
+ * Authors: Michel Kaempf <maxx@via.ecp.fr>
+ *          Aaron Holtzman <aholtzma@engr.uvic.ca>
+ *          Renaud Dartus <reno@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- *
+ * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
  *****************************************************************************/
+#include "defs.h"
+
+#include <string.h>                                              /* memset() */
+
+#include "config.h"
+#include "common.h"
+
+#include "threads.h"
+#include "mtime.h"
+
+#include "intf_msg.h"
 
-#include "int_types.h"
+#include "stream_control.h"
+#include "input_ext-dec.h"
+
+#include "audio_output.h"
+
+#include "ac3_imdct.h"
+#include "ac3_downmix.h"
 #include "ac3_decoder.h"
-#include "ac3_internal.h"
-#include "ac3_bit_stream.h"
+#include "ac3_decoder_thread.h"                           /* ac3dec_thread_t */
+
+#include "ac3_internal.h"                                       /* EXP_REUSE */
 
 /* Misc LUT */
-static u16 nfchans[] = { 2, 1, 2, 3, 3, 4, 4, 5 };
+static const u16 nfchans[] = { 2, 1, 2, 3, 3, 4, 4, 5 };
 
-struct frmsize_s {
+struct frmsize_s
+{
     u16 bit_rate;
     u16 frm_size[3];
 };
 
-static struct frmsize_s frmsizecod_tbl[] = {
+static const struct frmsize_s frmsizecod_tbl[] =
+{
       { 32  ,{64   ,69   ,96   } },
       { 32  ,{64   ,70   ,96   } },
       { 40  ,{80   ,87   ,120  } },
@@ -74,42 +100,54 @@ static struct frmsize_s frmsizecod_tbl[] = {
       { 640 ,{1280 ,1393 ,1920 } },
       { 640 ,{1280 ,1394 ,1920 } }};
 
-static int fscod_tbl[] = {48000, 44100, 32000};
+static const int fscod_tbl[] = {48000, 44100, 32000};
+
+/* Some internal functions */
+#ifdef TRACE
+static void parse_bsi_stats (ac3dec_t * p_ac3dec);
+static void parse_audblk_stats (ac3dec_t * p_ac3dec);
+#endif
 
 /* Parse a syncinfo structure */
 int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info) 
 {
-    int buf;
-
-    p_ac3dec->bit_stream.total_bits_read = 0;
-    p_ac3dec->bit_stream.i_available = 0;
-
+    ac3dec_thread_t * p_ac3dec_t = (ac3dec_thread_t *) p_ac3dec->bit_stream.p_callback_arg;
+    
+    p_ac3dec->total_bits_read = 0;
+    p_ac3dec->i_available = 0;
+    
     /* sync word - should be 0x0b77 */
-    NeedBits (&(p_ac3dec->bit_stream), 16);
-    buf =  p_ac3dec->bit_stream.buffer >> (32 - 16);
-    DumpBits (&(p_ac3dec->bit_stream), 16);
-    if (buf != 0x0b77)
-       return 1;
+    RealignBits(&p_ac3dec->bit_stream);
+    while( (ShowBits (&p_ac3dec->bit_stream,16)) != 0x0b77 && 
+            (!p_ac3dec_t->p_fifo->b_die) && (!p_ac3dec_t->p_fifo->b_error))
+    {
+        RemoveBits (&p_ac3dec->bit_stream,8);
+        p_ac3dec->total_bits_read += 8;
+    }
+    RemoveBits (&p_ac3dec->bit_stream,16);
+    p_ac3dec->total_bits_read += 16;
 
+    
     /* Get crc1 - we don't actually use this data though */
-    NeedBits (&(p_ac3dec->bit_stream), 16);
-    DumpBits (&(p_ac3dec->bit_stream), 16);
+    GetBits (&p_ac3dec->bit_stream,16);
 
     /* Get the sampling rate */
-    NeedBits (&(p_ac3dec->bit_stream), 2);
-    p_ac3dec->syncinfo.fscod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-    DumpBits (&(p_ac3dec->bit_stream), 2);
+    p_ac3dec->syncinfo.fscod = GetBits (&p_ac3dec->bit_stream,2);
 
     if (p_ac3dec->syncinfo.fscod >= 3)
-       return 1;
+    {
+        p_ac3dec->total_bits_read += 34;
+        return 1;
+    }
 
     /* Get the frame size code */
-    NeedBits (&(p_ac3dec->bit_stream), 6);
-    p_ac3dec->syncinfo.frmsizecod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 6));
-    DumpBits (&(p_ac3dec->bit_stream), 6);
+    p_ac3dec->syncinfo.frmsizecod = GetBits (&p_ac3dec->bit_stream,6);
+    p_ac3dec->total_bits_read += 40;
 
     if (p_ac3dec->syncinfo.frmsizecod >= 38)
-       return 1;
+    {
+        return 1;
+    }
 
     p_sync_info->bit_rate = frmsizecod_tbl[p_ac3dec->syncinfo.frmsizecod].bit_rate;
 
@@ -126,194 +164,153 @@ int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info)
  */
 int parse_bsi (ac3dec_t * p_ac3dec)
 {
-    u32 i;
-
     /* Check the AC-3 version number */
-    NeedBits (&(p_ac3dec->bit_stream), 5);
-    p_ac3dec->bsi.bsid = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 5));
-    DumpBits (&(p_ac3dec->bit_stream), 5);
+    p_ac3dec->bsi.bsid = GetBits (&p_ac3dec->bit_stream,5);
 
     if (p_ac3dec->bsi.bsid > 8)
-       return 1;
+    {
+        return 1;
+    }
 
-    /* Get the audio service provided by the steram */
-    NeedBits (&(p_ac3dec->bit_stream), 3);
-    p_ac3dec->bsi.bsmod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-    DumpBits (&(p_ac3dec->bit_stream), 3);
+    /* Get the audio service provided by the stream */
+    p_ac3dec->bsi.bsmod = GetBits (&p_ac3dec->bit_stream,3);
 
     /* Get the audio coding mode (ie how many channels)*/
-    NeedBits (&(p_ac3dec->bit_stream), 3);
-    p_ac3dec->bsi.acmod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-    DumpBits (&(p_ac3dec->bit_stream), 3);
+    p_ac3dec->bsi.acmod = GetBits (&p_ac3dec->bit_stream,3);
+    
     /* Predecode the number of full bandwidth channels as we use this
      * number a lot */
     p_ac3dec->bsi.nfchans = nfchans[p_ac3dec->bsi.acmod];
 
     /* If it is in use, get the centre channel mix level */
-    if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1)) {
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->bsi.cmixlev = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
+    if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
+    {
+        p_ac3dec->bsi.cmixlev = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->total_bits_read += 2;
     }
 
     /* If it is in use, get the surround channel mix level */
-    if (p_ac3dec->bsi.acmod & 0x4) {
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->bsi.surmixlev = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
+    if (p_ac3dec->bsi.acmod & 0x4)
+    {
+        p_ac3dec->bsi.surmixlev = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->total_bits_read += 2;
     }
 
     /* Get the dolby surround mode if in 2/0 mode */
-    if (p_ac3dec->bsi.acmod == 0x2) {
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->bsi.dsurmod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
+    if (p_ac3dec->bsi.acmod == 0x2)
+    {
+        p_ac3dec->bsi.dsurmod = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->total_bits_read += 2;
     }
 
     /* Is the low frequency effects channel on? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.lfeon = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    p_ac3dec->bsi.lfeon = GetBits (&p_ac3dec->bit_stream,1);
 
     /* Get the dialogue normalization level */
-    NeedBits (&(p_ac3dec->bit_stream), 5);
-    p_ac3dec->bsi.dialnorm = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 5));
-    DumpBits (&(p_ac3dec->bit_stream), 5);
+    p_ac3dec->bsi.dialnorm = GetBits (&p_ac3dec->bit_stream,5);
 
     /* Does compression gain exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.compre = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-    if (p_ac3dec->bsi.compre) {
+    if ((p_ac3dec->bsi.compre = GetBits (&p_ac3dec->bit_stream,1)))
+    {
         /* Get compression gain */
-        NeedBits (&(p_ac3dec->bit_stream), 8);
-        p_ac3dec->bsi.compr = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 8));
-        DumpBits (&(p_ac3dec->bit_stream), 8);
+        p_ac3dec->bsi.compr = GetBits (&p_ac3dec->bit_stream,8);
+        p_ac3dec->total_bits_read += 8;
     }
 
     /* Does language code exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.langcode = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-    if (p_ac3dec->bsi.langcode) {
+    if ((p_ac3dec->bsi.langcode = GetBits (&p_ac3dec->bit_stream,1)))
+    {
         /* Get langauge code */
-        NeedBits (&(p_ac3dec->bit_stream), 8);
-        p_ac3dec->bsi.langcod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 8));
-        DumpBits (&(p_ac3dec->bit_stream), 8);
+        p_ac3dec->bsi.langcod = GetBits (&p_ac3dec->bit_stream,8);
+        p_ac3dec->total_bits_read += 8;
     }
 
     /* Does audio production info exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.audprodie = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-    if (p_ac3dec->bsi.audprodie) {
+    if ((p_ac3dec->bsi.audprodie = GetBits (&p_ac3dec->bit_stream,1)))
+    {
         /* Get mix level */
-        NeedBits (&(p_ac3dec->bit_stream), 5);
-        p_ac3dec->bsi.mixlevel = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 5));
-        DumpBits (&(p_ac3dec->bit_stream), 5);
+        p_ac3dec->bsi.mixlevel = GetBits (&p_ac3dec->bit_stream,5);
 
         /* Get room type */
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->bsi.roomtyp = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
+        p_ac3dec->bsi.roomtyp = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->total_bits_read += 7;
     }
 
     /* If we're in dual mono mode then get some extra info */
-    if (p_ac3dec->bsi.acmod ==0) {
+    if (p_ac3dec->bsi.acmod == 0)
+    {
         /* Get the dialogue normalization level two */
-        NeedBits (&(p_ac3dec->bit_stream), 5);
-        p_ac3dec->bsi.dialnorm2 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 5));
-        DumpBits (&(p_ac3dec->bit_stream), 5);
+        p_ac3dec->bsi.dialnorm2 = GetBits (&p_ac3dec->bit_stream,5);
 
         /* Does compression gain two exist? */
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->bsi.compr2e = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
-        if (p_ac3dec->bsi.compr2e) {
+        if ((p_ac3dec->bsi.compr2e = GetBits (&p_ac3dec->bit_stream,1)))
+        {
             /* Get compression gain two */
-            NeedBits (&(p_ac3dec->bit_stream), 8);
-            p_ac3dec->bsi.compr2 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 8));
-            DumpBits (&(p_ac3dec->bit_stream), 8);
+            p_ac3dec->bsi.compr2 = GetBits (&p_ac3dec->bit_stream,8);
+            p_ac3dec->total_bits_read += 8;
         }
 
         /* Does language code two exist? */
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->bsi.langcod2e = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
-        if (p_ac3dec->bsi.langcod2e) {
+        if ((p_ac3dec->bsi.langcod2e = GetBits (&p_ac3dec->bit_stream,1)))
+        {
             /* Get langauge code two */
-            NeedBits (&(p_ac3dec->bit_stream), 8);
-            p_ac3dec->bsi.langcod2 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 8));
-            DumpBits (&(p_ac3dec->bit_stream), 8);
+            p_ac3dec->bsi.langcod2 = GetBits (&p_ac3dec->bit_stream,8);
+            p_ac3dec->total_bits_read += 8;
         }
 
         /* Does audio production info two exist? */
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->bsi.audprodi2e = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
-        if (p_ac3dec->bsi.audprodi2e) {
+        if ((p_ac3dec->bsi.audprodi2e = GetBits (&p_ac3dec->bit_stream,1)))
+        {
             /* Get mix level two */
-            NeedBits (&(p_ac3dec->bit_stream), 5);
-            p_ac3dec->bsi.mixlevel2 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 5));
-            DumpBits (&(p_ac3dec->bit_stream), 5);
+            p_ac3dec->bsi.mixlevel2 = GetBits (&p_ac3dec->bit_stream,5);
 
             /* Get room type two */
-            NeedBits (&(p_ac3dec->bit_stream), 2);
-            p_ac3dec->bsi.roomtyp2 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-            DumpBits (&(p_ac3dec->bit_stream), 2);
+            p_ac3dec->bsi.roomtyp2 = GetBits (&p_ac3dec->bit_stream,2);
+            p_ac3dec->total_bits_read += 7;
         }
+        p_ac3dec->total_bits_read += 8;
     }
 
     /* Get the copyright bit */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.copyrightb = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    p_ac3dec->bsi.copyrightb = GetBits (&p_ac3dec->bit_stream,1);
 
     /* Get the original bit */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.origbs = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    p_ac3dec->bsi.origbs = GetBits (&p_ac3dec->bit_stream,1);
 
     /* Does timecode one exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.timecod1e = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-
-    if (p_ac3dec->bsi.timecod1e) {
-        NeedBits (&(p_ac3dec->bit_stream), 14);
-        p_ac3dec->bsi.timecod1 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 14));
-        DumpBits (&(p_ac3dec->bit_stream), 14);
+    if ((p_ac3dec->bsi.timecod1e = GetBits (&p_ac3dec->bit_stream,1)))
+    {
+        p_ac3dec->bsi.timecod1 = GetBits (&p_ac3dec->bit_stream,14);
+        p_ac3dec->total_bits_read += 14;
     }
 
     /* Does timecode two exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.timecod2e = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-
-    if (p_ac3dec->bsi.timecod2e) {
-        NeedBits (&(p_ac3dec->bit_stream), 14);
-        p_ac3dec->bsi.timecod2 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 14));
-        DumpBits (&(p_ac3dec->bit_stream), 14);
+    if ((p_ac3dec->bsi.timecod2e = GetBits (&p_ac3dec->bit_stream,1)))
+    {
+        p_ac3dec->bsi.timecod2 = GetBits (&p_ac3dec->bit_stream,14);
+        p_ac3dec->total_bits_read += 14;
     }
 
     /* Does addition info exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->bsi.addbsie = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    if ((p_ac3dec->bsi.addbsie = GetBits (&p_ac3dec->bit_stream,1)))
+    {
+        u32 i;
 
-    if (p_ac3dec->bsi.addbsie) {
         /* Get how much info is there */
-        NeedBits (&(p_ac3dec->bit_stream), 6);
-        p_ac3dec->bsi.addbsil = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 6));
-        DumpBits (&(p_ac3dec->bit_stream), 6);
+        p_ac3dec->bsi.addbsil = GetBits (&p_ac3dec->bit_stream,6);
 
         /* Get the additional info */
-        for (i=0;i<(p_ac3dec->bsi.addbsil + 1);i++) {
-            NeedBits (&(p_ac3dec->bit_stream), 8);
-            p_ac3dec->bsi.addbsi[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 8));
-            DumpBits (&(p_ac3dec->bit_stream), 8);
+        for (i=0;i<(p_ac3dec->bsi.addbsil + 1);i++)
+        {
+            p_ac3dec->bsi.addbsi[i] = GetBits (&p_ac3dec->bit_stream,8);
         }
+        p_ac3dec->total_bits_read += 6 + 8 * (p_ac3dec->bsi.addbsil + 1);
     }
+    p_ac3dec->total_bits_read += 25;
+    
+#ifdef TRACE
+    parse_bsi_stats (p_ac3dec);
+#endif
 
     return 0;
 }
@@ -323,86 +320,84 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
 {
     int i, j;
 
-    for (i=0; i < p_ac3dec->bsi.nfchans; i++) {
+    for (i=0; i < p_ac3dec->bsi.nfchans; i++)
+    {
         /* Is this channel an interleaved 256 + 256 block ? */
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->audblk.blksw[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
+        p_ac3dec->audblk.blksw[i] = GetBits (&p_ac3dec->bit_stream,1);
     }
 
-    for (i=0; i < p_ac3dec->bsi.nfchans; i++) {
+    for (i=0; i < p_ac3dec->bsi.nfchans; i++)
+    {
         /* Should we dither this channel? */
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->audblk.dithflag[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
+        p_ac3dec->audblk.dithflag[i] = GetBits (&p_ac3dec->bit_stream,1);
     }
 
     /* Does dynamic range control exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->audblk.dynrnge = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-    if (p_ac3dec->audblk.dynrnge) {
+    if ((p_ac3dec->audblk.dynrnge = GetBits (&p_ac3dec->bit_stream,1)))
+    {
         /* Get dynamic range info */
-        NeedBits (&(p_ac3dec->bit_stream), 8);
-        p_ac3dec->audblk.dynrng = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 8));
-        DumpBits (&(p_ac3dec->bit_stream), 8);
+        p_ac3dec->audblk.dynrng = GetBits (&p_ac3dec->bit_stream,8);
+        p_ac3dec->total_bits_read += 8;
     }
 
     /* If we're in dual mono mode then get the second channel DR info */
-    if (p_ac3dec->bsi.acmod == 0) {
+    if (p_ac3dec->bsi.acmod == 0)
+    {
         /* Does dynamic range control two exist? */
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->audblk.dynrng2e = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
-        if (p_ac3dec->audblk.dynrng2e) {
+        if ((p_ac3dec->audblk.dynrng2e = GetBits (&p_ac3dec->bit_stream,1)))
+        {
             /* Get dynamic range info */
-            NeedBits (&(p_ac3dec->bit_stream), 8);
-            p_ac3dec->audblk.dynrng2 = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 8));
-            DumpBits (&(p_ac3dec->bit_stream), 8);
+            p_ac3dec->audblk.dynrng2 = GetBits (&p_ac3dec->bit_stream,8);
+            p_ac3dec->total_bits_read += 8;
         }
+        p_ac3dec->total_bits_read += 1;
     }
 
     /* Does coupling strategy exist? */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->audblk.cplstre = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    p_ac3dec->audblk.cplstre = GetBits (&p_ac3dec->bit_stream,1);
+    p_ac3dec->total_bits_read += 2 + 2 * p_ac3dec->bsi.nfchans;
 
     if ((!blknum) && (!p_ac3dec->audblk.cplstre))
-       return 1;
+    {
+        return 1;
+    }
 
-    if (p_ac3dec->audblk.cplstre) {
+    if (p_ac3dec->audblk.cplstre)
+    {
         /* Is coupling turned on? */
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->audblk.cplinu = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
-        if (p_ac3dec->audblk.cplinu) {
-           int nb_coupled_channels;
-
-           nb_coupled_channels = 0;
-            for (i=0; i < p_ac3dec->bsi.nfchans; i++) {
-                NeedBits (&(p_ac3dec->bit_stream), 1);
-                p_ac3dec->audblk.chincpl[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                DumpBits (&(p_ac3dec->bit_stream), 1);
-               if (p_ac3dec->audblk.chincpl[i])
-                   nb_coupled_channels++;
+        if ((p_ac3dec->audblk.cplinu = GetBits (&p_ac3dec->bit_stream,1)))
+        {
+            int nb_coupled_channels;
+
+            nb_coupled_channels = 0;
+            for (i=0; i < p_ac3dec->bsi.nfchans; i++)
+            {
+                p_ac3dec->audblk.chincpl[i] = GetBits (&p_ac3dec->bit_stream,1);
+                if (p_ac3dec->audblk.chincpl[i])
+                {
+                    nb_coupled_channels++;
+                }
+            }
+            p_ac3dec->total_bits_read += p_ac3dec->bsi.nfchans;
+            
+            if (nb_coupled_channels < 2)
+            {
+                return 1;
             }
-           if (nb_coupled_channels < 2)
-               return 1;
 
-            if (p_ac3dec->bsi.acmod == 0x2) {
-                NeedBits (&(p_ac3dec->bit_stream), 1);
-                p_ac3dec->audblk.phsflginu = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                DumpBits (&(p_ac3dec->bit_stream), 1);
+            if (p_ac3dec->bsi.acmod == 0x2)
+            {
+                p_ac3dec->audblk.phsflginu = GetBits (&p_ac3dec->bit_stream,1);
+                p_ac3dec->total_bits_read += 1;
             }
-            NeedBits (&(p_ac3dec->bit_stream), 4);
-            p_ac3dec->audblk.cplbegf = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-            DumpBits (&(p_ac3dec->bit_stream), 4);
-            NeedBits (&(p_ac3dec->bit_stream), 4);
-            p_ac3dec->audblk.cplendf = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-            DumpBits (&(p_ac3dec->bit_stream), 4);
+            p_ac3dec->audblk.cplbegf = GetBits (&p_ac3dec->bit_stream,4);
+            p_ac3dec->audblk.cplendf = GetBits (&p_ac3dec->bit_stream,4);
+            p_ac3dec->total_bits_read += 8;
 
-           if (p_ac3dec->audblk.cplbegf > p_ac3dec->audblk.cplendf + 2)
-               return 1;
+            if (p_ac3dec->audblk.cplbegf > p_ac3dec->audblk.cplendf + 2)
+            {
+                return 1;
+            }
 
             p_ac3dec->audblk.ncplsubnd = (p_ac3dec->audblk.cplendf + 2) - p_ac3dec->audblk.cplbegf + 1;
 
@@ -414,147 +409,175 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
              * band */
             p_ac3dec->audblk.ncplbnd = p_ac3dec->audblk.ncplsubnd;
 
-            for (i=1; i< p_ac3dec->audblk.ncplsubnd; i++) {
-                NeedBits (&(p_ac3dec->bit_stream), 1);
-                p_ac3dec->audblk.cplbndstrc[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                DumpBits (&(p_ac3dec->bit_stream), 1);
+            for (i=1; i< p_ac3dec->audblk.ncplsubnd; i++)
+            {
+                p_ac3dec->audblk.cplbndstrc[i] = GetBits (&p_ac3dec->bit_stream,1);
                 p_ac3dec->audblk.ncplbnd -= p_ac3dec->audblk.cplbndstrc[i];
             }
+            p_ac3dec->total_bits_read += p_ac3dec->audblk.ncplsubnd - 1;
         }
+        p_ac3dec->total_bits_read += 1;
     }
 
-    if (p_ac3dec->audblk.cplinu) {
+    if (p_ac3dec->audblk.cplinu)
+    {
         /* Loop through all the channels and get their coupling co-ords */
-        for (i=0; i < p_ac3dec->bsi.nfchans;i++) {
+        for (i=0; i < p_ac3dec->bsi.nfchans;i++)
+        {
             if (!p_ac3dec->audblk.chincpl[i])
+            {
                 continue;
+            }
 
             /* Is there new coupling co-ordinate info? */
-            NeedBits (&(p_ac3dec->bit_stream), 1);
-            p_ac3dec->audblk.cplcoe[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-            DumpBits (&(p_ac3dec->bit_stream), 1);
-
-           if ((!blknum) && (!p_ac3dec->audblk.cplcoe[i]))
-               return 1;
-
-            if (p_ac3dec->audblk.cplcoe[i]) {
-                NeedBits (&(p_ac3dec->bit_stream), 2);
-                p_ac3dec->audblk.mstrcplco[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-                DumpBits (&(p_ac3dec->bit_stream), 2);
-                for (j=0;j < p_ac3dec->audblk.ncplbnd; j++) {
-                    NeedBits (&(p_ac3dec->bit_stream), 4);
-                    p_ac3dec->audblk.cplcoexp[i][j] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-                    DumpBits (&(p_ac3dec->bit_stream), 4);
-                    NeedBits (&(p_ac3dec->bit_stream), 4);
-                    p_ac3dec->audblk.cplcomant[i][j] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-                    DumpBits (&(p_ac3dec->bit_stream), 4);
+            p_ac3dec->audblk.cplcoe[i] = GetBits (&p_ac3dec->bit_stream,1);
+
+            if ((!blknum) && (!p_ac3dec->audblk.cplcoe[i]))
+            {
+                return 1;
+            }
+
+            if (p_ac3dec->audblk.cplcoe[i])
+            {
+                p_ac3dec->audblk.mstrcplco[i] = GetBits (&p_ac3dec->bit_stream,2);
+                p_ac3dec->total_bits_read += 2;
+                for (j=0;j < p_ac3dec->audblk.ncplbnd; j++)
+                {
+                    p_ac3dec->audblk.cplcoexp[i][j] = GetBits (&p_ac3dec->bit_stream,4);
+                    p_ac3dec->audblk.cplcomant[i][j] = GetBits (&p_ac3dec->bit_stream,4);
                 }
+                p_ac3dec->total_bits_read += 8 * p_ac3dec->audblk.ncplbnd;
             }
         }
+        p_ac3dec->total_bits_read += p_ac3dec->bsi.nfchans;
 
         /* If we're in dual mono mode, there's going to be some phase info */
         if ((p_ac3dec->bsi.acmod == 0x2) && p_ac3dec->audblk.phsflginu &&
-          (p_ac3dec->audblk.cplcoe[0] || p_ac3dec->audblk.cplcoe[1])) {
-            for (j=0; j < p_ac3dec->audblk.ncplbnd; j++) {
-                NeedBits (&(p_ac3dec->bit_stream), 1);
-                p_ac3dec->audblk.phsflg[j] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                DumpBits (&(p_ac3dec->bit_stream), 1);
+           (p_ac3dec->audblk.cplcoe[0] || p_ac3dec->audblk.cplcoe[1]))
+        {
+            for (j=0; j < p_ac3dec->audblk.ncplbnd; j++)
+            {
+                p_ac3dec->audblk.phsflg[j] = GetBits (&p_ac3dec->bit_stream,1);
             }
+            p_ac3dec->total_bits_read += p_ac3dec->audblk.ncplbnd;
 
         }
     }
 
     /* If we're in dual mono mode, there may be a rematrix strategy */
-    if (p_ac3dec->bsi.acmod == 0x2) {
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->audblk.rematstr = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
-
-       if ((!blknum) && (!p_ac3dec->audblk.rematstr))
-           return 1;
-
-        if (p_ac3dec->audblk.rematstr) {
-            if (p_ac3dec->audblk.cplinu == 0) {
-                for (i = 0; i < 4; i++) {
-                    NeedBits (&(p_ac3dec->bit_stream), 1);
-                    p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                    DumpBits (&(p_ac3dec->bit_stream), 1);
+    if (p_ac3dec->bsi.acmod == 0x2)
+    {
+        p_ac3dec->audblk.rematstr = GetBits (&p_ac3dec->bit_stream,1);
+        p_ac3dec->total_bits_read += 1;
+
+        if ((!blknum) && (!p_ac3dec->audblk.rematstr))
+        {
+            return 1;
+        }
+
+        if (p_ac3dec->audblk.rematstr)
+        {
+            if (p_ac3dec->audblk.cplinu == 0)
+            {
+                for (i = 0; i < 4; i++)
+                {
+                    p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
                 }
+                p_ac3dec->total_bits_read += 4;
             }
-            if ((p_ac3dec->audblk.cplbegf > 2) && p_ac3dec->audblk.cplinu) {
-                for (i = 0; i < 4; i++) {
-                    NeedBits (&(p_ac3dec->bit_stream), 1);
-                    p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                    DumpBits (&(p_ac3dec->bit_stream), 1);
+            if ((p_ac3dec->audblk.cplbegf > 2) && p_ac3dec->audblk.cplinu)
+            {
+                for (i = 0; i < 4; i++)
+                {
+                    p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
                 }
+                p_ac3dec->total_bits_read += 4;
             }
-            if ((p_ac3dec->audblk.cplbegf <= 2) && p_ac3dec->audblk.cplinu) {
-                for (i = 0; i < 3; i++) {
-                    NeedBits (&(p_ac3dec->bit_stream), 1);
-                    p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                    DumpBits (&(p_ac3dec->bit_stream), 1);
+            if ((p_ac3dec->audblk.cplbegf <= 2) && p_ac3dec->audblk.cplinu)
+            {
+                for (i = 0; i < 3; i++)
+                {
+                    p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
                 }
+                p_ac3dec->total_bits_read += 3;
             }
             if ((p_ac3dec->audblk.cplbegf == 0) && p_ac3dec->audblk.cplinu)
-                for (i = 0; i < 2; i++) {
-                    NeedBits (&(p_ac3dec->bit_stream), 1);
-                    p_ac3dec->audblk.rematflg[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-                    DumpBits (&(p_ac3dec->bit_stream), 1);
+            {
+                for (i = 0; i < 2; i++)
+                {
+                    p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
                 }
+                p_ac3dec->total_bits_read += 2;
+            }
         }
     }
 
     if (p_ac3dec->audblk.cplinu)
     {
         /* Get the coupling channel exponent strategy */
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->audblk.cplexpstr = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
+        p_ac3dec->audblk.cplexpstr = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->total_bits_read += 2;
 
-       if ((!blknum) && (p_ac3dec->audblk.cplexpstr == EXP_REUSE))
-           return 1;
+        if ((!blknum) && (p_ac3dec->audblk.cplexpstr == EXP_REUSE))
+        {
+            return 1;
+        }
 
         if (p_ac3dec->audblk.cplexpstr==0)
+        {
             p_ac3dec->audblk.ncplgrps = 0;
+        }
         else
+        {
             p_ac3dec->audblk.ncplgrps = (p_ac3dec->audblk.cplendmant - p_ac3dec->audblk.cplstrtmant) /
-               (3 << (p_ac3dec->audblk.cplexpstr-1));
+                (3 << (p_ac3dec->audblk.cplexpstr-1));
+        }
 
     }
 
-    for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->audblk.chexpstr[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
+    for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
+    {
+        p_ac3dec->audblk.chexpstr[i] = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->total_bits_read += 2;
 
-       if ((!blknum) && (p_ac3dec->audblk.chexpstr[i] == EXP_REUSE))
-           return 1;
+        if ((!blknum) && (p_ac3dec->audblk.chexpstr[i] == EXP_REUSE))
+        {
+            return 1;
+        }
     }
 
     /* Get the exponent strategy for lfe channel */
-    if (p_ac3dec->bsi.lfeon) {
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->audblk.lfeexpstr = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
+    if (p_ac3dec->bsi.lfeon)
+    {
+        p_ac3dec->audblk.lfeexpstr = GetBits (&p_ac3dec->bit_stream,1);
+        p_ac3dec->total_bits_read += 1;
 
-       if ((!blknum) && (p_ac3dec->audblk.lfeexpstr == EXP_REUSE))
-           return 1;
+        if ((!blknum) && (p_ac3dec->audblk.lfeexpstr == EXP_REUSE))
+        {
+            return 1;
+        }
     }
 
     /* Determine the bandwidths of all the fbw channels */
-    for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
+    for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
+    {
         u16 grp_size;
 
-        if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE) {
-            if (p_ac3dec->audblk.cplinu && p_ac3dec->audblk.chincpl[i]) {
+        if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE)
+        {
+            if (p_ac3dec->audblk.cplinu && p_ac3dec->audblk.chincpl[i])
+            {
                 p_ac3dec->audblk.endmant[i] = p_ac3dec->audblk.cplstrtmant;
-            } else {
-                NeedBits (&(p_ac3dec->bit_stream), 6);
-                p_ac3dec->audblk.chbwcod[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 6));
-                DumpBits (&(p_ac3dec->bit_stream), 6);
-
-               if (p_ac3dec->audblk.chbwcod[i] > 60)
-                   return 1;
+            }
+            else
+            {
+                p_ac3dec->audblk.chbwcod[i] = GetBits (&p_ac3dec->bit_stream,6);
+                p_ac3dec->total_bits_read += 6;
+
+                if (p_ac3dec->audblk.chbwcod[i] > 60)
+                {
+                    return 1;
+                }
 
                 p_ac3dec->audblk.endmant[i] = ((p_ac3dec->audblk.chbwcod[i] + 12) * 3) + 37;
             }
@@ -566,216 +589,206 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
     }
 
     /* Get the coupling exponents if they exist */
-    if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cplexpstr != EXP_REUSE)) {
-        NeedBits (&(p_ac3dec->bit_stream), 4);
-        p_ac3dec->audblk.cplabsexp = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-        DumpBits (&(p_ac3dec->bit_stream), 4);
-        for (i=0; i< p_ac3dec->audblk.ncplgrps;i++) {
-            NeedBits (&(p_ac3dec->bit_stream), 7);
-            p_ac3dec->audblk.cplexps[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 7));
-            DumpBits (&(p_ac3dec->bit_stream), 7);
-
-           if (p_ac3dec->audblk.cplexps[i] >= 125)
-               return 1;
+    if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cplexpstr != EXP_REUSE))
+    {
+        p_ac3dec->audblk.cplabsexp = GetBits (&p_ac3dec->bit_stream,4);
+        p_ac3dec->total_bits_read += 4;
+        for (i=0; i< p_ac3dec->audblk.ncplgrps;i++)
+        {
+            p_ac3dec->audblk.cplexps[i] = GetBits (&p_ac3dec->bit_stream,7);
+            p_ac3dec->total_bits_read += 7;
+
+            if (p_ac3dec->audblk.cplexps[i] >= 125)
+            {
+                return 1;
+            }
         }
     }
 
     /* Get the fwb channel exponents */
-    for (i=0; i < p_ac3dec->bsi.nfchans; i++) {
-        if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE) {
-            NeedBits (&(p_ac3dec->bit_stream), 4);
-            p_ac3dec->audblk.exps[i][0] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-            DumpBits (&(p_ac3dec->bit_stream), 4);
-            for (j=1; j<=p_ac3dec->audblk.nchgrps[i];j++) {
-                NeedBits (&(p_ac3dec->bit_stream), 7);
-                p_ac3dec->audblk.exps[i][j] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 7));
-                DumpBits (&(p_ac3dec->bit_stream), 7);
-               if (p_ac3dec->audblk.exps[i][j] >= 125)
-                   return 1;
+    for (i=0; i < p_ac3dec->bsi.nfchans; i++)
+    {
+        if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE)
+        {
+            p_ac3dec->audblk.exps[i][0] = GetBits (&p_ac3dec->bit_stream,4);
+            p_ac3dec->total_bits_read += 4;
+            for (j=1; j<=p_ac3dec->audblk.nchgrps[i];j++)
+            {
+                p_ac3dec->audblk.exps[i][j] = GetBits (&p_ac3dec->bit_stream,7);
+                p_ac3dec->total_bits_read += 7;
+                if (p_ac3dec->audblk.exps[i][j] >= 125)
+                {
+                    return 1;
+                }
             }
-            NeedBits (&(p_ac3dec->bit_stream), 2);
-            p_ac3dec->audblk.gainrng[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-            DumpBits (&(p_ac3dec->bit_stream), 2);
+            p_ac3dec->audblk.gainrng[i] = GetBits (&p_ac3dec->bit_stream,2);
+            p_ac3dec->total_bits_read += 2;
         }
     }
 
     /* Get the lfe channel exponents */
-    if (p_ac3dec->bsi.lfeon && (p_ac3dec->audblk.lfeexpstr != EXP_REUSE)) {
-        NeedBits (&(p_ac3dec->bit_stream), 4);
-        p_ac3dec->audblk.lfeexps[0] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-        DumpBits (&(p_ac3dec->bit_stream), 4);
-        NeedBits (&(p_ac3dec->bit_stream), 7);
-        p_ac3dec->audblk.lfeexps[1] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 7));
-        DumpBits (&(p_ac3dec->bit_stream), 7);
-       if (p_ac3dec->audblk.lfeexps[1] >= 125)
-           return 1;
-        NeedBits (&(p_ac3dec->bit_stream), 7);
-        p_ac3dec->audblk.lfeexps[2] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 7));
-        DumpBits (&(p_ac3dec->bit_stream), 7);
-       if (p_ac3dec->audblk.lfeexps[2] >= 125)
-           return 1;
+    if (p_ac3dec->bsi.lfeon && (p_ac3dec->audblk.lfeexpstr != EXP_REUSE))
+    {
+        p_ac3dec->audblk.lfeexps[0] = GetBits (&p_ac3dec->bit_stream,4);
+        p_ac3dec->audblk.lfeexps[1] = GetBits (&p_ac3dec->bit_stream,7);
+        p_ac3dec->total_bits_read += 11;
+        if (p_ac3dec->audblk.lfeexps[1] >= 125)
+        {
+            return 1;
+        }
+        p_ac3dec->audblk.lfeexps[2] = GetBits (&p_ac3dec->bit_stream,7);
+        p_ac3dec->total_bits_read += 7;
+        if (p_ac3dec->audblk.lfeexps[2] >= 125)
+        {
+            return 1;
+        }
     }
 
     /* Get the parametric bit allocation parameters */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->audblk.baie = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    p_ac3dec->audblk.baie = GetBits (&p_ac3dec->bit_stream,1);
+    p_ac3dec->total_bits_read += 1;
 
     if ((!blknum) && (!p_ac3dec->audblk.baie))
-       return 1;
-
-    if (p_ac3dec->audblk.baie) {
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->audblk.sdcycod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->audblk.fdcycod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->audblk.sgaincod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
-        NeedBits (&(p_ac3dec->bit_stream), 2);
-        p_ac3dec->audblk.dbpbcod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-        DumpBits (&(p_ac3dec->bit_stream), 2);
-        NeedBits (&(p_ac3dec->bit_stream), 3);
-        p_ac3dec->audblk.floorcod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-        DumpBits (&(p_ac3dec->bit_stream), 3);
+    {
+        return 1;
+    }
+
+    if (p_ac3dec->audblk.baie)
+    {
+        p_ac3dec->audblk.sdcycod = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->audblk.fdcycod = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->audblk.sgaincod = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->audblk.dbpbcod = GetBits (&p_ac3dec->bit_stream,2);
+        p_ac3dec->audblk.floorcod = GetBits (&p_ac3dec->bit_stream,3);
+        p_ac3dec->total_bits_read += 11;
     }
 
     /* Get the SNR off set info if it exists */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->audblk.snroffste = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    p_ac3dec->audblk.snroffste = GetBits (&p_ac3dec->bit_stream,1);
     if ((!blknum) && (!p_ac3dec->audblk.snroffste))
-       return 1;
-
-    if (p_ac3dec->audblk.snroffste) {
-        NeedBits (&(p_ac3dec->bit_stream), 6);
-        p_ac3dec->audblk.csnroffst = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 6));
-        DumpBits (&(p_ac3dec->bit_stream), 6);
-
-        if (p_ac3dec->audblk.cplinu) {
-            NeedBits (&(p_ac3dec->bit_stream), 4);
-            p_ac3dec->audblk.cplfsnroffst = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-            DumpBits (&(p_ac3dec->bit_stream), 4);
-            NeedBits (&(p_ac3dec->bit_stream), 3);
-            p_ac3dec->audblk.cplfgaincod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-            DumpBits (&(p_ac3dec->bit_stream), 3);
+    {
+        return 1;
+    }
+
+    if (p_ac3dec->audblk.snroffste)
+    {
+        p_ac3dec->audblk.csnroffst = GetBits (&p_ac3dec->bit_stream,6);
+        p_ac3dec->total_bits_read += 6;
+
+        if (p_ac3dec->audblk.cplinu)
+        {
+            p_ac3dec->audblk.cplfsnroffst = GetBits (&p_ac3dec->bit_stream,4);
+            p_ac3dec->audblk.cplfgaincod = GetBits (&p_ac3dec->bit_stream,3);
+            p_ac3dec->total_bits_read += 7;
         }
 
-        for (i = 0;i < p_ac3dec->bsi.nfchans; i++) {
-            NeedBits (&(p_ac3dec->bit_stream), 4);
-            p_ac3dec->audblk.fsnroffst[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-            DumpBits (&(p_ac3dec->bit_stream), 4);
-            NeedBits (&(p_ac3dec->bit_stream), 3);
-            p_ac3dec->audblk.fgaincod[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-            DumpBits (&(p_ac3dec->bit_stream), 3);
+        for (i = 0;i < p_ac3dec->bsi.nfchans; i++)
+        {
+            p_ac3dec->audblk.fsnroffst[i] = GetBits (&p_ac3dec->bit_stream,4);
+            p_ac3dec->audblk.fgaincod[i] = GetBits (&p_ac3dec->bit_stream,3);
         }
-        if (p_ac3dec->bsi.lfeon) {
-            NeedBits (&(p_ac3dec->bit_stream), 4);
-            p_ac3dec->audblk.lfefsnroffst = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-            DumpBits (&(p_ac3dec->bit_stream), 4);
-            NeedBits (&(p_ac3dec->bit_stream), 3);
-            p_ac3dec->audblk.lfefgaincod = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-            DumpBits (&(p_ac3dec->bit_stream), 3);
+        p_ac3dec->total_bits_read += 7 * p_ac3dec->bsi.nfchans;
+        if (p_ac3dec->bsi.lfeon)
+        {
+            p_ac3dec->audblk.lfefsnroffst = GetBits (&p_ac3dec->bit_stream,4);
+            p_ac3dec->audblk.lfefgaincod = GetBits (&p_ac3dec->bit_stream,3);
+            p_ac3dec->total_bits_read += 7;
         }
     }
 
     /* Get coupling leakage info if it exists */
-    if (p_ac3dec->audblk.cplinu) {
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        p_ac3dec->audblk.cplleake = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-        DumpBits (&(p_ac3dec->bit_stream), 1);
-       if ((!blknum) && (!p_ac3dec->audblk.cplleake))
-           return 1;
-
-        if (p_ac3dec->audblk.cplleake) {
-            NeedBits (&(p_ac3dec->bit_stream), 3);
-            p_ac3dec->audblk.cplfleak = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-            DumpBits (&(p_ac3dec->bit_stream), 3);
-            NeedBits (&(p_ac3dec->bit_stream), 3);
-            p_ac3dec->audblk.cplsleak = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-            DumpBits (&(p_ac3dec->bit_stream), 3);
+    if (p_ac3dec->audblk.cplinu)
+    {
+        p_ac3dec->audblk.cplleake = GetBits (&p_ac3dec->bit_stream,1);
+        p_ac3dec->total_bits_read += 1;
+        if ((!blknum) && (!p_ac3dec->audblk.cplleake))
+        {
+            return 1;
+        }
+
+        if (p_ac3dec->audblk.cplleake)
+        {
+            p_ac3dec->audblk.cplfleak = GetBits (&p_ac3dec->bit_stream,3);
+            p_ac3dec->audblk.cplsleak = GetBits (&p_ac3dec->bit_stream,3);
+            p_ac3dec->total_bits_read += 6;
         }
     }
 
     /* Get the delta bit alloaction info */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->audblk.deltbaie = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-
-    if (p_ac3dec->audblk.deltbaie) {
-        if (p_ac3dec->audblk.cplinu) {
-            NeedBits (&(p_ac3dec->bit_stream), 2);
-            p_ac3dec->audblk.cpldeltbae = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-            DumpBits (&(p_ac3dec->bit_stream), 2);
-           if (p_ac3dec->audblk.cpldeltbae == 3)
-               return 1;
+    p_ac3dec->audblk.deltbaie = GetBits (&p_ac3dec->bit_stream,1);
+    p_ac3dec->total_bits_read += 1;
+
+    if (p_ac3dec->audblk.deltbaie)
+    {
+        if (p_ac3dec->audblk.cplinu)
+        {
+            p_ac3dec->audblk.cpldeltbae = GetBits (&p_ac3dec->bit_stream,2);
+            p_ac3dec->total_bits_read += 2;
+            if (p_ac3dec->audblk.cpldeltbae == 3)
+            {
+                return 1;
+            }
         }
 
-        for (i = 0;i < p_ac3dec->bsi.nfchans; i++) {
-            NeedBits (&(p_ac3dec->bit_stream), 2);
-            p_ac3dec->audblk.deltbae[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 2));
-            DumpBits (&(p_ac3dec->bit_stream), 2);
-           if (p_ac3dec->audblk.deltbae[i] == 3)
-               return 1;
+        for (i = 0;i < p_ac3dec->bsi.nfchans; i++)
+        {
+            p_ac3dec->audblk.deltbae[i] = GetBits (&p_ac3dec->bit_stream,2);
+            p_ac3dec->total_bits_read += 2;
+            if (p_ac3dec->audblk.deltbae[i] == 3)
+            {
+                return 1;
+            }
         }
 
-        if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cpldeltbae == DELTA_BIT_NEW)) {
-            NeedBits (&(p_ac3dec->bit_stream), 3);
-            p_ac3dec->audblk.cpldeltnseg = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-            DumpBits (&(p_ac3dec->bit_stream), 3);
-            for (i = 0;i < p_ac3dec->audblk.cpldeltnseg + 1; i++) {
-                NeedBits (&(p_ac3dec->bit_stream), 5);
-                p_ac3dec->audblk.cpldeltoffst[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 5));
-                DumpBits (&(p_ac3dec->bit_stream), 5);
-                NeedBits (&(p_ac3dec->bit_stream), 4);
-                p_ac3dec->audblk.cpldeltlen[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-                DumpBits (&(p_ac3dec->bit_stream), 4);
-                NeedBits (&(p_ac3dec->bit_stream), 3);
-                p_ac3dec->audblk.cpldeltba[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-                DumpBits (&(p_ac3dec->bit_stream), 3);
+        if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cpldeltbae == DELTA_BIT_NEW))
+        {
+            p_ac3dec->audblk.cpldeltnseg = GetBits (&p_ac3dec->bit_stream,3);
+            for (i = 0;i < p_ac3dec->audblk.cpldeltnseg + 1; i++)
+            {
+                p_ac3dec->audblk.cpldeltoffst[i] = GetBits (&p_ac3dec->bit_stream,5);
+                p_ac3dec->audblk.cpldeltlen[i] = GetBits (&p_ac3dec->bit_stream,4);
+                p_ac3dec->audblk.cpldeltba[i] = GetBits (&p_ac3dec->bit_stream,3);
             }
+            p_ac3dec->total_bits_read += 12 * (p_ac3dec->audblk.cpldeltnseg + 1) + 3;
         }
 
-        for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
-            if (p_ac3dec->audblk.deltbae[i] == DELTA_BIT_NEW) {
-                NeedBits (&(p_ac3dec->bit_stream), 3);
-                p_ac3dec->audblk.deltnseg[i] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-                DumpBits (&(p_ac3dec->bit_stream), 3);
+        for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
+        {
+            if (p_ac3dec->audblk.deltbae[i] == DELTA_BIT_NEW)
+            {
+                p_ac3dec->audblk.deltnseg[i] = GetBits (&p_ac3dec->bit_stream,3);
 //                if (p_ac3dec->audblk.deltnseg[i] >= 8)
 //                    fprintf (stderr, "parse debug: p_ac3dec->audblk.deltnseg[%i] == %i\n", i, p_ac3dec->audblk.deltnseg[i]);
-                for (j = 0; j < p_ac3dec->audblk.deltnseg[i] + 1; j++) {
-                    NeedBits (&(p_ac3dec->bit_stream), 5);
-                    p_ac3dec->audblk.deltoffst[i][j] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 5));
-                    DumpBits (&(p_ac3dec->bit_stream), 5);
-                    NeedBits (&(p_ac3dec->bit_stream), 4);
-                    p_ac3dec->audblk.deltlen[i][j] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 4));
-                    DumpBits (&(p_ac3dec->bit_stream), 4);
-                    NeedBits (&(p_ac3dec->bit_stream), 3);
-                    p_ac3dec->audblk.deltba[i][j] = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 3));
-                    DumpBits (&(p_ac3dec->bit_stream), 3);
+                for (j = 0; j < p_ac3dec->audblk.deltnseg[i] + 1; j++)
+                {
+                    p_ac3dec->audblk.deltoffst[i][j] = GetBits (&p_ac3dec->bit_stream,5);
+                    p_ac3dec->audblk.deltlen[i][j] = GetBits (&p_ac3dec->bit_stream,4);
+                    p_ac3dec->audblk.deltba[i][j] = GetBits (&p_ac3dec->bit_stream,3);
                 }
+                p_ac3dec->total_bits_read += 12 * (p_ac3dec->audblk.deltnseg[i] + 1) + 3;
             }
         }
     }
 
     /* Check to see if there's any dummy info to get */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    p_ac3dec->audblk.skiple = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 1));
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-
-    if (p_ac3dec->audblk.skiple) {
-        NeedBits (&(p_ac3dec->bit_stream), 9);
-        p_ac3dec->audblk.skipl = (u16)(p_ac3dec->bit_stream.buffer >> (32 - 9));
-        DumpBits (&(p_ac3dec->bit_stream), 9);
-
-        for (i = 0; i < p_ac3dec->audblk.skipl ; i++) {
-            NeedBits (&(p_ac3dec->bit_stream), 8);
-            DumpBits (&(p_ac3dec->bit_stream), 8);
+    p_ac3dec->audblk.skiple = GetBits (&p_ac3dec->bit_stream,1);
+    p_ac3dec->total_bits_read += 1;
+
+    if (p_ac3dec->audblk.skiple)
+    {
+        p_ac3dec->audblk.skipl = GetBits (&p_ac3dec->bit_stream,9);
+
+        for (i = 0; i < p_ac3dec->audblk.skipl ; i++)
+        {
+            GetBits (&p_ac3dec->bit_stream,8);
         }
+        p_ac3dec->total_bits_read += 8 * p_ac3dec->audblk.skipl + 9;
     }
-
+    
+#ifdef TRACE
+    parse_audblk_stats(p_ac3dec);
+#endif
+    
     return 0;
 }
 
@@ -784,23 +797,86 @@ void parse_auxdata (ac3dec_t * p_ac3dec)
     int i;
     int skip_length;
 
-    skip_length = (p_ac3dec->syncinfo.frame_size * 16) - p_ac3dec->bit_stream.total_bits_read - 17 - 1;
-//    fprintf (stderr, "parse debug: skip_length == %i\n", skip_length);
+    skip_length = (p_ac3dec->syncinfo.frame_size * 16) - p_ac3dec->total_bits_read - 17 - 1;
 
-    for (i = 0; i < skip_length; i++) {
-        NeedBits (&(p_ac3dec->bit_stream), 1);
-        DumpBits (&(p_ac3dec->bit_stream), 1);
+    for (i = 0; i < skip_length; i++)
+    {
+        RemoveBits (&p_ac3dec->bit_stream,1);
     }
 
     /* get the auxdata exists bit */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    DumpBits (&(p_ac3dec->bit_stream), 1);
-
+    RemoveBits (&p_ac3dec->bit_stream,1);
+    
     /* Skip the CRC reserved bit */
-    NeedBits (&(p_ac3dec->bit_stream), 1);
-    DumpBits (&(p_ac3dec->bit_stream), 1);
+    RemoveBits (&p_ac3dec->bit_stream,1);
 
     /* Get the crc */
-    NeedBits (&(p_ac3dec->bit_stream), 16);
-    DumpBits (&(p_ac3dec->bit_stream), 16);
+    RemoveBits (&p_ac3dec->bit_stream,16);
 }
+
+#ifdef TRACE
+static void parse_bsi_stats (ac3dec_t * p_ac3dec) /* Some stats */
+{  
+    struct mixlev_s
+    {
+        float clev;
+        char *desc;
+    };
+    static const char *service_ids[8] = 
+    {
+        "CM","ME","VI","HI",
+        "D", "C","E", "VO"
+    };
+/*
+    static const struct mixlev_s cmixlev_tbl[4] =  
+    {
+        {0.707, "(-3.0 dB)"}, {0.595, "(-4.5 dB)"},
+        {0.500, "(-6.0 dB)"}, {1.0,  "Invalid"}
+    };
+    static const struct mixlev_s smixlev_tbl[4] =  
+    {
+        {0.707, "(-3.0 dB)"}, {0.500, "(-6.0 dB)"},
+        {  0.0,   "off    "}, {  1.0, "Invalid"}
+    };
+ */
+    
+    static int  i=0;
+    
+    if ( !i )
+    {
+/*      if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
+               printf("CentreMixLevel %s ",cmixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
+        if (p_ac3dec->bsi.acmod & 0x4)
+               printf("SurMixLevel %s",smixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
+ */
+        intf_Msg ( "(ac3dec_parsebsi) %s %d.%d Mode",
+                service_ids[p_ac3dec->bsi.bsmod],
+                p_ac3dec->bsi.nfchans,p_ac3dec->bsi.lfeon);
+    }
+    i++;
+    
+    if ( i > 100 )
+        i = 0;
+}
+
+static void parse_audblk_stats (ac3dec_t * p_ac3dec)
+{
+    char *exp_strat_tbl[4] = {"R   ","D15 ","D25 ","D45 "};
+    u32 i;
+
+    intf_ErrMsg ("(ac3dec_parseaudblk) ");
+    intf_ErrMsg ("%s ",p_ac3dec->audblk.cplinu ? "cpl on" : "cpl off");
+    intf_ErrMsg ("%s ",p_ac3dec->audblk.baie? "bai" : " ");
+    intf_ErrMsg ("%s ",p_ac3dec->audblk.snroffste? "snroffst" : " ");
+    intf_ErrMsg ("%s ",p_ac3dec->audblk.deltbaie? "deltba" : " ");
+    intf_ErrMsg ("%s ",p_ac3dec->audblk.phsflginu? "phsflg" : " ");
+    intf_ErrMsg ("(%s %s %s %s %s) ",exp_strat_tbl[p_ac3dec->audblk.chexpstr[0]],
+           exp_strat_tbl[p_ac3dec->audblk.chexpstr[1]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[2]],
+           exp_strat_tbl[p_ac3dec->audblk.chexpstr[3]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[4]]);
+    intf_ErrMsg ("[");
+    for(i=0;i<p_ac3dec->bsi.nfchans;i++)
+            intf_ErrMsg ("%1d",p_ac3dec->audblk.blksw[i]);
+    intf_ErrMsg ("]");
+}
+#endif
+