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;
}