Commit 3b94a56f authored by Renaud Dartus's avatar Renaud Dartus

* Begin of the new ac3_decoder ;)

  - New ac3_decoder_thread (we now use GetBits)

Please warn me if you encounter some problem
parent 39db76ab
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_bit_allocate.c: ac3 allocation tables * ac3_bit_allocate.c: ac3 allocation tables
***************************************************************************** *****************************************************************************
* Copyright (C) 2000 VideoLAN * Copyright (C) 2000 VideoLAN
* $Id: ac3_bit_allocate.c,v 1.17 2001/04/06 09:15:47 sam Exp $ * $Id: ac3_bit_allocate.c,v 1.18 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca> * Aaron Holtzman <aholtzma@engr.uvic.ca>
...@@ -24,9 +24,16 @@ ...@@ -24,9 +24,16 @@
*****************************************************************************/ *****************************************************************************/
#include "defs.h" #include "defs.h"
#include <string.h> /* memcpy(), memset() */ #include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "stream_control.h"
#include "input_ext-dec.h"
#include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_internal.h" #include "ac3_internal.h"
......
/*****************************************************************************
* ac3_bit_stream.h: getbits functions for the ac3 decoder
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: ac3_bit_stream.h,v 1.9 2001/03/21 13:42:34 sam Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
* 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.
*
* 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.
*****************************************************************************/
static __inline__ u32 bitstream_get (ac3_bit_stream_t * p_bit_stream,
u32 num_bits)
{
u32 result=0;
while (p_bit_stream->i_available < num_bits)
{
if (p_bit_stream->byte_stream.p_byte >= p_bit_stream->byte_stream.p_end)
{
ac3dec_thread_t * p_ac3dec = p_bit_stream->byte_stream.info;
/* no, switch to next buffer */
if(!p_ac3dec->p_fifo->b_die)
ac3_byte_stream_next (&p_bit_stream->byte_stream);
}
p_bit_stream->buffer |=((u32) *(p_bit_stream->byte_stream.p_byte++))
<< (24 - p_bit_stream->i_available);
p_bit_stream->i_available += 8;
}
result = p_bit_stream->buffer >> (32 - num_bits);
p_bit_stream->buffer <<= num_bits;
p_bit_stream->i_available -= num_bits;
p_bit_stream->total_bits_read += num_bits;
return result;
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_decoder.c: core ac3 decoder * ac3_decoder.c: core ac3 decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.c,v 1.28 2001/03/21 13:42:34 sam Exp $ * $Id: ac3_decoder.c,v 1.29 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org> * Michel Lespinasse <walken@zoy.org>
...@@ -25,8 +25,21 @@ ...@@ -25,8 +25,21 @@
#include "defs.h" #include "defs.h"
#include "int_types.h" #include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
#include "stream_control.h"
#include "input_ext-dec.h"
#include "audio_output.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_decoder_thread.h"
#include "ac3_internal.h" #include "ac3_internal.h"
#include <stdio.h> #include <stdio.h>
...@@ -35,8 +48,8 @@ void imdct_init (imdct_t * p_imdct); ...@@ -35,8 +48,8 @@ void imdct_init (imdct_t * p_imdct);
int ac3_init (ac3dec_t * p_ac3dec) int ac3_init (ac3dec_t * p_ac3dec)
{ {
//p_ac3dec->bit_stream.buffer = 0; // p_ac3dec->bit_stream.buffer = 0;
//p_ac3dec->bit_stream.i_available = 0; // p_ac3dec->bit_stream.i_available = 0;
p_ac3dec->mantissa.lfsr_state = 1; /* dither_gen initialization */ p_ac3dec->mantissa.lfsr_state = 1; /* dither_gen initialization */
imdct_init(&p_ac3dec->imdct); imdct_init(&p_ac3dec->imdct);
...@@ -46,21 +59,50 @@ int ac3_init (ac3dec_t * p_ac3dec) ...@@ -46,21 +59,50 @@ int ac3_init (ac3dec_t * p_ac3dec)
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer) int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
{ {
int i; int i;
ac3dec_thread_t * p_ac3dec_t = (ac3dec_thread_t *) p_ac3dec->bit_stream.p_callback_arg;
if (parse_bsi (p_ac3dec)) if (parse_bsi (p_ac3dec))
{
intf_WarnMsg (1,"Error during ac3parsing");
parse_auxdata (p_ac3dec);
return 1; return 1;
}
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
if ((p_ac3dec_t->p_fifo->b_die) && (p_ac3dec_t->p_fifo->b_error))
{
return 1;
}
if (parse_audblk (p_ac3dec, i)) if (parse_audblk (p_ac3dec, i))
{
intf_WarnMsg (1,"Error during ac3audioblock");
parse_auxdata (p_ac3dec);
return 1;
}
if ((p_ac3dec_t->p_fifo->b_die) && (p_ac3dec_t->p_fifo->b_error))
{
return 1; return 1;
}
if (exponent_unpack (p_ac3dec)) if (exponent_unpack (p_ac3dec))
{
intf_WarnMsg (1,"Error during ac3unpack");
parse_auxdata (p_ac3dec);
return 1; return 1;
}
bit_allocate (p_ac3dec); bit_allocate (p_ac3dec);
mantissa_unpack (p_ac3dec); mantissa_unpack (p_ac3dec);
if ((p_ac3dec_t->p_fifo->b_die) && (p_ac3dec_t->p_fifo->b_error))
{
return 1;
}
if (p_ac3dec->bsi.acmod == 0x2) if (p_ac3dec->bsi.acmod == 0x2)
rematrix (p_ac3dec); rematrix (p_ac3dec);
imdct (p_ac3dec, buffer); imdct (p_ac3dec, buffer);
// downmix (p_ac3dec, buffer);
buffer += 2*256; buffer += 2*256;
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_decoder.h : ac3 decoder interface * ac3_decoder.h : ac3 decoder interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder.h,v 1.4 2001/03/21 13:42:34 sam Exp $ * $Id: ac3_decoder.h,v 1.5 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Renaud Dartus <reno@videolan.org> * Renaud Dartus <reno@videolan.org>
...@@ -32,22 +32,12 @@ typedef struct ac3_sync_info_s { ...@@ -32,22 +32,12 @@ typedef struct ac3_sync_info_s {
int bit_rate; /* nominal bit rate in kbps */ int bit_rate; /* nominal bit rate in kbps */
} ac3_sync_info_t; } ac3_sync_info_t;
typedef struct ac3_byte_stream_s {
u8 * p_byte;
u8 * p_end;
void * info;
} ac3_byte_stream_t;
/**** ac3 decoder API - functions publically provided by the ac3 decoder ****/ /**** ac3 decoder API - functions publically provided by the ac3 decoder ****/
int ac3_init (ac3dec_t * p_ac3dec); int ac3_init (ac3dec_t * p_ac3dec);
int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info); int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info);
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer); int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer);
static ac3_byte_stream_t * ac3_byte_stream (ac3dec_t * p_ac3dec);
/**** ac3 decoder API - user functions to be provided to the ac3 decoder ****/
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream);
/**** EVERYTHING AFTER THIS POINT IS PRIVATE ! DO NOT USE DIRECTLY ****/ /**** EVERYTHING AFTER THIS POINT IS PRIVATE ! DO NOT USE DIRECTLY ****/
...@@ -347,15 +337,6 @@ typedef struct stream_samples_s ...@@ -347,15 +337,6 @@ typedef struct stream_samples_s
float channel[6][256]; float channel[6][256];
} stream_samples_t; } stream_samples_t;
typedef struct ac3_bit_stream_s
{
u32 buffer;
int i_available;
ac3_byte_stream_t byte_stream;
unsigned int total_bits_read; /* temporary */
} ac3_bit_stream_t;
typedef struct bit_allocate_s typedef struct bit_allocate_s
{ {
s16 psd[256]; s16 psd[256];
...@@ -420,8 +401,10 @@ struct ac3dec_s ...@@ -420,8 +401,10 @@ struct ac3dec_s
*/ */
/* The bit stream structure handles the PES stream at the bit level */ /* The bit stream structure handles the PES stream at the bit level */
ac3_bit_stream_t bit_stream; bit_stream_t bit_stream;
int i_available;
unsigned int total_bits_read; /* temporary */
/* /*
* Decoder properties * Decoder properties
*/ */
...@@ -436,10 +419,3 @@ struct ac3dec_s ...@@ -436,10 +419,3 @@ struct ac3dec_s
mantissa_t mantissa; mantissa_t mantissa;
imdct_t imdct; imdct_t imdct;
}; };
/**** ac3 decoder inline functions ****/
static ac3_byte_stream_t * ac3_byte_stream (ac3dec_t * p_ac3dec)
{
return &(p_ac3dec->bit_stream.byte_stream);
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_decoder_thread.c: ac3 decoder thread * ac3_decoder_thread.c: ac3 decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder_thread.c,v 1.27 2001/04/06 09:15:47 sam Exp $ * $Id: ac3_decoder_thread.c,v 1.28 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Lespinasse <walken@zoy.org> * Authors: Michel Lespinasse <walken@zoy.org>
* *
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
#include <unistd.h> /* getpid() */ #include <unistd.h> /* getpid() */
#include <stdio.h> /* "intf_msg.h" */ #include <stdio.h> /* "intf_msg.h" */
#include <string.h> /* memcpy(), memset() */
#include <stdlib.h> /* malloc(), free() */ #include <stdlib.h> /* malloc(), free() */
#include "config.h" #include "config.h"
...@@ -65,49 +64,53 @@ static int InitThread (ac3dec_thread_t * p_adec); ...@@ -65,49 +64,53 @@ static int InitThread (ac3dec_thread_t * p_adec);
static void RunThread (ac3dec_thread_t * p_adec); static void RunThread (ac3dec_thread_t * p_adec);
static void ErrorThread (ac3dec_thread_t * p_adec); static void ErrorThread (ac3dec_thread_t * p_adec);
static void EndThread (ac3dec_thread_t * p_adec); static void EndThread (ac3dec_thread_t * p_adec);
static void BitstreamCallback ( bit_stream_t *p_bit_stream,
boolean_t b_new_pes );
/***************************************************************************** /*****************************************************************************
* ac3dec_CreateThread: creates an ac3 decoder thread * ac3dec_CreateThread: creates an ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config ) vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
{ {
ac3dec_thread_t * p_ac3dec; ac3dec_thread_t * p_ac3dec_t;
intf_DbgMsg( "ac3dec debug: creating ac3 decoder thread" ); intf_DbgMsg( "ac3dec debug: creating ac3 decoder thread" );
/* Allocate the memory needed to store the thread's structure */ /* Allocate the memory needed to store the thread's structure */
if ((p_ac3dec = (ac3dec_thread_t *)malloc (sizeof(ac3dec_thread_t))) == NULL) if((p_ac3dec_t = (ac3dec_thread_t *)malloc(sizeof(ac3dec_thread_t)))==NULL)
{ {
intf_ErrMsg ( "ac3dec error: not enough memory " intf_ErrMsg ( "ac3dec error: not enough memory "
"for ac3dec_CreateThread() to create the new thread"); "for ac3dec_CreateThread() to create the new thread");
return 0; return 0;
} }
/* /*
* Initialize the thread properties * Initialize the thread properties
*/ */
p_ac3dec->p_config = p_config; p_ac3dec_t->p_config = p_config;
p_ac3dec->p_fifo = p_config->decoder_config.p_decoder_fifo; p_ac3dec_t->p_fifo = p_config->decoder_config.p_decoder_fifo;
/* Initialize the ac3 decoder structures */ /* Initialize the ac3 decoder structures */
ac3_init (&p_ac3dec->ac3_decoder); ac3_init (&p_ac3dec_t->ac3_decoder);
/* /*
* Initialize the output properties * Initialize the output properties
*/ */
p_ac3dec->p_aout = p_config->p_aout; p_ac3dec_t->p_aout = p_config->p_aout;
p_ac3dec->p_aout_fifo = NULL; p_ac3dec_t->p_aout_fifo = NULL;
/* Spawn the ac3 decoder thread */ /* Spawn the ac3 decoder thread */
if (vlc_thread_create(&p_ac3dec->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec)) if (vlc_thread_create(&p_ac3dec_t->thread_id, "ac3 decoder",
(vlc_thread_func_t)RunThread, (void *)p_ac3dec_t))
{ {
intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread" ); intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread" );
free (p_ac3dec); free (p_ac3dec_t);
return 0; return 0;
} }
intf_DbgMsg ("ac3dec debug: ac3 decoder thread (%p) created", p_ac3dec); intf_DbgMsg ("ac3dec debug: ac3 decoder thread (%p) created", p_ac3dec_t);
return p_ac3dec->thread_id; return p_ac3dec_t->thread_id;
} }
/* Following functions are local */ /* Following functions are local */
...@@ -115,31 +118,19 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config ) ...@@ -115,31 +118,19 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
/***************************************************************************** /*****************************************************************************
* InitThread : initialize an ac3 decoder thread * InitThread : initialize an ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
static int InitThread (ac3dec_thread_t * p_ac3dec) static int InitThread (ac3dec_thread_t * p_ac3dec_t)
{ {
aout_fifo_t aout_fifo; aout_fifo_t aout_fifo;
ac3_byte_stream_t * byte_stream;
intf_DbgMsg ("ac3dec debug: initializing ac3 decoder thread %p", p_ac3dec); intf_DbgMsg("ac3dec debug: initializing ac3 decoder thread %p",p_ac3dec_t);
/* Get the first data packet. */ p_ac3dec_t->p_config->decoder_config.pf_init_bit_stream(
vlc_mutex_lock( &p_ac3dec->p_fifo->data_lock ); &p_ac3dec_t->ac3_decoder.bit_stream,
while ( DECODER_FIFO_ISEMPTY( *p_ac3dec->p_fifo ) ) p_ac3dec_t->p_config->decoder_config.p_decoder_fifo );
{ p_ac3dec_t->ac3_decoder.bit_stream.pf_bitstream_callback=BitstreamCallback;
if ( p_ac3dec->p_fifo->b_die ) p_ac3dec_t->ac3_decoder.bit_stream.p_callback_arg = (void *) p_ac3dec_t;
{
vlc_mutex_unlock( &p_ac3dec->p_fifo->data_lock );
return -1;
}
vlc_cond_wait( &p_ac3dec->p_fifo->data_wait, &p_ac3dec->p_fifo->data_lock );
}
p_ac3dec->p_data = DECODER_FIFO_START(*p_ac3dec->p_fifo)->p_first;
byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
byte_stream->p_byte = p_ac3dec->p_data->p_payload_start;
byte_stream->p_end = p_ac3dec->p_data->p_payload_end;
byte_stream->info = p_ac3dec;
vlc_mutex_unlock (&p_ac3dec->p_fifo->data_lock);
aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO; aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
aout_fifo.i_channels = 2; aout_fifo.i_channels = 2;
aout_fifo.b_stereo = 1; aout_fifo.b_stereo = 1;
...@@ -147,247 +138,178 @@ static int InitThread (ac3dec_thread_t * p_ac3dec) ...@@ -147,247 +138,178 @@ static int InitThread (ac3dec_thread_t * p_ac3dec)
aout_fifo.l_frame_size = AC3DEC_FRAME_SIZE; aout_fifo.l_frame_size = AC3DEC_FRAME_SIZE;
/* Creating the audio output fifo */ /* Creating the audio output fifo */
if ((p_ac3dec->p_aout_fifo = aout_CreateFifo(p_ac3dec->p_aout, &aout_fifo)) == NULL) if ((p_ac3dec_t->p_aout_fifo = aout_CreateFifo(p_ac3dec_t->p_aout, &aout_fifo)) == NULL)
{ {
return -1; return -1;
} }
intf_DbgMsg ("ac3dec debug: ac3 decoder thread %p initialized", p_ac3dec); /* InitBitstream has normally begun to read a PES packet, get its
* PTS/DTS */
if( !p_ac3dec_t->p_fifo->b_die )
{
BitstreamCallback( &p_ac3dec_t->ac3_decoder.bit_stream, 1 );
}
intf_DbgMsg("ac3dec debug: ac3 decoder thread %p initialized", p_ac3dec_t);
return 0; return 0;
} }
/***************************************************************************** /*****************************************************************************
* RunThread : ac3 decoder thread * RunThread : ac3 decoder thread
*****************************************************************************/ *****************************************************************************/
static void RunThread (ac3dec_thread_t * p_ac3dec) static void RunThread (ac3dec_thread_t * p_ac3dec_t)
{ {
int sync; int sync;
intf_DbgMsg ("ac3dec debug: running ac3 decoder thread (%p) (pid == %i)", p_ac3dec, getpid()); intf_DbgMsg ("ac3dec debug: running ac3 decoder thread (%p) (pid == %i)", p_ac3dec_t, getpid());
/* Initializing the ac3 decoder thread */ /* Initializing the ac3 decoder thread */
if (InitThread (p_ac3dec)) /* XXX?? */ if (InitThread (p_ac3dec_t)) /* XXX?? */
{ {
p_ac3dec->p_fifo->b_error = 1; p_ac3dec_t->p_fifo->b_error = 1;
} }
sync = 0; sync = 0;
p_ac3dec->sync_ptr = 0; p_ac3dec_t->sync_ptr = 0;
/* ac3 decoder thread's main loop */ /* ac3 decoder thread's main loop */
/* FIXME : do we have enough room to store the decoded frames ?? */ /* FIXME : do we have enough room to store the decoded frames ?? */
while ((!p_ac3dec->p_fifo->b_die) && (!p_ac3dec->p_fifo->b_error)) while ((!p_ac3dec_t->p_fifo->b_die) && (!p_ac3dec_t->p_fifo->b_error))
{ {
s16 * buffer; s16 * buffer;
ac3_sync_info_t sync_info; ac3_sync_info_t sync_info;
if (!sync) { /* have to find a synchro point */ if (!sync) {
int ptr; do {
ac3_byte_stream_t * p_byte_stream; GetBits(&p_ac3dec_t->ac3_decoder.bit_stream,8);
} while ((!p_ac3dec_t->sync_ptr) && (!p_ac3dec_t->p_fifo->b_die)
intf_DbgMsg ("ac3dec: sync"); && (!p_ac3dec_t->p_fifo->b_error));
p_byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
/* first read till next ac3 magic header */
do
{
ac3_byte_stream_next (p_byte_stream);
} while ((!p_ac3dec->sync_ptr) &&
(!p_ac3dec->p_fifo->b_die) &&
(!p_ac3dec->p_fifo->b_error));
/* skip the specified number of bytes */
if( p_ac3dec->p_fifo->b_die || p_ac3dec->p_fifo->b_error )
{
goto bad_frame;
}
ptr = p_ac3dec->sync_ptr;
while (--ptr && (!p_ac3dec->p_fifo->b_die) && (!p_ac3dec->p_fifo->b_error))
{
if (p_byte_stream->p_byte >= p_byte_stream->p_end)
{
ac3_byte_stream_next (p_byte_stream);
}
p_byte_stream->p_byte++;
}
if( p_ac3dec->p_fifo->b_die || p_ac3dec->p_fifo->b_error )
{
goto bad_frame;
}
/* we are in sync now */ /* we are in sync now */
sync = 1; sync = 1;
p_ac3dec->sync_ptr = 0;
} }
if (DECODER_FIFO_START(*p_ac3dec->p_fifo)->i_pts) if (DECODER_FIFO_START(*p_ac3dec_t->p_fifo)->i_pts)
{
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(*p_ac3dec->p_fifo)->i_pts;
DECODER_FIFO_START(*p_ac3dec->p_fifo)->i_pts = 0;
}
else
{ {
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE; p_ac3dec_t->p_aout_fifo->date[p_ac3dec_t->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START(*p_ac3dec_t->p_fifo)->i_pts;
DECODER_FIFO_START(*p_ac3dec_t->p_fifo)->i_pts = 0;
} else {
p_ac3dec_t->p_aout_fifo->date[p_ac3dec_t->p_aout_fifo->l_end_frame] =
LAST_MDATE;
} }
if (ac3_sync_frame (&p_ac3dec->ac3_decoder, &sync_info)) if (ac3_sync_frame (&p_ac3dec_t->ac3_decoder, &sync_info))
{ {
sync = 0; sync = 0;
goto bad_frame; goto bad_frame;
} }
p_ac3dec->p_aout_fifo->l_rate = sync_info.sample_rate; p_ac3dec_t->p_aout_fifo->l_rate = sync_info.sample_rate;
buffer = ((s16 *)p_ac3dec->p_aout_fifo->buffer) + (p_ac3dec->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE); buffer = ((s16 *)p_ac3dec_t->p_aout_fifo->buffer) +
(p_ac3dec_t->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE);
if (ac3_decode_frame (&p_ac3dec->ac3_decoder, buffer)) if (ac3_decode_frame (&p_ac3dec_t->ac3_decoder, buffer))
{ {
sync = 0; sync = 0;
goto bad_frame; goto bad_frame;
} }
vlc_mutex_lock (&p_ac3dec->p_aout_fifo->data_lock); vlc_mutex_lock (&p_ac3dec_t->p_aout_fifo->data_lock);
p_ac3dec->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE; p_ac3dec_t->p_aout_fifo->l_end_frame =
vlc_cond_signal (&p_ac3dec->p_aout_fifo->data_wait); (p_ac3dec_t->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
vlc_mutex_unlock (&p_ac3dec->p_aout_fifo->data_lock); vlc_cond_signal (&p_ac3dec_t->p_aout_fifo->data_wait);
vlc_mutex_unlock (&p_ac3dec_t->p_aout_fifo->data_lock);
bad_frame:
continue; bad_frame:
RealignBits(&p_ac3dec_t->ac3_decoder.bit_stream);
} }
/* If b_error is set, the ac3 decoder thread enters the error loop */ /* If b_error is set, the ac3 decoder thread enters the error loop */
if (p_ac3dec->p_fifo->b_error) if (p_ac3dec_t->p_fifo->b_error)
{ {
ErrorThread (p_ac3dec); ErrorThread (p_ac3dec_t);
} }
/* End of the ac3 decoder thread */ /* End of the ac3 decoder thread */
EndThread (p_ac3dec); EndThread (p_ac3dec_t);
} }
/***************************************************************************** /*****************************************************************************
* ErrorThread : ac3 decoder's RunThread() error loop * ErrorThread : ac3 decoder's RunThread() error loop
*****************************************************************************/ *****************************************************************************/
static void ErrorThread (ac3dec_thread_t * p_ac3dec) static void ErrorThread (ac3dec_thread_t * p_ac3dec_t)
{ {
/* We take the lock, because we are going to read/write the start/end /* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */ * indexes of the decoder fifo */
vlc_mutex_lock (&p_ac3dec->p_fifo->data_lock); vlc_mutex_lock (&p_ac3dec_t->p_fifo->data_lock);
/* Wait until a `die' order is sent */ /* Wait until a `die' order is sent */
while (!p_ac3dec->p_fifo->b_die) while (!p_ac3dec_t->p_fifo->b_die)
{ {
/* Trash all received PES packets */ /* Trash all received PES packets */
while (!DECODER_FIFO_ISEMPTY(*p_ac3dec->p_fifo)) while (!DECODER_FIFO_ISEMPTY(*p_ac3dec_t->p_fifo))
{ {
p_ac3dec->p_fifo->pf_delete_pes(p_ac3dec->p_fifo->p_packets_mgt, p_ac3dec_t->p_fifo->pf_delete_pes(p_ac3dec_t->p_fifo->p_packets_mgt,
DECODER_FIFO_START(*p_ac3dec->p_fifo)); DECODER_FIFO_START(*p_ac3dec_t->p_fifo));
DECODER_FIFO_INCSTART (*p_ac3dec->p_fifo); DECODER_FIFO_INCSTART (*p_ac3dec_t->p_fifo);
} }
/* Waiting for the input thread to put new PES packets in the fifo */ /* Waiting for the input thread to put new PES packets in the fifo */
vlc_cond_wait (&p_ac3dec->p_fifo->data_wait, vlc_cond_wait (&p_ac3dec_t->p_fifo->data_wait,
&p_ac3dec->p_fifo->data_lock); &p_ac3dec_t->p_fifo->data_lock);
} }
/* We can release the lock before leaving */ /* We can release the lock before leaving */
vlc_mutex_unlock (&p_ac3dec->p_fifo->data_lock); vlc_mutex_unlock (&p_ac3dec_t->p_fifo->data_lock);
} }
/***************************************************************************** /*****************************************************************************
* EndThread : ac3 decoder thread destruction * EndThread : ac3 decoder thread destruction
*****************************************************************************/ *****************************************************************************/
static void EndThread (ac3dec_thread_t * p_ac3dec) static void EndThread (ac3dec_thread_t * p_ac3dec_t)
{ {
intf_DbgMsg ("ac3dec debug: destroying ac3 decoder thread %p", p_ac3dec); intf_DbgMsg ("ac3dec debug: destroying ac3 decoder thread %p", p_ac3dec_t);
/* If the audio output fifo was created, we destroy it */ /* If the audio output fifo was created, we destroy it */
if (p_ac3dec->p_aout_fifo != NULL) if (p_ac3dec_t->p_aout_fifo != NULL)
{ {
aout_DestroyFifo (p_ac3dec->p_aout_fifo); aout_DestroyFifo (p_ac3dec_t->p_aout_fifo);
/* Make sure the output thread leaves the NextFrame() function */ /* Make sure the output thread leaves the NextFrame() function */
vlc_mutex_lock (&(p_ac3dec->p_aout_fifo->data_lock)); vlc_mutex_lock (&(p_ac3dec_t->p_aout_fifo->data_lock));
vlc_cond_signal (&(p_ac3dec->p_aout_fifo->data_wait)); vlc_cond_signal (&(p_ac3dec_t->p_aout_fifo->data_wait));
vlc_mutex_unlock (&(p_ac3dec->p_aout_fifo->data_lock)); vlc_mutex_unlock (&(p_ac3dec_t->p_aout_fifo->data_lock));
} }
/* Destroy descriptor */ /* Destroy descriptor */
free( p_ac3dec->p_config ); free( p_ac3dec_t->p_config );
free( p_ac3dec ); free( p_ac3dec_t );
intf_DbgMsg ("ac3dec debug: ac3 decoder thread %p destroyed", p_ac3dec); intf_DbgMsg ("ac3dec debug: ac3 decoder thread %p destroyed", p_ac3dec_t);
} }
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream) /*****************************************************************************
* BitstreamCallback: Import parameters from the new data/PES packet
*****************************************************************************
* This function is called by input's NextDataPacket.
*****************************************************************************/
static void BitstreamCallback ( bit_stream_t * p_bit_stream,
boolean_t b_new_pes)
{ {
ac3dec_thread_t * p_ac3dec = p_byte_stream->info;
/* We are looking for the next TS packet that contains real data, ac3dec_thread_t *p_ac3dec_t=(ac3dec_thread_t *)p_bit_stream->p_callback_arg;
* and not just a PES header */
do if( b_new_pes )
{ {
/* We were reading the last TS packet of this PES packet... It's int ptr;
* time to jump to the next PES packet */
if (p_ac3dec->p_data->p_next == NULL) ptr = *(p_bit_stream->p_byte + 1);
{ ptr <<= 8;
int ptr; ptr |= *(p_bit_stream->p_byte + 2);
p_ac3dec_t->sync_ptr = ptr;
/* We are going to read/write the start and end indexes of the p_bit_stream->p_byte += 3;
* decoder fifo and to use the fifo's conditional variable, }
* that's why we need to take the lock before */
vlc_mutex_lock (&p_ac3dec->p_fifo->data_lock);
/* Is the input thread dying ? */
if (p_ac3dec->p_fifo->b_die)
{
vlc_mutex_unlock (&p_ac3dec->p_fifo->data_lock);
return;
}
/* We should increase the start index of the decoder fifo, but
* if we do this now, the input thread could overwrite the
* pointer to the current PES packet, and we weren't able to
* give it back to the netlist. That's why we free the PES
* packet first. */
p_ac3dec->p_fifo->pf_delete_pes(p_ac3dec->p_fifo->p_packets_mgt,
DECODER_FIFO_START(*p_ac3dec->p_fifo));
DECODER_FIFO_INCSTART (*p_ac3dec->p_fifo);
while (DECODER_FIFO_ISEMPTY(*p_ac3dec->p_fifo))
{
vlc_cond_wait(&p_ac3dec->p_fifo->data_wait, &p_ac3dec->p_fifo->data_lock);
if (p_ac3dec->p_fifo->b_die)
{
vlc_mutex_unlock (&p_ac3dec->p_fifo->data_lock);
return;
}
}
/* The next byte could be found in the next PES packet */
p_ac3dec->p_data = DECODER_FIFO_START(*p_ac3dec->p_fifo)->p_first;
/* parse ac3 magic header */
ptr = *(p_ac3dec->p_data->p_payload_start + 1);
ptr <<= 8;
ptr |= *(p_ac3dec->p_data->p_payload_start + 2);
p_ac3dec->sync_ptr = ptr;
p_ac3dec->p_data->p_payload_start += 3;
/* We can release the fifo's data lock */
vlc_mutex_unlock (&p_ac3dec->p_fifo->data_lock);
}
/* Perhaps the next TS packet of the current PES packet contains
* real data (ie its payload's size is greater than 0) */
else
{
p_ac3dec->p_data = p_ac3dec->p_data->p_next;
}
} while (p_ac3dec->p_data->p_payload_start == p_ac3dec->p_data->p_payload_end);
p_byte_stream->p_byte = p_ac3dec->p_data->p_payload_start;
p_byte_stream->p_end = p_ac3dec->p_data->p_payload_end;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_decoder_thread.h : ac3 decoder thread interface * ac3_decoder_thread.h : ac3 decoder thread interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder_thread.h,v 1.4 2001/03/21 13:42:34 sam Exp $ * $Id: ac3_decoder_thread.h,v 1.5 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* *
...@@ -30,12 +30,14 @@ typedef struct ac3dec_thread_s ...@@ -30,12 +30,14 @@ typedef struct ac3dec_thread_s
* Thread properties * Thread properties
*/ */
vlc_thread_t thread_id; /* id for thread functions */ vlc_thread_t thread_id; /* id for thread functions */
// bit_stream_t bit_stream;
/* /*
* Input properties * Input properties
*/ */
decoder_fifo_t * p_fifo; /* stores the PES stream data */ decoder_fifo_t * p_fifo; /* stores the PES stream data */
data_packet_t * p_data; // data_packet_t * p_data;
int sync_ptr; /* sync ptr from ac3 magic header */ int sync_ptr; /* sync ptr from ac3 magic header */
adec_config_t * p_config; adec_config_t * p_config;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_downmix.c: ac3 downmix functions * ac3_downmix.c: ac3 downmix functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_downmix.c,v 1.19 2001/04/06 09:15:47 sam Exp $ * $Id: ac3_downmix.c,v 1.20 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca> * Aaron Holtzman <aholtzma@engr.uvic.ca>
...@@ -24,10 +24,15 @@ ...@@ -24,10 +24,15 @@
*****************************************************************************/ *****************************************************************************/
#include "defs.h" #include "defs.h"
#include "int_types.h" #include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_internal.h" #include "ac3_internal.h"
#include "ac3_downmix.h" #include "ac3_downmix.h"
/* Pre-scaled downmix coefficients */ /* Pre-scaled downmix coefficients */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_downmix_c.c: ac3 downmix functions * ac3_downmix_c.c: ac3 downmix functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_downmix_c.c,v 1.4 2001/04/06 09:15:47 sam Exp $ * $Id: ac3_downmix_c.c,v 1.5 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Renaud Dartus <reno@videolan.org> * Authors: Renaud Dartus <reno@videolan.org>
* Aaron Holtzman <aholtzma@engr.uvic.ca> * Aaron Holtzman <aholtzma@engr.uvic.ca>
...@@ -24,7 +24,13 @@ ...@@ -24,7 +24,13 @@
#include "defs.h" #include "defs.h"
#include "int_types.h" #include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_internal.h" #include "ac3_internal.h"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_exponent.c: ac3 exponent calculations * ac3_exponent.c: ac3 exponent calculations
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_exponent.c,v 1.22 2001/04/06 09:15:47 sam Exp $ * $Id: ac3_exponent.c,v 1.23 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org> * Michel Lespinasse <walken@zoy.org>
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include "intf_msg.h" #include "intf_msg.h"
#include "ac3_bit_stream.h"
#include "ac3_internal.h" #include "ac3_internal.h"
static const s16 exps_1[128] = static const s16 exps_1[128] =
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_imdct.c: ac3 DCT * ac3_imdct.c: ac3 DCT
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_imdct.c,v 1.14 2001/03/21 13:42:34 sam Exp $ * $Id: ac3_imdct.c,v 1.15 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca> * Aaron Holtzman <aholtzma@engr.uvic.ca>
...@@ -28,7 +28,14 @@ ...@@ -28,7 +28,14 @@
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include "int_types.h" #include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_internal.h" #include "ac3_internal.h"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_mantissa.c: ac3 mantissa computation * ac3_mantissa.c: ac3 mantissa computation
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_mantissa.c,v 1.22 2001/04/06 09:15:47 sam Exp $ * $Id: ac3_mantissa.c,v 1.23 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca> * Aaron Holtzman <aholtzma@engr.uvic.ca>
...@@ -25,8 +25,6 @@ ...@@ -25,8 +25,6 @@
#include "defs.h" #include "defs.h"
#include <string.h> /* memcpy(), memset() */
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h" #include "threads.h"
...@@ -41,7 +39,6 @@ ...@@ -41,7 +39,6 @@
#include "ac3_decoder_thread.h" #include "ac3_decoder_thread.h"
#include "ac3_internal.h" #include "ac3_internal.h"
#include "ac3_bit_stream.h"
#include "intf_msg.h" #include "intf_msg.h"
...@@ -267,7 +264,8 @@ static __inline__ u16 dither_gen (mantissa_t * p_mantissa) ...@@ -267,7 +264,8 @@ static __inline__ u16 dither_gen (mantissa_t * p_mantissa)
/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */ /* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */
static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp) static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 dithflag,
u16 exp)
{ {
u32 group_code; u32 group_code;
...@@ -275,7 +273,7 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp) ...@@ -275,7 +273,7 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
switch (bap) switch (bap)
{ {
case 0: case 0:
if (p_ac3dec->audblk.dithflag[exp]) if (dithflag)
{ {
return ( dither_gen(&p_ac3dec->mantissa) * exp_lut[exp] ); return ( dither_gen(&p_ac3dec->mantissa) * exp_lut[exp] );
} }
...@@ -284,13 +282,15 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp) ...@@ -284,13 +282,15 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
case 1: case 1:
if (p_ac3dec->mantissa.q_1_pointer >= 0) if (p_ac3dec->mantissa.q_1_pointer >= 0)
{ {
return (p_ac3dec->mantissa.q_1[p_ac3dec->mantissa.q_1_pointer--] * exp_lut[exp]); return (p_ac3dec->mantissa.q_1[p_ac3dec->mantissa.q_1_pointer--] *
exp_lut[exp]);
} }
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),5)) >= 27) if ((group_code = GetBits (&p_ac3dec->bit_stream,5)) >= 27)
{ {
intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (1)" ); intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (1)" );
} }
p_ac3dec->total_bits_read += 5;
p_ac3dec->mantissa.q_1[ 1 ] = q_1_1[ group_code ]; p_ac3dec->mantissa.q_1[ 1 ] = q_1_1[ group_code ];
p_ac3dec->mantissa.q_1[ 0 ] = q_1_2[ group_code ]; p_ac3dec->mantissa.q_1[ 0 ] = q_1_2[ group_code ];
...@@ -302,13 +302,15 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp) ...@@ -302,13 +302,15 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
case 2: case 2:
if (p_ac3dec->mantissa.q_2_pointer >= 0) if (p_ac3dec->mantissa.q_2_pointer >= 0)
{ {
return (p_ac3dec->mantissa.q_2[p_ac3dec->mantissa.q_2_pointer--] * exp_lut[exp]); return (p_ac3dec->mantissa.q_2[p_ac3dec->mantissa.q_2_pointer--] *
exp_lut[exp]);
} }
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),7)) >= 125) if ((group_code = GetBits (&p_ac3dec->bit_stream,7)) >= 125)
{ {
intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (2)" ); intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (2)" );
} }
p_ac3dec->total_bits_read += 7;
p_ac3dec->mantissa.q_2[ 1 ] = q_2_1[ group_code ]; p_ac3dec->mantissa.q_2[ 1 ] = q_2_1[ group_code ];
p_ac3dec->mantissa.q_2[ 0 ] = q_2_2[ group_code ]; p_ac3dec->mantissa.q_2[ 0 ] = q_2_2[ group_code ];
...@@ -318,23 +320,26 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp) ...@@ -318,23 +320,26 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
return (q_2_0[ group_code ] * exp_lut[exp]); return (q_2_0[ group_code ] * exp_lut[exp]);
case 3: case 3:
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),3)) >= 7) if ((group_code = GetBits (&p_ac3dec->bit_stream,3)) >= 7)
{ {
intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (3)" ); intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (3)" );
} }
p_ac3dec->total_bits_read += 7;
return (q_3[group_code] * exp_lut[exp]); return (q_3[group_code] * exp_lut[exp]);
case 4: case 4:
if (p_ac3dec->mantissa.q_4_pointer >= 0) if (p_ac3dec->mantissa.q_4_pointer >= 0)
{ {
return (p_ac3dec->mantissa.q_4[p_ac3dec->mantissa.q_4_pointer--] * exp_lut[exp]); return (p_ac3dec->mantissa.q_4[p_ac3dec->mantissa.q_4_pointer--] *
exp_lut[exp]);
} }
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),7)) >= 121) if ((group_code = GetBits (&p_ac3dec->bit_stream,7)) >= 121)
{ {
intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (4)" ); intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (4)" );
} }
p_ac3dec->total_bits_read += 7;
p_ac3dec->mantissa.q_4[ 0 ] = q_4_1[ group_code ]; p_ac3dec->mantissa.q_4[ 0 ] = q_4_1[ group_code ];
...@@ -343,16 +348,18 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp) ...@@ -343,16 +348,18 @@ static __inline__ float float_get (ac3dec_t * p_ac3dec, u16 bap, u16 exp)
return (q_4_0[ group_code ] * exp_lut[exp]); return (q_4_0[ group_code ] * exp_lut[exp]);
case 5: case 5:
if ((group_code = bitstream_get(&(p_ac3dec->bit_stream),4)) >= 15) if ((group_code = GetBits (&p_ac3dec->bit_stream,4)) >= 15)
{ {
intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (5)" ); intf_WarnMsg ( 1, "ac3dec error: invalid mantissa (5)" );
} }
p_ac3dec->total_bits_read += 4;
return (q_5[group_code] * exp_lut[exp]); return (q_5[group_code] * exp_lut[exp]);
default: default:
group_code = bitstream_get(&(p_ac3dec->bit_stream),qnttztab[bap]); group_code = GetBits (&p_ac3dec->bit_stream,qnttztab[bap]);
group_code <<= 16 - qnttztab[bap]; group_code <<= 16 - qnttztab[bap];
p_ac3dec->total_bits_read += qnttztab[bap];
return ((s16)(group_code) * exp_lut[exp]); return ((s16)(group_code) * exp_lut[exp]);
} }
...@@ -371,7 +378,8 @@ static __inline__ void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch) ...@@ -371,7 +378,8 @@ static __inline__ void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch)
{ {
if (!p_ac3dec->audblk.cplbndstrc[sub_bnd++]) if (!p_ac3dec->audblk.cplbndstrc[sub_bnd++])
{ {
cpl_exp_tmp = p_ac3dec->audblk.cplcoexp[ch][bnd] + 3 * p_ac3dec->audblk.mstrcplco[ch]; cpl_exp_tmp = p_ac3dec->audblk.cplcoexp[ch][bnd] +
3 * p_ac3dec->audblk.mstrcplco[ch];
if (p_ac3dec->audblk.cplcoexp[ch][bnd] == 15) if (p_ac3dec->audblk.cplcoexp[ch][bnd] == 15)
{ {
cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 11; cpl_mant_tmp = (p_ac3dec->audblk.cplcomant[ch][bnd]) << 11;
...@@ -397,7 +405,7 @@ static __inline__ void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch) ...@@ -397,7 +405,7 @@ static __inline__ void uncouple_channel (ac3dec_t * p_ac3dec, u32 ch)
* so the channels are uncorrelated */ * so the channels are uncorrelated */
if (p_ac3dec->audblk.dithflag[ch] && !p_ac3dec->audblk.cpl_bap[i]) if (p_ac3dec->audblk.dithflag[ch] && !p_ac3dec->audblk.cpl_bap[i])
{ {
p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * dither_gen(&p_ac3dec->mantissa) * p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * dither_gen(&p_ac3dec->mantissa) *
exp_lut[p_ac3dec->audblk.cpl_exp[i]]; exp_lut[p_ac3dec->audblk.cpl_exp[i]];
} else { } else {
p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * p_ac3dec->audblk.cplfbw[i]; p_ac3dec->coeffs.fbw[ch][i] = cpl_coord * p_ac3dec->audblk.cplfbw[i];
...@@ -422,18 +430,21 @@ void mantissa_unpack (ac3dec_t * p_ac3dec) ...@@ -422,18 +430,21 @@ void mantissa_unpack (ac3dec_t * p_ac3dec)
{ {
for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++)
{ {
p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]); p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j],
p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j]);
} }
} }
/* 2 */ /* 2 */
for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++)
{ {
p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]); p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j],
p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j]);
} }
for (j = p_ac3dec->audblk.cplstrtmant; j < p_ac3dec->audblk.cplendmant; j++) for (j = p_ac3dec->audblk.cplstrtmant; j < p_ac3dec->audblk.cplendmant; j++)
{ {
p_ac3dec->audblk.cplfbw[j] = float_get (p_ac3dec, p_ac3dec->audblk.cpl_bap[j], p_ac3dec->audblk.cpl_exp[j]); p_ac3dec->audblk.cplfbw[j] = float_get (p_ac3dec, p_ac3dec->audblk.cpl_bap[j], 0,
p_ac3dec->audblk.cpl_exp[j]);
} }
uncouple_channel (p_ac3dec, i); uncouple_channel (p_ac3dec, i);
...@@ -442,7 +453,8 @@ void mantissa_unpack (ac3dec_t * p_ac3dec) ...@@ -442,7 +453,8 @@ void mantissa_unpack (ac3dec_t * p_ac3dec)
{ {
for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++)
{ {
p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]); p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j],
p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j]);
} }
if (p_ac3dec->audblk.chincpl[i]) if (p_ac3dec->audblk.chincpl[i])
{ {
...@@ -456,7 +468,8 @@ void mantissa_unpack (ac3dec_t * p_ac3dec) ...@@ -456,7 +468,8 @@ void mantissa_unpack (ac3dec_t * p_ac3dec)
{ {
for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++) for (j = 0; j < p_ac3dec->audblk.endmant[i]; j++)
{ {
p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j], p_ac3dec->audblk.fbw_exp[i][j]); p_ac3dec->coeffs.fbw[i][j] = float_get (p_ac3dec, p_ac3dec->audblk.fbw_bap[i][j],
p_ac3dec->audblk.dithflag[i], p_ac3dec->audblk.fbw_exp[i][j]);
} }
} }
} }
...@@ -466,7 +479,8 @@ void mantissa_unpack (ac3dec_t * p_ac3dec) ...@@ -466,7 +479,8 @@ void mantissa_unpack (ac3dec_t * p_ac3dec)
/* There are always 7 mantissas for lfe, no dither for lfe */ /* There are always 7 mantissas for lfe, no dither for lfe */
for (j = 0; j < 7; j++) for (j = 0; j < 7; j++)
{ {
p_ac3dec->coeffs.lfe[j] = float_get (p_ac3dec, p_ac3dec->audblk.lfe_bap[j], p_ac3dec->audblk.lfe_exp[j]); p_ac3dec->coeffs.lfe[j] = float_get (p_ac3dec, p_ac3dec->audblk.lfe_bap[j], 0,
p_ac3dec->audblk.lfe_exp[j]);
} }
} }
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_parse.c: ac3 parsing procedures * ac3_parse.c: ac3 parsing procedures
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: ac3_parse.c,v 1.17 2001/04/06 09:15:47 sam Exp $ * $Id: ac3_parse.c,v 1.18 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca> * Aaron Holtzman <aholtzma@engr.uvic.ca>
...@@ -25,10 +25,9 @@ ...@@ -25,10 +25,9 @@
#include "defs.h" #include "defs.h"
#include <string.h> /* memcpy(), memset() */
#include "config.h" #include "config.h"
#include "common.h" #include "common.h"
#include "threads.h" #include "threads.h"
#include "mtime.h" #include "mtime.h"
...@@ -42,7 +41,6 @@ ...@@ -42,7 +41,6 @@
#include "ac3_decoder_thread.h" #include "ac3_decoder_thread.h"
#include "ac3_internal.h" #include "ac3_internal.h"
#include "ac3_bit_stream.h"
/* Misc LUT */ /* Misc LUT */
static const u16 nfchans[] = { 2, 1, 2, 3, 3, 4, 4, 5 }; static const u16 nfchans[] = { 2, 1, 2, 3, 3, 4, 4, 5 };
...@@ -103,30 +101,38 @@ void parse_audblk_stats (ac3dec_t * p_ac3dec); ...@@ -103,30 +101,38 @@ void parse_audblk_stats (ac3dec_t * p_ac3dec);
/* Parse a syncinfo structure */ /* Parse a syncinfo structure */
int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info) int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info)
{ {
int buf; ac3dec_thread_t * p_ac3dec_t = (ac3dec_thread_t *) p_ac3dec->bit_stream.p_callback_arg;
p_ac3dec->bit_stream.total_bits_read = 0; p_ac3dec->total_bits_read = 0;
p_ac3dec->bit_stream.i_available = 0; p_ac3dec->i_available = 0;
/* sync word - should be 0x0b77 */ /* sync word - should be 0x0b77 */
if( (buf = bitstream_get(&(p_ac3dec->bit_stream),16)) != 0x0b77) 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))
{ {
return 1; 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 */ /* Get crc1 - we don't actually use this data though */
bitstream_get(&(p_ac3dec->bit_stream),16); GetBits (&p_ac3dec->bit_stream,16);
/* Get the sampling rate */ /* Get the sampling rate */
p_ac3dec->syncinfo.fscod = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->syncinfo.fscod = GetBits (&p_ac3dec->bit_stream,2);
if (p_ac3dec->syncinfo.fscod >= 3) if (p_ac3dec->syncinfo.fscod >= 3)
{ {
p_ac3dec->total_bits_read += 34;
return 1; return 1;
} }
/* Get the frame size code */ /* Get the frame size code */
p_ac3dec->syncinfo.frmsizecod = bitstream_get(&(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) if (p_ac3dec->syncinfo.frmsizecod >= 38)
{ {
...@@ -149,7 +155,7 @@ int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info) ...@@ -149,7 +155,7 @@ int ac3_sync_frame (ac3dec_t * p_ac3dec, ac3_sync_info_t * p_sync_info)
int parse_bsi (ac3dec_t * p_ac3dec) int parse_bsi (ac3dec_t * p_ac3dec)
{ {
/* Check the AC-3 version number */ /* Check the AC-3 version number */
p_ac3dec->bsi.bsid = bitstream_get(&(p_ac3dec->bit_stream),5); p_ac3dec->bsi.bsid = GetBits (&p_ac3dec->bit_stream,5);
if (p_ac3dec->bsi.bsid > 8) if (p_ac3dec->bsi.bsid > 8)
{ {
...@@ -157,10 +163,11 @@ int parse_bsi (ac3dec_t * p_ac3dec) ...@@ -157,10 +163,11 @@ int parse_bsi (ac3dec_t * p_ac3dec)
} }
/* Get the audio service provided by the stream */ /* Get the audio service provided by the stream */
p_ac3dec->bsi.bsmod = bitstream_get(&(p_ac3dec->bit_stream),3); p_ac3dec->bsi.bsmod = GetBits (&p_ac3dec->bit_stream,3);
/* Get the audio coding mode (ie how many channels)*/ /* Get the audio coding mode (ie how many channels)*/
p_ac3dec->bsi.acmod = bitstream_get(&(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 /* Predecode the number of full bandwidth channels as we use this
* number a lot */ * number a lot */
p_ac3dec->bsi.nfchans = nfchans[p_ac3dec->bsi.acmod]; p_ac3dec->bsi.nfchans = nfchans[p_ac3dec->bsi.acmod];
...@@ -168,115 +175,129 @@ int parse_bsi (ac3dec_t * p_ac3dec) ...@@ -168,115 +175,129 @@ int parse_bsi (ac3dec_t * p_ac3dec)
/* If it is in use, get the centre channel mix level */ /* If it is in use, get the centre channel mix level */
if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1)) if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
{ {
p_ac3dec->bsi.cmixlev = bitstream_get(&(p_ac3dec->bit_stream),2); 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 it is in use, get the surround channel mix level */
if (p_ac3dec->bsi.acmod & 0x4) if (p_ac3dec->bsi.acmod & 0x4)
{ {
p_ac3dec->bsi.surmixlev = bitstream_get(&(p_ac3dec->bit_stream),2); 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 */ /* Get the dolby surround mode if in 2/0 mode */
if (p_ac3dec->bsi.acmod == 0x2) if (p_ac3dec->bsi.acmod == 0x2)
{ {
p_ac3dec->bsi.dsurmod = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->bsi.dsurmod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
} }
/* Is the low frequency effects channel on? */ /* Is the low frequency effects channel on? */
p_ac3dec->bsi.lfeon = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->bsi.lfeon = GetBits (&p_ac3dec->bit_stream,1);
/* Get the dialogue normalization level */ /* Get the dialogue normalization level */
p_ac3dec->bsi.dialnorm = bitstream_get(&(p_ac3dec->bit_stream),5); p_ac3dec->bsi.dialnorm = GetBits (&p_ac3dec->bit_stream,5);
/* Does compression gain exist? */ /* Does compression gain exist? */
if ((p_ac3dec->bsi.compre = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.compre = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get compression gain */ /* Get compression gain */
p_ac3dec->bsi.compr = bitstream_get(&(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? */ /* Does language code exist? */
if ((p_ac3dec->bsi.langcode = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.langcode = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get langauge code */ /* Get langauge code */
p_ac3dec->bsi.langcod = bitstream_get(&(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? */ /* Does audio production info exist? */
if ((p_ac3dec->bsi.audprodie = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.audprodie = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get mix level */ /* Get mix level */
p_ac3dec->bsi.mixlevel = bitstream_get(&(p_ac3dec->bit_stream),5); p_ac3dec->bsi.mixlevel = GetBits (&p_ac3dec->bit_stream,5);
/* Get room type */ /* Get room type */
p_ac3dec->bsi.roomtyp = bitstream_get(&(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 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 */ /* Get the dialogue normalization level two */
p_ac3dec->bsi.dialnorm2 = bitstream_get(&(p_ac3dec->bit_stream),5); p_ac3dec->bsi.dialnorm2 = GetBits (&p_ac3dec->bit_stream,5);
/* Does compression gain two exist? */ /* Does compression gain two exist? */
if ((p_ac3dec->bsi.compr2e = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.compr2e = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get compression gain two */ /* Get compression gain two */
p_ac3dec->bsi.compr2 = bitstream_get(&(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? */ /* Does language code two exist? */
if ((p_ac3dec->bsi.langcod2e = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.langcod2e = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get langauge code two */ /* Get langauge code two */
p_ac3dec->bsi.langcod2 = bitstream_get(&(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? */ /* Does audio production info two exist? */
if ((p_ac3dec->bsi.audprodi2e = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.audprodi2e = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get mix level two */ /* Get mix level two */
p_ac3dec->bsi.mixlevel2 = bitstream_get(&(p_ac3dec->bit_stream),5); p_ac3dec->bsi.mixlevel2 = GetBits (&p_ac3dec->bit_stream,5);
/* Get room type two */ /* Get room type two */
p_ac3dec->bsi.roomtyp2 = bitstream_get(&(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 */ /* Get the copyright bit */
p_ac3dec->bsi.copyrightb = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->bsi.copyrightb = GetBits (&p_ac3dec->bit_stream,1);
/* Get the original bit */ /* Get the original bit */
p_ac3dec->bsi.origbs = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->bsi.origbs = GetBits (&p_ac3dec->bit_stream,1);
/* Does timecode one exist? */ /* Does timecode one exist? */
if ((p_ac3dec->bsi.timecod1e = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.timecod1e = GetBits (&p_ac3dec->bit_stream,1)))
{ {
p_ac3dec->bsi.timecod1 = bitstream_get(&(p_ac3dec->bit_stream),14); p_ac3dec->bsi.timecod1 = GetBits (&p_ac3dec->bit_stream,14);
p_ac3dec->total_bits_read += 14;
} }
/* Does timecode two exist? */ /* Does timecode two exist? */
if ((p_ac3dec->bsi.timecod2e = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.timecod2e = GetBits (&p_ac3dec->bit_stream,1)))
{ {
p_ac3dec->bsi.timecod2 = bitstream_get(&(p_ac3dec->bit_stream),14); p_ac3dec->bsi.timecod2 = GetBits (&p_ac3dec->bit_stream,14);
p_ac3dec->total_bits_read += 14;
} }
/* Does addition info exist? */ /* Does addition info exist? */
if ((p_ac3dec->bsi.addbsie = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->bsi.addbsie = GetBits (&p_ac3dec->bit_stream,1)))
{ {
u32 i; u32 i;
/* Get how much info is there */ /* Get how much info is there */
p_ac3dec->bsi.addbsil = bitstream_get(&(p_ac3dec->bit_stream),6); p_ac3dec->bsi.addbsil = GetBits (&p_ac3dec->bit_stream,6);
/* Get the additional info */ /* Get the additional info */
for (i=0;i<(p_ac3dec->bsi.addbsil + 1);i++) for (i=0;i<(p_ac3dec->bsi.addbsil + 1);i++)
{ {
p_ac3dec->bsi.addbsi[i] = bitstream_get(&(p_ac3dec->bit_stream),8); 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 STATS #ifdef STATS
parse_bsi_stats (p_ac3dec); parse_bsi_stats (p_ac3dec);
#endif #endif
...@@ -292,35 +313,39 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -292,35 +313,39 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
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 ? */ /* Is this channel an interleaved 256 + 256 block ? */
p_ac3dec->audblk.blksw[i] = bitstream_get(&(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? */ /* Should we dither this channel? */
p_ac3dec->audblk.dithflag[i] = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.dithflag[i] = GetBits (&p_ac3dec->bit_stream,1);
} }
/* Does dynamic range control exist? */ /* Does dynamic range control exist? */
if ((p_ac3dec->audblk.dynrnge = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->audblk.dynrnge = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get dynamic range info */ /* Get dynamic range info */
p_ac3dec->audblk.dynrng = bitstream_get(&(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 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? */ /* Does dynamic range control two exist? */
if ((p_ac3dec->audblk.dynrng2e = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->audblk.dynrng2e = GetBits (&p_ac3dec->bit_stream,1)))
{ {
/* Get dynamic range info */ /* Get dynamic range info */
p_ac3dec->audblk.dynrng2 = bitstream_get(&(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? */ /* Does coupling strategy exist? */
p_ac3dec->audblk.cplstre = bitstream_get(&(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)) if ((!blknum) && (!p_ac3dec->audblk.cplstre))
{ {
...@@ -330,19 +355,21 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -330,19 +355,21 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->audblk.cplstre) if (p_ac3dec->audblk.cplstre)
{ {
/* Is coupling turned on? */ /* Is coupling turned on? */
if ((p_ac3dec->audblk.cplinu = bitstream_get(&(p_ac3dec->bit_stream),1))) if ((p_ac3dec->audblk.cplinu = GetBits (&p_ac3dec->bit_stream,1)))
{ {
int nb_coupled_channels; int nb_coupled_channels;
nb_coupled_channels = 0; nb_coupled_channels = 0;
for (i=0; i < p_ac3dec->bsi.nfchans; i++) for (i=0; i < p_ac3dec->bsi.nfchans; i++)
{ {
p_ac3dec->audblk.chincpl[i] = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.chincpl[i] = GetBits (&p_ac3dec->bit_stream,1);
if (p_ac3dec->audblk.chincpl[i]) if (p_ac3dec->audblk.chincpl[i])
{ {
nb_coupled_channels++; nb_coupled_channels++;
} }
} }
p_ac3dec->total_bits_read += p_ac3dec->bsi.nfchans;
if (nb_coupled_channels < 2) if (nb_coupled_channels < 2)
{ {
return 1; return 1;
...@@ -350,10 +377,12 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -350,10 +377,12 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->bsi.acmod == 0x2) if (p_ac3dec->bsi.acmod == 0x2)
{ {
p_ac3dec->audblk.phsflginu = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.phsflginu = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
} }
p_ac3dec->audblk.cplbegf = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.cplbegf = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cplendf = bitstream_get(&(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) if (p_ac3dec->audblk.cplbegf > p_ac3dec->audblk.cplendf + 2)
{ {
...@@ -372,10 +401,12 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -372,10 +401,12 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
for (i=1; i< p_ac3dec->audblk.ncplsubnd; i++) for (i=1; i< p_ac3dec->audblk.ncplsubnd; i++)
{ {
p_ac3dec->audblk.cplbndstrc[i] = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.cplbndstrc[i] = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->audblk.ncplbnd -= p_ac3dec->audblk.cplbndstrc[i]; 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)
...@@ -389,7 +420,7 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -389,7 +420,7 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
} }
/* Is there new coupling co-ordinate info? */ /* Is there new coupling co-ordinate info? */
p_ac3dec->audblk.cplcoe[i] = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.cplcoe[i] = GetBits (&p_ac3dec->bit_stream,1);
if ((!blknum) && (!p_ac3dec->audblk.cplcoe[i])) if ((!blknum) && (!p_ac3dec->audblk.cplcoe[i]))
{ {
...@@ -398,14 +429,17 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -398,14 +429,17 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->audblk.cplcoe[i]) if (p_ac3dec->audblk.cplcoe[i])
{ {
p_ac3dec->audblk.mstrcplco[i] = bitstream_get(&(p_ac3dec->bit_stream),2); 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++) for (j=0;j < p_ac3dec->audblk.ncplbnd; j++)
{ {
p_ac3dec->audblk.cplcoexp[i][j] = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.cplcoexp[i][j] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cplcomant[i][j] = bitstream_get(&(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 we're in dual mono mode, there's going to be some phase info */
if ((p_ac3dec->bsi.acmod == 0x2) && p_ac3dec->audblk.phsflginu && if ((p_ac3dec->bsi.acmod == 0x2) && p_ac3dec->audblk.phsflginu &&
...@@ -413,8 +447,9 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -413,8 +447,9 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
{ {
for (j=0; j < p_ac3dec->audblk.ncplbnd; j++) for (j=0; j < p_ac3dec->audblk.ncplbnd; j++)
{ {
p_ac3dec->audblk.phsflg[j] = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.phsflg[j] = GetBits (&p_ac3dec->bit_stream,1);
} }
p_ac3dec->total_bits_read += p_ac3dec->audblk.ncplbnd;
} }
} }
...@@ -422,7 +457,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -422,7 +457,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
/* If we're in dual mono mode, there may be a rematrix strategy */ /* If we're in dual mono mode, there may be a rematrix strategy */
if (p_ac3dec->bsi.acmod == 0x2) if (p_ac3dec->bsi.acmod == 0x2)
{ {
p_ac3dec->audblk.rematstr = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.rematstr = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if ((!blknum) && (!p_ac3dec->audblk.rematstr)) if ((!blknum) && (!p_ac3dec->audblk.rematstr))
{ {
...@@ -435,29 +471,33 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -435,29 +471,33 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
{ {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
p_ac3dec->audblk.rematflg[i] = bitstream_get(&(p_ac3dec->bit_stream),1); 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) if ((p_ac3dec->audblk.cplbegf > 2) && p_ac3dec->audblk.cplinu)
{ {
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
p_ac3dec->audblk.rematflg[i] = bitstream_get(&(p_ac3dec->bit_stream),1); 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) if ((p_ac3dec->audblk.cplbegf <= 2) && p_ac3dec->audblk.cplinu)
{ {
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
p_ac3dec->audblk.rematflg[i] = bitstream_get(&(p_ac3dec->bit_stream),1); 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) if ((p_ac3dec->audblk.cplbegf == 0) && p_ac3dec->audblk.cplinu)
{ {
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
p_ac3dec->audblk.rematflg[i] = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.rematflg[i] = GetBits (&p_ac3dec->bit_stream,1);
} }
p_ac3dec->total_bits_read += 2;
} }
} }
} }
...@@ -465,7 +505,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -465,7 +505,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->audblk.cplinu) if (p_ac3dec->audblk.cplinu)
{ {
/* Get the coupling channel exponent strategy */ /* Get the coupling channel exponent strategy */
p_ac3dec->audblk.cplexpstr = bitstream_get(&(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)) if ((!blknum) && (p_ac3dec->audblk.cplexpstr == EXP_REUSE))
{ {
...@@ -486,7 +527,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -486,7 +527,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
for (i = 0; i < p_ac3dec->bsi.nfchans; i++) for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
{ {
p_ac3dec->audblk.chexpstr[i] = bitstream_get(&(p_ac3dec->bit_stream),2); 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)) if ((!blknum) && (p_ac3dec->audblk.chexpstr[i] == EXP_REUSE))
{ {
...@@ -497,7 +539,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -497,7 +539,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
/* Get the exponent strategy for lfe channel */ /* Get the exponent strategy for lfe channel */
if (p_ac3dec->bsi.lfeon) if (p_ac3dec->bsi.lfeon)
{ {
p_ac3dec->audblk.lfeexpstr = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.lfeexpstr = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if ((!blknum) && (p_ac3dec->audblk.lfeexpstr == EXP_REUSE)) if ((!blknum) && (p_ac3dec->audblk.lfeexpstr == EXP_REUSE))
{ {
...@@ -518,7 +561,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -518,7 +561,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
} }
else else
{ {
p_ac3dec->audblk.chbwcod[i] = bitstream_get(&(p_ac3dec->bit_stream),6); p_ac3dec->audblk.chbwcod[i] = GetBits (&p_ac3dec->bit_stream,6);
p_ac3dec->total_bits_read += 6;
if (p_ac3dec->audblk.chbwcod[i] > 60) if (p_ac3dec->audblk.chbwcod[i] > 60)
{ {
...@@ -537,10 +581,12 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -537,10 +581,12 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
/* Get the coupling exponents if they exist */ /* Get the coupling exponents if they exist */
if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cplexpstr != EXP_REUSE)) if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cplexpstr != EXP_REUSE))
{ {
p_ac3dec->audblk.cplabsexp = bitstream_get(&(p_ac3dec->bit_stream),4); 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++) for (i=0; i< p_ac3dec->audblk.ncplgrps;i++)
{ {
p_ac3dec->audblk.cplexps[i] = bitstream_get(&(p_ac3dec->bit_stream),7); p_ac3dec->audblk.cplexps[i] = GetBits (&p_ac3dec->bit_stream,7);
p_ac3dec->total_bits_read += 7;
if (p_ac3dec->audblk.cplexps[i] >= 125) if (p_ac3dec->audblk.cplexps[i] >= 125)
{ {
...@@ -554,29 +600,33 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -554,29 +600,33 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
{ {
if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE) if (p_ac3dec->audblk.chexpstr[i] != EXP_REUSE)
{ {
p_ac3dec->audblk.exps[i][0] = bitstream_get(&(p_ac3dec->bit_stream),4); 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++) for (j=1; j<=p_ac3dec->audblk.nchgrps[i];j++)
{ {
p_ac3dec->audblk.exps[i][j] = bitstream_get(&(p_ac3dec->bit_stream),7); 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) if (p_ac3dec->audblk.exps[i][j] >= 125)
{ {
return 1; return 1;
} }
} }
p_ac3dec->audblk.gainrng[i] = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->audblk.gainrng[i] = GetBits (&p_ac3dec->bit_stream,2);
} }
} }
/* Get the lfe channel exponents */ /* Get the lfe channel exponents */
if (p_ac3dec->bsi.lfeon && (p_ac3dec->audblk.lfeexpstr != EXP_REUSE)) if (p_ac3dec->bsi.lfeon && (p_ac3dec->audblk.lfeexpstr != EXP_REUSE))
{ {
p_ac3dec->audblk.lfeexps[0] = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.lfeexps[0] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.lfeexps[1] = bitstream_get(&(p_ac3dec->bit_stream),7); p_ac3dec->audblk.lfeexps[1] = GetBits (&p_ac3dec->bit_stream,7);
p_ac3dec->total_bits_read += 11;
if (p_ac3dec->audblk.lfeexps[1] >= 125) if (p_ac3dec->audblk.lfeexps[1] >= 125)
{ {
return 1; return 1;
} }
p_ac3dec->audblk.lfeexps[2] = bitstream_get(&(p_ac3dec->bit_stream),7); p_ac3dec->audblk.lfeexps[2] = GetBits (&p_ac3dec->bit_stream,7);
p_ac3dec->total_bits_read += 7;
if (p_ac3dec->audblk.lfeexps[2] >= 125) if (p_ac3dec->audblk.lfeexps[2] >= 125)
{ {
return 1; return 1;
...@@ -584,7 +634,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -584,7 +634,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
} }
/* Get the parametric bit allocation parameters */ /* Get the parametric bit allocation parameters */
p_ac3dec->audblk.baie = bitstream_get(&(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)) if ((!blknum) && (!p_ac3dec->audblk.baie))
{ {
...@@ -593,15 +644,16 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -593,15 +644,16 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->audblk.baie) if (p_ac3dec->audblk.baie)
{ {
p_ac3dec->audblk.sdcycod = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->audblk.sdcycod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.fdcycod = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->audblk.fdcycod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.sgaincod = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->audblk.sgaincod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.dbpbcod = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->audblk.dbpbcod = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->audblk.floorcod = bitstream_get(&(p_ac3dec->bit_stream),3); 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 */ /* Get the SNR off set info if it exists */
p_ac3dec->audblk.snroffste = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.snroffste = GetBits (&p_ac3dec->bit_stream,1);
if ((!blknum) && (!p_ac3dec->audblk.snroffste)) if ((!blknum) && (!p_ac3dec->audblk.snroffste))
{ {
return 1; return 1;
...@@ -609,30 +661,35 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -609,30 +661,35 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->audblk.snroffste) if (p_ac3dec->audblk.snroffste)
{ {
p_ac3dec->audblk.csnroffst = bitstream_get(&(p_ac3dec->bit_stream),6); p_ac3dec->audblk.csnroffst = GetBits (&p_ac3dec->bit_stream,6);
p_ac3dec->total_bits_read += 6;
if (p_ac3dec->audblk.cplinu) if (p_ac3dec->audblk.cplinu)
{ {
p_ac3dec->audblk.cplfsnroffst = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.cplfsnroffst = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cplfgaincod = bitstream_get(&(p_ac3dec->bit_stream),3); 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++) for (i = 0;i < p_ac3dec->bsi.nfchans; i++)
{ {
p_ac3dec->audblk.fsnroffst[i] = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.fsnroffst[i] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.fgaincod[i] = bitstream_get(&(p_ac3dec->bit_stream),3); p_ac3dec->audblk.fgaincod[i] = GetBits (&p_ac3dec->bit_stream,3);
} }
p_ac3dec->total_bits_read += 7 * p_ac3dec->bsi.nfchans;
if (p_ac3dec->bsi.lfeon) if (p_ac3dec->bsi.lfeon)
{ {
p_ac3dec->audblk.lfefsnroffst = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.lfefsnroffst = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.lfefgaincod = bitstream_get(&(p_ac3dec->bit_stream),3); p_ac3dec->audblk.lfefgaincod = GetBits (&p_ac3dec->bit_stream,3);
p_ac3dec->total_bits_read += 7;
} }
} }
/* Get coupling leakage info if it exists */ /* Get coupling leakage info if it exists */
if (p_ac3dec->audblk.cplinu) if (p_ac3dec->audblk.cplinu)
{ {
p_ac3dec->audblk.cplleake = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.cplleake = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if ((!blknum) && (!p_ac3dec->audblk.cplleake)) if ((!blknum) && (!p_ac3dec->audblk.cplleake))
{ {
return 1; return 1;
...@@ -640,19 +697,22 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -640,19 +697,22 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->audblk.cplleake) if (p_ac3dec->audblk.cplleake)
{ {
p_ac3dec->audblk.cplfleak = bitstream_get(&(p_ac3dec->bit_stream),3); p_ac3dec->audblk.cplfleak = GetBits (&p_ac3dec->bit_stream,3);
p_ac3dec->audblk.cplsleak = bitstream_get(&(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 */ /* Get the delta bit alloaction info */
p_ac3dec->audblk.deltbaie = bitstream_get(&(p_ac3dec->bit_stream),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.deltbaie)
{ {
if (p_ac3dec->audblk.cplinu) if (p_ac3dec->audblk.cplinu)
{ {
p_ac3dec->audblk.cpldeltbae = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->audblk.cpldeltbae = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
if (p_ac3dec->audblk.cpldeltbae == 3) if (p_ac3dec->audblk.cpldeltbae == 3)
{ {
return 1; return 1;
...@@ -661,7 +721,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -661,7 +721,8 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
for (i = 0;i < p_ac3dec->bsi.nfchans; i++) for (i = 0;i < p_ac3dec->bsi.nfchans; i++)
{ {
p_ac3dec->audblk.deltbae[i] = bitstream_get(&(p_ac3dec->bit_stream),2); p_ac3dec->audblk.deltbae[i] = GetBits (&p_ac3dec->bit_stream,2);
p_ac3dec->total_bits_read += 2;
if (p_ac3dec->audblk.deltbae[i] == 3) if (p_ac3dec->audblk.deltbae[i] == 3)
{ {
return 1; return 1;
...@@ -670,45 +731,49 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum) ...@@ -670,45 +731,49 @@ int parse_audblk (ac3dec_t * p_ac3dec, int blknum)
if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cpldeltbae == DELTA_BIT_NEW)) if (p_ac3dec->audblk.cplinu && (p_ac3dec->audblk.cpldeltbae == DELTA_BIT_NEW))
{ {
p_ac3dec->audblk.cpldeltnseg = bitstream_get(&(p_ac3dec->bit_stream),3); p_ac3dec->audblk.cpldeltnseg = GetBits (&p_ac3dec->bit_stream,3);
for (i = 0;i < p_ac3dec->audblk.cpldeltnseg + 1; i++) for (i = 0;i < p_ac3dec->audblk.cpldeltnseg + 1; i++)
{ {
p_ac3dec->audblk.cpldeltoffst[i] = bitstream_get(&(p_ac3dec->bit_stream),5); p_ac3dec->audblk.cpldeltoffst[i] = GetBits (&p_ac3dec->bit_stream,5);
p_ac3dec->audblk.cpldeltlen[i] = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.cpldeltlen[i] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.cpldeltba[i] = bitstream_get(&(p_ac3dec->bit_stream),3); 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++) for (i = 0; i < p_ac3dec->bsi.nfchans; i++)
{ {
if (p_ac3dec->audblk.deltbae[i] == DELTA_BIT_NEW) if (p_ac3dec->audblk.deltbae[i] == DELTA_BIT_NEW)
{ {
p_ac3dec->audblk.deltnseg[i] = bitstream_get(&(p_ac3dec->bit_stream),3); p_ac3dec->audblk.deltnseg[i] = GetBits (&p_ac3dec->bit_stream,3);
// if (p_ac3dec->audblk.deltnseg[i] >= 8) // if (p_ac3dec->audblk.deltnseg[i] >= 8)
// fprintf (stderr, "parse debug: p_ac3dec->audblk.deltnseg[%i] == %i\n", i, p_ac3dec->audblk.deltnseg[i]); // 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++) for (j = 0; j < p_ac3dec->audblk.deltnseg[i] + 1; j++)
{ {
p_ac3dec->audblk.deltoffst[i][j] = bitstream_get(&(p_ac3dec->bit_stream),5); p_ac3dec->audblk.deltoffst[i][j] = GetBits (&p_ac3dec->bit_stream,5);
p_ac3dec->audblk.deltlen[i][j] = bitstream_get(&(p_ac3dec->bit_stream),4); p_ac3dec->audblk.deltlen[i][j] = GetBits (&p_ac3dec->bit_stream,4);
p_ac3dec->audblk.deltba[i][j] = bitstream_get(&(p_ac3dec->bit_stream),3); 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 */ /* Check to see if there's any dummy info to get */
p_ac3dec->audblk.skiple = bitstream_get(&(p_ac3dec->bit_stream),1); p_ac3dec->audblk.skiple = GetBits (&p_ac3dec->bit_stream,1);
p_ac3dec->total_bits_read += 1;
if (p_ac3dec->audblk.skiple) if (p_ac3dec->audblk.skiple)
{ {
p_ac3dec->audblk.skipl = bitstream_get(&(p_ac3dec->bit_stream),9); p_ac3dec->audblk.skipl = GetBits (&p_ac3dec->bit_stream,9);
for (i = 0; i < p_ac3dec->audblk.skipl ; i++) for (i = 0; i < p_ac3dec->audblk.skipl ; i++)
{ {
bitstream_get(&(p_ac3dec->bit_stream),8); GetBits (&p_ac3dec->bit_stream,8);
} }
p_ac3dec->total_bits_read += 8 * p_ac3dec->audblk.skipl + 9;
} }
#ifdef STATS #ifdef STATS
// parse_audblk_stats(p_ac3dec); // parse_audblk_stats(p_ac3dec);
#endif #endif
...@@ -721,28 +786,28 @@ void parse_auxdata (ac3dec_t * p_ac3dec) ...@@ -721,28 +786,28 @@ void parse_auxdata (ac3dec_t * p_ac3dec)
int i; int i;
int skip_length; int skip_length;
skip_length = (p_ac3dec->syncinfo.frame_size * 16) - p_ac3dec->bit_stream.total_bits_read - 17 - 1; skip_length = (p_ac3dec->syncinfo.frame_size * 16) - p_ac3dec->total_bits_read - 17 - 1;
for (i = 0; i < skip_length; i++) for (i = 0; i < skip_length; i++)
{ {
bitstream_get(&(p_ac3dec->bit_stream),1); RemoveBits (&p_ac3dec->bit_stream,1);
} }
/* get the auxdata exists bit */ /* get the auxdata exists bit */
bitstream_get(&(p_ac3dec->bit_stream),1); RemoveBits (&p_ac3dec->bit_stream,1);
/* Skip the CRC reserved bit */ /* Skip the CRC reserved bit */
bitstream_get(&(p_ac3dec->bit_stream),1); RemoveBits (&p_ac3dec->bit_stream,1);
/* Get the crc */ /* Get the crc */
bitstream_get(&(p_ac3dec->bit_stream),16); RemoveBits (&p_ac3dec->bit_stream,16);
} }
void parse_bsi_stats (ac3dec_t * p_ac3dec) /*Some stats */ void parse_bsi_stats (ac3dec_t * p_ac3dec) /*Some stats */
{ {
struct mixlev_s struct mixlev_s
{ {
float clev; float clev;
char *desc; char *desc;
}; };
static const char *service_ids[8] = static const char *service_ids[8] =
...@@ -763,14 +828,14 @@ void parse_bsi_stats (ac3dec_t * p_ac3dec) /*Some stats */ ...@@ -763,14 +828,14 @@ void parse_bsi_stats (ac3dec_t * p_ac3dec) /*Some stats */
}; };
*/ */
static int i; static int i=0;
if ( !i ) if ( !i )
{ {
/* if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1)) /* if ((p_ac3dec->bsi.acmod & 0x1) && (p_ac3dec->bsi.acmod != 0x1))
printf("CentreMixLevel %s ",cmixlev_tbl[p_ac3dec->bsi.cmixlev].desc); printf("CentreMixLevel %s ",cmixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
if (p_ac3dec->bsi.acmod & 0x4) if (p_ac3dec->bsi.acmod & 0x4)
printf("SurMixLevel %s",smixlev_tbl[p_ac3dec->bsi.cmixlev].desc); printf("SurMixLevel %s",smixlev_tbl[p_ac3dec->bsi.cmixlev].desc);
*/ */
intf_Msg ( "(ac3dec_parsebsi) %s %d.%d Mode", intf_Msg ( "(ac3dec_parsebsi) %s %d.%d Mode",
service_ids[p_ac3dec->bsi.bsmod], service_ids[p_ac3dec->bsi.bsmod],
...@@ -787,19 +852,19 @@ void parse_audblk_stats (ac3dec_t * p_ac3dec) ...@@ -787,19 +852,19 @@ void parse_audblk_stats (ac3dec_t * p_ac3dec)
char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "}; char *exp_strat_tbl[4] = {"R ","D15 ","D25 ","D45 "};
u32 i; u32 i;
intf_ErrMsg ("(ac3dec_parseaudblk) "); intf_ErrMsg ("(ac3dec_parseaudblk) ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.cplinu ? "cpl on" : "cpl off"); 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.baie? "bai" : " ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.snroffste? "snroffst" : " "); intf_ErrMsg ("%s ",p_ac3dec->audblk.snroffste? "snroffst" : " ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.deltbaie? "deltba" : " "); intf_ErrMsg ("%s ",p_ac3dec->audblk.deltbaie? "deltba" : " ");
intf_ErrMsg ("%s ",p_ac3dec->audblk.phsflginu? "phsflg" : " "); intf_ErrMsg ("%s ",p_ac3dec->audblk.phsflginu? "phsflg" : " ");
intf_ErrMsg ("(%s %s %s %s %s) ",exp_strat_tbl[p_ac3dec->audblk.chexpstr[0]], 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[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]]); exp_strat_tbl[p_ac3dec->audblk.chexpstr[3]],exp_strat_tbl[p_ac3dec->audblk.chexpstr[4]]);
intf_ErrMsg ("["); intf_ErrMsg ("[");
for(i=0;i<p_ac3dec->bsi.nfchans;i++) for(i=0;i<p_ac3dec->bsi.nfchans;i++)
intf_ErrMsg ("%1d",p_ac3dec->audblk.blksw[i]); intf_ErrMsg ("%1d",p_ac3dec->audblk.blksw[i]);
intf_ErrMsg ("]"); intf_ErrMsg ("]");
intf_ErrMsg ("\n"); intf_ErrMsg ("\n");
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_rematrix.c: ac3 audio rematrixing * ac3_rematrix.c: ac3 audio rematrixing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_rematrix.c,v 1.12 2001/03/21 13:42:34 sam Exp $ * $Id: ac3_rematrix.c,v 1.13 2001/04/20 12:14:34 reno Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Aaron Holtzman <aholtzma@engr.uvic.ca> * Aaron Holtzman <aholtzma@engr.uvic.ca>
...@@ -23,7 +23,14 @@ ...@@ -23,7 +23,14 @@
*****************************************************************************/ *****************************************************************************/
#include "defs.h" #include "defs.h"
#include "int_types.h" #include "config.h"
#include "common.h"
#include "threads.h"
#include "mtime.h"
#include "stream_control.h"
#include "input_ext-dec.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_internal.h" #include "ac3_internal.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment