Commit a5e77c46 authored by Michel Lespinasse's avatar Michel Lespinasse

Created a small&clean public interface for the ac3 decoder (see ac3_decoder.h)

Modified ac3_decoder_thread to use this interface

Find ac3 sync words not by scanning the ac3 stream but by using the magic
bytes at the start of the ac3 pes packets
parent c6313a9b
/***************************************************************************** /*****************************************************************************
* ac3_decoder.h : ac3 decoder thread interface * ac3_decoder.h : ac3 decoder interface
* (c)1999 VideoLAN * (c)1999 VideoLAN
*****************************************************************************/ *****************************************************************************/
/* Exponent strategy constants */ /**** ac3 decoder API - public ac3 decoder structures */
#define EXP_REUSE (0)
#define EXP_D15 (1)
#define EXP_D25 (2)
#define EXP_D45 (3)
/* Delta bit allocation constants */ typedef struct ac3dec_s ac3dec_t;
#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1) typedef struct ac3_sync_info_s {
#define DELTA_BIT_NONE (2) int sample_rate; /* sample rate in Hz */
#define DELTA_BIT_RESERVED (3) int frame_size; /* frame size in bytes */
int bit_rate; /* nominal bit rate in kbps */
} 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 ****/
int ac3_init (ac3dec_t * p_ac3dec);
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);
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 ****/
/**** ac3 decoder internal structures ****/
/* The following structures are filled in by their corresponding parse_* /* The following structures are filled in by their corresponding parse_*
* functions. See http://www.atsc.org/Standards/A52/a_52.pdf for * functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
...@@ -21,8 +40,7 @@ ...@@ -21,8 +40,7 @@
* conditional fields. * conditional fields.
*/ */
typedef struct syncinfo_s typedef struct syncinfo_s {
{
/* Sync word == 0x0B77 */ /* Sync word == 0x0B77 */
/* u16 syncword; */ /* u16 syncword; */
/* crc for the first 5/8 of the sync block */ /* crc for the first 5/8 of the sync block */
...@@ -36,12 +54,10 @@ typedef struct syncinfo_s ...@@ -36,12 +54,10 @@ typedef struct syncinfo_s
/* Frame size in 16 bit words */ /* Frame size in 16 bit words */
u16 frame_size; u16 frame_size;
/* Bit rate in kilobits */ /* Bit rate in kilobits */
u16 bit_rate; //u16 bit_rate;
} syncinfo_t; } syncinfo_t;
typedef struct bsi_s typedef struct bsi_s {
{
/* Bit stream identification == 0x8 */ /* Bit stream identification == 0x8 */
u16 bsid; u16 bsid;
/* Bit stream mode */ /* Bit stream mode */
...@@ -105,12 +121,10 @@ typedef struct bsi_s ...@@ -105,12 +121,10 @@ typedef struct bsi_s
/* Number of channels (excluding LFE) /* Number of channels (excluding LFE)
* Derived from acmod */ * Derived from acmod */
u16 nfchans; u16 nfchans;
} bsi_t; } bsi_t;
/* more pain */ /* more pain */
typedef struct audblk_s typedef struct audblk_s {
{
/* block switch bit indexed by channel num */ /* block switch bit indexed by channel num */
u16 blksw[5]; u16 blksw[5];
/* dither enable bit indexed by channel num */ /* dither enable bit indexed by channel num */
...@@ -282,7 +296,6 @@ typedef struct audblk_s ...@@ -282,7 +296,6 @@ typedef struct audblk_s
/* FIXME?? figure out exactly how many entries there should be (253-37?) */ /* FIXME?? figure out exactly how many entries there should be (253-37?) */
u16 cpl_bap[256]; u16 cpl_bap[256];
u16 lfe_bap[7]; u16 lfe_bap[7];
} audblk_t; } audblk_t;
/* Everything you wanted to know about band structure */ /* Everything you wanted to know about band structure */
...@@ -304,35 +317,16 @@ typedef struct audblk_s ...@@ -304,35 +317,16 @@ typedef struct audblk_s
* approximate a 1/6 octave scale. * approximate a 1/6 octave scale.
*/ */
typedef struct stream_coeffs_s typedef struct stream_coeffs_s {
{
float fbw[5][256]; float fbw[5][256];
float lfe[256]; float lfe[256];
} stream_coeffs_t; } stream_coeffs_t;
typedef struct stream_samples_s typedef struct stream_samples_s {
{
float channel[6][256]; float channel[6][256];
} stream_samples_t; } stream_samples_t;
#define AC3DEC_FRAME_SIZE (2*256) typedef struct ac3_bit_stream_s {
/*****************************************************************************
* ac3dec_frame_t
*****************************************************************************/
typedef s16 ac3dec_frame_t[ AC3DEC_FRAME_SIZE ];
typedef struct ac3_byte_stream_s
{
u8 * p_byte;
u8 * p_end;
void * info;
} ac3_byte_stream_t;
typedef struct ac3_bit_stream_s
{
u32 buffer; u32 buffer;
int i_available; int i_available;
ac3_byte_stream_t byte_stream; ac3_byte_stream_t byte_stream;
...@@ -340,11 +334,7 @@ typedef struct ac3_bit_stream_s ...@@ -340,11 +334,7 @@ typedef struct ac3_bit_stream_s
unsigned int total_bits_read; /* temporary */ unsigned int total_bits_read; /* temporary */
} ac3_bit_stream_t; } ac3_bit_stream_t;
/***************************************************************************** struct ac3dec_s {
* ac3dec_t : ac3 decoder descriptor
*****************************************************************************/
typedef struct ac3dec_s
{
/* /*
* Input properties * Input properties
*/ */
...@@ -361,9 +351,11 @@ typedef struct ac3dec_s ...@@ -361,9 +351,11 @@ typedef struct ac3dec_s
stream_coeffs_t coeffs; stream_coeffs_t coeffs;
stream_samples_t samples; stream_samples_t samples;
};
} ac3dec_t; /**** ac3 decoder inline functions ****/
int ac3_audio_block (ac3dec_t * p_ac3dec, s16 * buffer);
void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream); static ac3_byte_stream_t * ac3_byte_stream (ac3dec_t * p_ac3dec)
{
return &(p_ac3dec->bit_stream.byte_stream);
}
/***************************************************************************** /*****************************************************************************
* ac3_decoder.h : ac3 decoder thread interface * ac3_decoder_thread.h : ac3 decoder thread interface
* (c)1999 VideoLAN * (c)1999 VideoLAN
*****************************************************************************/ *****************************************************************************/
...@@ -21,6 +21,7 @@ typedef struct ac3dec_thread_s ...@@ -21,6 +21,7 @@ typedef struct ac3dec_thread_s
decoder_fifo_t fifo; /* stores the PES stream data */ decoder_fifo_t fifo; /* stores the PES stream data */
input_thread_t * p_input; input_thread_t * p_input;
ts_packet_t * p_ts; ts_packet_t * p_ts;
int sync_ptr; /* sync ptr from ac3 magic header */
/* /*
* Decoder properties * Decoder properties
......
This diff is collapsed.
void bit_allocate( ac3dec_t * );
...@@ -9,18 +9,6 @@ static __inline__ u8 GetByte (ac3_byte_stream_t * p_byte_stream) ...@@ -9,18 +9,6 @@ static __inline__ u8 GetByte (ac3_byte_stream_t * p_byte_stream)
return *(p_byte_stream->p_byte++); return *(p_byte_stream->p_byte++);
} }
/*****************************************************************************
* NeedBits : reads i_bits new bits in the bit stream and stores them in the
* bit buffer
*****************************************************************************
* - i_bits must be less or equal 32 !
* - There is something important to notice with that function : if the number
* of bits available in the bit buffer when calling NeedBits() is greater than
* 24 (i_available > 24) but less than the number of needed bits
* (i_available < i_bits), the byte returned by GetByte() will be shifted with
* a negative value and the number of bits available in the bit buffer will be
* set to more than 32 !
*****************************************************************************/
static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits) static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
{ {
while (p_bit_stream->i_available < i_bits) { while (p_bit_stream->i_available < i_bits) {
...@@ -30,12 +18,6 @@ static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits) ...@@ -30,12 +18,6 @@ static __inline__ void NeedBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
} }
} }
/*****************************************************************************
* DumpBits : removes i_bits bits from the bit buffer
*****************************************************************************
* - i_bits <= i_available
* - i_bits < 32 (because (u32 << 32) <=> (u32 = u32))
*****************************************************************************/
static __inline__ void DumpBits (ac3_bit_stream_t * p_bit_stream, int i_bits) static __inline__ void DumpBits (ac3_bit_stream_t * p_bit_stream, int i_bits)
{ {
p_bit_stream->buffer <<= i_bits; p_bit_stream->buffer <<= i_bits;
......
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_parse.h" #include "ac3_internal.h"
#include "ac3_exponent.h"
#include "ac3_bit_allocate.h" int ac3_init (ac3dec_t * p_ac3dec)
#include "ac3_mantissa.h" {
#include "ac3_rematrix.h" //p_ac3dec->bit_stream.buffer = 0;
#include "ac3_imdct.h" p_ac3dec->bit_stream.i_available = 0;
#include "ac3_downmix.h"
int ac3_audio_block (ac3dec_t * p_ac3dec, s16 * buffer)
{
parse_audblk( p_ac3dec );
if (exponent_unpack( p_ac3dec ))
return 1;
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->bsi.acmod == 0x2 )
rematrix( p_ac3dec );
imdct( p_ac3dec );
downmix( p_ac3dec, buffer );
return 0; return 0;
}
int ac3_decode_frame (ac3dec_t * p_ac3dec, s16 * buffer)
{
int i;
parse_bsi (p_ac3dec);
for (i = 0; i < 6; i++) {
parse_audblk (p_ac3dec);
if (exponent_unpack (p_ac3dec))
return 1;
bit_allocate (p_ac3dec);
mantissa_unpack (p_ac3dec);
if (p_ac3dec->bsi.acmod == 0x2)
rematrix (p_ac3dec);
imdct (p_ac3dec);
downmix (p_ac3dec, buffer);
buffer += 2*256;
} }
parse_auxdata (p_ac3dec);
return 0;
}
/***************************************************************************** /*****************************************************************************
* ac3_decoder.c: ac3 decoder thread * ac3_decoder_thread.c: ac3 decoder thread
* (c)1999 VideoLAN * (c)1999 VideoLAN
*****************************************************************************/ *****************************************************************************/
...@@ -42,8 +42,9 @@ ...@@ -42,8 +42,9 @@
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_decoder_thread.h" #include "ac3_decoder_thread.h"
#include "ac3_parse.h"
#include "ac3_imdct.h" #define AC3DEC_FRAME_SIZE (2*1536)
typedef s16 ac3dec_frame_t[ AC3DEC_FRAME_SIZE ];
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -84,10 +85,12 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input ) ...@@ -84,10 +85,12 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
vlc_cond_init( &p_ac3dec->fifo.data_wait ); vlc_cond_init( &p_ac3dec->fifo.data_wait );
p_ac3dec->fifo.i_start = 0; p_ac3dec->fifo.i_start = 0;
p_ac3dec->fifo.i_end = 0; p_ac3dec->fifo.i_end = 0;
/* Initialize the ac3 decoder structures */
ac3_init (&p_ac3dec->ac3_decoder);
/* Initialize the bit stream structure */ /* Initialize the bit stream structure */
p_ac3dec->p_input = p_input; p_ac3dec->p_input = p_input;
p_ac3dec->ac3_decoder.bit_stream.buffer = 0;
p_ac3dec->ac3_decoder.bit_stream.i_available = 0;
/* /*
* Initialize the output properties * Initialize the output properties
...@@ -95,8 +98,6 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input ) ...@@ -95,8 +98,6 @@ ac3dec_thread_t * ac3dec_CreateThread( input_thread_t * p_input )
p_ac3dec->p_aout = p_input->p_aout; p_ac3dec->p_aout = p_input->p_aout;
p_ac3dec->p_aout_fifo = NULL; p_ac3dec->p_aout_fifo = NULL;
imdct_init();
/* 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->thread_id, "ac3 decoder", (vlc_thread_func_t)RunThread, (void *)p_ac3dec) )
{ {
...@@ -131,25 +132,13 @@ void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec ) ...@@ -131,25 +132,13 @@ void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec )
/* Following functions are local */ /* Following functions are local */
/*****************************************************************************
* decode_find_sync()
*****************************************************************************/
static __inline__ int decode_find_sync( ac3dec_thread_t * p_ac3dec )
{
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
{
if (! (ac3_test_sync (&p_ac3dec->ac3_decoder)))
return 0;
}
return( -1 );
}
/***************************************************************************** /*****************************************************************************
* 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 )
{ {
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\n", p_ac3dec ); intf_DbgMsg( "ac3dec debug: initializing ac3 decoder thread %p\n", p_ac3dec );
...@@ -166,11 +155,12 @@ static int InitThread( ac3dec_thread_t * p_ac3dec ) ...@@ -166,11 +155,12 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock ); vlc_cond_wait( &p_ac3dec->fifo.data_wait, &p_ac3dec->fifo.data_lock );
} }
p_ac3dec->p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts; p_ac3dec->p_ts = DECODER_FIFO_START( p_ac3dec->fifo )->p_first_ts;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.p_byte = byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
byte_stream->p_byte =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start; p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_start;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.p_end = byte_stream->p_end =
p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end; p_ac3dec->p_ts->buffer + p_ac3dec->p_ts->i_payload_end;
p_ac3dec->ac3_decoder.bit_stream.byte_stream.info = p_ac3dec; byte_stream->info = p_ac3dec;
vlc_mutex_unlock( &p_ac3dec->fifo.data_lock ); vlc_mutex_unlock( &p_ac3dec->fifo.data_lock );
aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO; aout_fifo.i_type = AOUT_ADEC_STEREO_FIFO;
...@@ -194,6 +184,8 @@ static int InitThread( ac3dec_thread_t * p_ac3dec ) ...@@ -194,6 +184,8 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
*****************************************************************************/ *****************************************************************************/
static void RunThread( ac3dec_thread_t * p_ac3dec ) static void RunThread( ac3dec_thread_t * p_ac3dec )
{ {
int sync;
intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() ); intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() );
msleep( INPUT_PTS_DELAY ); msleep( INPUT_PTS_DELAY );
...@@ -204,13 +196,44 @@ static void RunThread( ac3dec_thread_t * p_ac3dec ) ...@@ -204,13 +196,44 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
p_ac3dec->b_error = 1; p_ac3dec->b_error = 1;
} }
sync = 0;
p_ac3dec->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->b_die) && (!p_ac3dec->b_error) ) while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
{ {
int i; s16 * buffer;
ac3_sync_info_t sync_info;
if (!sync) { /* have to find a synchro point */
int ptr;
ac3_byte_stream_t * p_byte_stream;
p_byte_stream = ac3_byte_stream (&p_ac3dec->ac3_decoder);
decode_find_sync( p_ac3dec ); /* first read till next ac3 magic header */
do {
ac3_byte_stream_next (p_byte_stream);
} while ((!p_ac3dec->sync_ptr) &&
(!p_ac3dec->b_die) &&
(!p_ac3dec->b_error));
/* skip the specified number of bytes */
ptr = p_ac3dec->sync_ptr;
while (--ptr && (!p_ac3dec->b_die) && (!p_ac3dec->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++;
}
/* we are in sync now */
sync = 1;
p_ac3dec->sync_ptr = 0;
}
if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts ) if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts )
{ {
...@@ -222,46 +245,25 @@ static void RunThread( ac3dec_thread_t * p_ac3dec ) ...@@ -222,46 +245,25 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE; p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
} }
parse_syncinfo( &p_ac3dec->ac3_decoder ); if (ac3_sync_frame (&p_ac3dec->ac3_decoder, &sync_info)) {
switch ( p_ac3dec->ac3_decoder.syncinfo.fscod ) sync = 0;
{ goto bad_frame;
case 0:
p_ac3dec->p_aout_fifo->l_rate = 48000;
break;
case 1:
p_ac3dec->p_aout_fifo->l_rate = 44100;
break;
case 2:
p_ac3dec->p_aout_fifo->l_rate = 32000;
break;
default: /* XXX?? */
fprintf( stderr, "ac3dec debug: invalid fscod\n" );
continue;
} }
parse_bsi( &p_ac3dec->ac3_decoder ); p_ac3dec->p_aout_fifo->l_rate = sync_info.sample_rate;
for (i = 0; i < 6; i++)
{
s16 * buffer;
buffer = ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ]; buffer = ((ac3dec_frame_t *)p_ac3dec->p_aout_fifo->buffer)[ p_ac3dec->p_aout_fifo->l_end_frame ];
if (ac3_audio_block (&p_ac3dec->ac3_decoder, buffer)) if (ac3_decode_frame (&p_ac3dec->ac3_decoder, buffer)) {
sync = 0;
goto bad_frame; goto bad_frame;
}
if (i)
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = LAST_MDATE;
vlc_mutex_lock( &p_ac3dec->p_aout_fifo->data_lock ); vlc_mutex_lock( &p_ac3dec->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->p_aout_fifo->l_end_frame = (p_ac3dec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait ); vlc_cond_signal( &p_ac3dec->p_aout_fifo->data_wait );
vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock ); vlc_mutex_unlock( &p_ac3dec->p_aout_fifo->data_lock );
}
parse_auxdata( &p_ac3dec->ac3_decoder );
bad_frame: bad_frame:
} }
...@@ -336,6 +338,8 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream) ...@@ -336,6 +338,8 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream)
/* We were reading the last TS packet of this PES packet... It's /* We were reading the last TS packet of this PES packet... It's
* time to jump to the next PES packet */ * time to jump to the next PES packet */
if (p_ac3dec->p_ts->p_next_ts == NULL) { if (p_ac3dec->p_ts->p_next_ts == NULL) {
int ptr;
/* We are going to read/write the start and end indexes of the /* We are going to read/write the start and end indexes of the
* decoder fifo and to use the fifo's conditional variable, * decoder fifo and to use the fifo's conditional variable,
* that's why we need to take the lock before */ * that's why we need to take the lock before */
...@@ -368,6 +372,13 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream) ...@@ -368,6 +372,13 @@ void ac3_byte_stream_next (ac3_byte_stream_t * p_byte_stream)
/* The next byte could be found in the next PES packet */ /* The next byte could be found in the next PES packet */
p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts; p_ac3dec->p_ts = DECODER_FIFO_START (p_ac3dec->fifo)->p_first_ts;
/* parse ac3 magic header */
ptr = p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+2];
ptr <<= 8;
ptr |= p_ac3dec->p_ts->buffer [p_ac3dec->p_ts->i_payload_start+3];
p_ac3dec->sync_ptr = ptr;
p_ac3dec->p_ts->i_payload_start += 4;
/* We can release the fifo's data lock */ /* We can release the fifo's data lock */
vlc_mutex_unlock (&p_ac3dec->fifo.data_lock); vlc_mutex_unlock (&p_ac3dec->fifo.data_lock);
} }
......
This diff is collapsed.
void downmix( ac3dec_t *, s16 * );
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_bit_stream.h" #include "ac3_bit_stream.h"
#include "ac3_exponent.h" #include "ac3_internal.h"
static const s16 exps_1[128] = static const s16 exps_1[128] =
{ -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, { -2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,
...@@ -33,13 +33,14 @@ static const s16 exps_3[128] = ...@@ -33,13 +33,14 @@ static const s16 exps_3[128] =
#define UNPACK_CPL 2 #define UNPACK_CPL 2
#define UNPACK_LFE 4 #define UNPACK_LFE 4
static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, u16 ngrps, u16 initial_exp, u16 exps[], u16 * dest ) static __inline__ int exp_unpack_ch (ac3dec_t * p_ac3dec, u16 type,
u16 expstr, u16 ngrps, u16 initial_exp,
u16 exps[], u16 * dest)
{ {
u16 i,j; u16 i,j;
s16 exp_acc; s16 exp_acc;
if ( expstr == EXP_REUSE ) if (expstr == EXP_REUSE) {
{
return 0; return 0;
} }
...@@ -49,20 +50,16 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, ...@@ -49,20 +50,16 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
/* In the case of a fbw channel then the initial absolute values is /* In the case of a fbw channel then the initial absolute values is
* also an exponent */ * also an exponent */
if ( type != UNPACK_CPL ) if (type != UNPACK_CPL) {
{
dest[j++] = exp_acc; dest[j++] = exp_acc;
} }
/* Loop through the groups and fill the dest array appropriately */ /* Loop through the groups and fill the dest array appropriately */
switch ( expstr ) switch (expstr) {
{
case EXP_D15: /* 1 */ case EXP_D15: /* 1 */
for ( i = 0; i < ngrps; i++ ) for (i = 0; i < ngrps; i++) {
{ if (exps[i] > 124) {
if ( exps[i] > 124 ) fprintf (stderr, "ac3dec debug: invalid exponent\n");
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1; return 1;
} }
exp_acc += (exps_1[exps[i]] /*- 2*/); exp_acc += (exps_1[exps[i]] /*- 2*/);
...@@ -75,11 +72,9 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, ...@@ -75,11 +72,9 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
break; break;
case EXP_D25: /* 2 */ case EXP_D25: /* 2 */
for ( i = 0; i < ngrps; i++ ) for (i = 0; i < ngrps; i++) {
{ if (exps[i] > 124) {
if ( exps[i] > 124 ) fprintf (stderr, "ac3dec debug: invalid exponent\n");
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1; return 1;
} }
exp_acc += (exps_1[exps[i]] /*- 2*/); exp_acc += (exps_1[exps[i]] /*- 2*/);
...@@ -95,11 +90,9 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, ...@@ -95,11 +90,9 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
break; break;
case EXP_D45: /* 3 */ case EXP_D45: /* 3 */
for ( i = 0; i < ngrps; i++ ) for (i = 0; i < ngrps; i++) {
{ if (exps[i] > 124) {
if ( exps[i] > 124 ) fprintf (stderr, "ac3dec debug: invalid exponent\n");
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
return 1; return 1;
} }
exp_acc += (exps_1[exps[i]] /*- 2*/); exp_acc += (exps_1[exps[i]] /*- 2*/);
...@@ -124,36 +117,33 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr, ...@@ -124,36 +117,33 @@ static __inline__ int exp_unpack_ch( ac3dec_t * p_ac3dec, u16 type, u16 expstr,
return 0; return 0;
} }
int exponent_unpack( ac3dec_t * p_ac3dec ) int exponent_unpack (ac3dec_t * p_ac3dec)
{ {
u16 i; u16 i;
for ( i = 0; i < p_ac3dec->bsi.nfchans; i++ ) for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
{ if (exp_unpack_ch (p_ac3dec, UNPACK_FBW, p_ac3dec->audblk.chexpstr[i],
if (exp_unpack_ch( p_ac3dec, UNPACK_FBW, p_ac3dec->audblk.chexpstr[i],
p_ac3dec->audblk.nchgrps[i], p_ac3dec->audblk.nchgrps[i],
p_ac3dec->audblk.exps[i][0], p_ac3dec->audblk.exps[i][0],
&p_ac3dec->audblk.exps[i][1], &p_ac3dec->audblk.exps[i][1],
p_ac3dec->audblk.fbw_exp[i] )) p_ac3dec->audblk.fbw_exp[i]))
return 1; return 1;
} }
if ( p_ac3dec->audblk.cplinu ) if (p_ac3dec->audblk.cplinu) {
{ if (exp_unpack_ch (p_ac3dec, UNPACK_CPL, p_ac3dec->audblk.cplexpstr,
if (exp_unpack_ch( p_ac3dec, UNPACK_CPL, p_ac3dec->audblk.cplexpstr,
p_ac3dec->audblk.ncplgrps, p_ac3dec->audblk.ncplgrps,
p_ac3dec->audblk.cplabsexp << 1, p_ac3dec->audblk.cplabsexp << 1,
p_ac3dec->audblk.cplexps, p_ac3dec->audblk.cplexps,
&p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant] )) &p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant]))
return 1; return 1;
} }
if ( p_ac3dec->bsi.lfeon ) if (p_ac3dec->bsi.lfeon) {
{ if (exp_unpack_ch (p_ac3dec, UNPACK_LFE, p_ac3dec->audblk.lfeexpstr,
if (exp_unpack_ch( p_ac3dec, UNPACK_LFE, p_ac3dec->audblk.lfeexpstr,
2, p_ac3dec->audblk.lfeexps[0], 2, p_ac3dec->audblk.lfeexps[0],
&p_ac3dec->audblk.lfeexps[1], &p_ac3dec->audblk.lfeexps[1],
p_ac3dec->audblk.lfe_exp )) p_ac3dec->audblk.lfe_exp))
return 1; return 1;
} }
......
int exponent_unpack( ac3dec_t * );
...@@ -2,13 +2,12 @@ ...@@ -2,13 +2,12 @@
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_imdct.h" #include "ac3_internal.h"
void imdct_do_256(float x[],float y[],float delay[]); void imdct_do_256(float x[],float y[],float delay[]);
void imdct_do_512(float x[],float y[],float delay[]); void imdct_do_512(float x[],float y[],float delay[]);
typedef struct complex_s typedef struct complex_s {
{
float real; float real;
float imag; float imag;
} complex_t; } complex_t;
...@@ -119,22 +118,21 @@ static __inline__ complex_t cmplx_mult(complex_t a, complex_t b) ...@@ -119,22 +118,21 @@ static __inline__ complex_t cmplx_mult(complex_t a, complex_t b)
return ret; return ret;
} }
void imdct_init(void) static void imdct_init(void) __attribute__ ((__constructor__));
static void imdct_init(void)
{ {
int i,k; int i,k;
complex_t angle_step; complex_t angle_step;
complex_t current_angle; complex_t current_angle;
/* Twiddle factors to turn IFFT into IMDCT */ /* Twiddle factors to turn IFFT into IMDCT */
for( i=0; i < N/4; i++) for (i=0; i < N/4; i++) {
{
xcos1[i] = -cos(2 * M_PI * (8*i+1)/(8*N)) ; xcos1[i] = -cos(2 * M_PI * (8*i+1)/(8*N)) ;
xsin1[i] = -sin(2 * M_PI * (8*i+1)/(8*N)) ; xsin1[i] = -sin(2 * M_PI * (8*i+1)/(8*N)) ;
} }
/* More twiddle factors to turn IFFT into IMDCT */ /* More twiddle factors to turn IFFT into IMDCT */
for( i=0; i < N/8; i++) for (i=0; i < N/8; i++) {
{
xcos2[i] = -cos(2 * M_PI * (8*i+1)/(4*N)) ; xcos2[i] = -cos(2 * M_PI * (8*i+1)/(4*N)) ;
xsin2[i] = -sin(2 * M_PI * (8*i+1)/(4*N)) ; xsin2[i] = -sin(2 * M_PI * (8*i+1)/(4*N)) ;
} }
...@@ -148,29 +146,26 @@ void imdct_init(void) ...@@ -148,29 +146,26 @@ void imdct_init(void)
w[5] = w_32; w[5] = w_32;
w[6] = w_64; w[6] = w_64;
for( i = 0; i < 7; i++) for (i = 0; i < 7; i++) {
{
angle_step.real = cos(-2.0f * M_PI / (1 << (i+1))); angle_step.real = cos(-2.0f * M_PI / (1 << (i+1)));
angle_step.imag = sin(-2.0f * M_PI / (1 << (i+1))); angle_step.imag = sin(-2.0f * M_PI / (1 << (i+1)));
current_angle.real = 1.0f; current_angle.real = 1.0f;
current_angle.imag = 0.0f; current_angle.imag = 0.0f;
for (k = 0; k < 1 << i; k++) for (k = 0; k < 1 << i; k++) {
{
w[i][k] = current_angle; w[i][k] = current_angle;
current_angle = cmplx_mult(current_angle,angle_step); current_angle = cmplx_mult(current_angle,angle_step);
} }
} }
} }
void imdct( ac3dec_t * p_ac3dec ) void imdct (ac3dec_t * p_ac3dec)
{ {
int i; int i;
for(i=0; i<p_ac3dec->bsi.nfchans;i++) for (i=0; i<p_ac3dec->bsi.nfchans;i++) {
{ if (p_ac3dec->audblk.blksw[i])
if(p_ac3dec->audblk.blksw[i])
imdct_do_256(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]); imdct_do_256(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]);
else else
imdct_do_512(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]); imdct_do_512(p_ac3dec->coeffs.fbw[i],p_ac3dec->samples.channel[i],delay[i]);
...@@ -202,31 +197,26 @@ imdct_do_512(float x[],float y[],float delay[]) ...@@ -202,31 +197,26 @@ imdct_do_512(float x[],float y[],float delay[])
float *window_ptr; float *window_ptr;
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for( i=0; i < N/4; i++) for (i=0; i < N/4; i++) {
{
/* z[i] = (X[N/2-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */ /* z[i] = (X[N/2-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) ; */
buf[i].real = (x[N/2-2*i-1] * xcos1[i]) - (x[2*i] * xsin1[i]); buf[i].real = (x[N/2-2*i-1] * xcos1[i]) - (x[2*i] * xsin1[i]);
buf[i].imag = -((x[2*i] * xcos1[i]) + (x[N/2-2*i-1] * xsin1[i])); buf[i].imag = -((x[2*i] * xcos1[i]) + (x[N/2-2*i-1] * xsin1[i]));
} }
/* Bit reversed shuffling */ /* Bit reversed shuffling */
for(i=0; i<N/4; i++) for (i=0; i<N/4; i++) {
{
k = bit_reverse_512[i]; k = bit_reverse_512[i];
if (k < i) if (k < i)
swap_cmplx(&buf[i],&buf[k]); swap_cmplx(&buf[i],&buf[k]);
} }
/* FFT Merge */ /* FFT Merge */
for (m=0; m < 7; m++) for (m=0; m < 7; m++) {
{
two_m = (1 << m); two_m = (1 << m);
two_m_plus_one = (1 << (m+1)); two_m_plus_one = (1 << (m+1));
for(k = 0; k < two_m; k++) for (k = 0; k < two_m; k++) {
{ for (i = 0; i < 128; i += two_m_plus_one) {
for(i = 0; i < 128; i += two_m_plus_one)
{
p = k + i; p = k + i;
q = p + two_m; q = p + two_m;
tmp_a_r = buf[p].real; tmp_a_r = buf[p].real;
...@@ -237,14 +227,12 @@ imdct_do_512(float x[],float y[],float delay[]) ...@@ -237,14 +227,12 @@ imdct_do_512(float x[],float y[],float delay[])
buf[p].imag = tmp_a_i + tmp_b_i; buf[p].imag = tmp_a_i + tmp_b_i;
buf[q].real = tmp_a_r - tmp_b_r; buf[q].real = tmp_a_r - tmp_b_r;
buf[q].imag = tmp_a_i - tmp_b_i; buf[q].imag = tmp_a_i - tmp_b_i;
} }
} }
} }
/* Post IFFT complex multiply plus IFFT complex conjugate*/ /* Post IFFT complex multiply plus IFFT complex conjugate*/
for( i=0; i < N/4; i++) for (i=0; i < N/4; i++) {
{
/* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */ /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
tmp_a_r = buf[i].real; tmp_a_r = buf[i].real;
tmp_a_i = - buf[i].imag; tmp_a_i = - buf[i].imag;
...@@ -256,29 +244,25 @@ imdct_do_512(float x[],float y[],float delay[]) ...@@ -256,29 +244,25 @@ imdct_do_512(float x[],float y[],float delay[])
delay_ptr = delay; delay_ptr = delay;
window_ptr = window; window_ptr = window;
/* Window and convert to real valued signal */ /* Window and convert to real valued signal */
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
*y_ptr++ = 2.0f * (-buf[N/8+i].imag * *window_ptr++ + *delay_ptr++); *y_ptr++ = 2.0f * (-buf[N/8+i].imag * *window_ptr++ + *delay_ptr++);
*y_ptr++ = 2.0f * ( buf[N/8-i-1].real * *window_ptr++ + *delay_ptr++); *y_ptr++ = 2.0f * (buf[N/8-i-1].real * *window_ptr++ + *delay_ptr++);
} }
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
*y_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++); *y_ptr++ = 2.0f * (-buf[i].real * *window_ptr++ + *delay_ptr++);
*y_ptr++ = 2.0f * ( buf[N/4-i-1].imag * *window_ptr++ + *delay_ptr++); *y_ptr++ = 2.0f * (buf[N/4-i-1].imag * *window_ptr++ + *delay_ptr++);
} }
/* The trailing edge of the window goes into the delay line */ /* The trailing edge of the window goes into the delay line */
delay_ptr = delay; delay_ptr = delay;
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
*delay_ptr++ = -buf[N/8+i].real * *--window_ptr; *delay_ptr++ = -buf[N/8+i].real * *--window_ptr;
*delay_ptr++ = buf[N/8-i-1].imag * *--window_ptr; *delay_ptr++ = buf[N/8-i-1].imag * *--window_ptr;
} }
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
*delay_ptr++ = buf[i].imag * *--window_ptr; *delay_ptr++ = buf[i].imag * *--window_ptr;
*delay_ptr++ = -buf[N/4-i-1].real * *--window_ptr; *delay_ptr++ = -buf[N/4-i-1].real * *--window_ptr;
} }
...@@ -304,8 +288,7 @@ imdct_do_256(float x[],float y[],float delay[]) ...@@ -304,8 +288,7 @@ imdct_do_256(float x[],float y[],float delay[])
buf_2 = &buf[64]; buf_2 = &buf[64];
/* Pre IFFT complex multiply plus IFFT cmplx conjugate */ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
for(k=0; k<N/8; k++) for (k=0; k<N/8; k++) {
{
/* X1[k] = X[2*k] */ /* X1[k] = X[2*k] */
/* X2[k] = X[2*k+1] */ /* X2[k] = X[2*k+1] */
...@@ -321,26 +304,21 @@ imdct_do_256(float x[],float y[],float delay[]) ...@@ -321,26 +304,21 @@ imdct_do_256(float x[],float y[],float delay[])
} }
/* IFFT Bit reversed shuffling */ /* IFFT Bit reversed shuffling */
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
k = bit_reverse_256[i]; k = bit_reverse_256[i];
if (k < i) if (k < i) {
{
swap_cmplx(&buf_1[i],&buf_1[k]); swap_cmplx(&buf_1[i],&buf_1[k]);
swap_cmplx(&buf_2[i],&buf_2[k]); swap_cmplx(&buf_2[i],&buf_2[k]);
} }
} }
/* FFT Merge */ /* FFT Merge */
for (m=0; m < 6; m++) for (m=0; m < 6; m++) {
{
two_m = (1 << m); two_m = (1 << m);
two_m_plus_one = (1 << (m+1)); two_m_plus_one = (1 << (m+1));
for(k = 0; k < two_m; k++) for (k = 0; k < two_m; k++) {
{ for (i = 0; i < 64; i += two_m_plus_one) {
for(i = 0; i < 64; i += two_m_plus_one)
{
p = k + i; p = k + i;
q = p + two_m; q = p + two_m;
/* Do block 1 */ /* Do block 1 */
...@@ -362,14 +340,12 @@ imdct_do_256(float x[],float y[],float delay[]) ...@@ -362,14 +340,12 @@ imdct_do_256(float x[],float y[],float delay[])
buf_2[p].imag = tmp_a_i + tmp_b_i; buf_2[p].imag = tmp_a_i + tmp_b_i;
buf_2[q].real = tmp_a_r - tmp_b_r; buf_2[q].real = tmp_a_r - tmp_b_r;
buf_2[q].imag = tmp_a_i - tmp_b_i; buf_2[q].imag = tmp_a_i - tmp_b_i;
} }
} }
} }
/* Post IFFT complex multiply */ /* Post IFFT complex multiply */
for( i=0; i < N/8; i++) for (i=0; i < N/8; i++) {
{
/* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
tmp_a_r = buf_1[i].real; tmp_a_r = buf_1[i].real;
tmp_a_i = - buf_1[i].imag; tmp_a_i = - buf_1[i].imag;
...@@ -383,8 +359,7 @@ imdct_do_256(float x[],float y[],float delay[]) ...@@ -383,8 +359,7 @@ imdct_do_256(float x[],float y[],float delay[])
} }
/* Window and convert to real valued signal */ /* Window and convert to real valued signal */
for(i=0; i<N/8; i++) for (i=0; i<N/8; i++) {
{
y[2*i] = -buf_1[i].imag * window[2*i]; y[2*i] = -buf_1[i].imag * window[2*i];
y[2*i+1] = buf_1[N/8-i-1].real * window[2*i+1]; y[2*i+1] = buf_1[N/8-i-1].real * window[2*i+1];
y[N/4+2*i] = -buf_1[i].real * window[N/4+2*i]; y[N/4+2*i] = -buf_1[i].real * window[N/4+2*i];
...@@ -396,8 +371,7 @@ imdct_do_256(float x[],float y[],float delay[]) ...@@ -396,8 +371,7 @@ imdct_do_256(float x[],float y[],float delay[])
} }
/* Overlap and add */ /* Overlap and add */
for(i=0; i<N/2; i++) for (i=0; i<N/2; i++) {
{
y[i] = 2 * (y[i] + delay[i]); y[i] = 2 * (y[i] + delay[i]);
delay[i] = y[N/2+i]; delay[i] = y[N/2+i];
} }
......
void imdct( ac3dec_t * p_ac3dec );
void imdct_init( void );
/* Exponent strategy constants */
#define EXP_REUSE (0)
#define EXP_D15 (1)
#define EXP_D25 (2)
#define EXP_D45 (3)
/* Delta bit allocation constants */
#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1)
#define DELTA_BIT_NONE (2)
#define DELTA_BIT_RESERVED (3)
/* ac3_bit_allocate.c */
void bit_allocate (ac3dec_t *);
/* ac3_downmix.c */
void downmix (ac3dec_t *, s16 *);
/* ac3_exponent.c */
int exponent_unpack (ac3dec_t *);
/* ac3_imdct.c */
void imdct (ac3dec_t * p_ac3dec);
/* ac3_mantissa.c */
void mantissa_unpack (ac3dec_t *);
/* ac3_parse.c */
int ac3_test_sync (ac3dec_t *);
void parse_syncinfo (ac3dec_t *);
void parse_bsi (ac3dec_t *);
void parse_audblk (ac3dec_t *);
void parse_auxdata (ac3dec_t *);
/* ac3_rematrix.c */
void rematrix (ac3dec_t *);
This diff is collapsed.
void mantissa_unpack( ac3dec_t * );
This diff is collapsed.
int ac3_test_sync (ac3dec_t *);
void parse_syncinfo( ac3dec_t * );
void parse_bsi( ac3dec_t * );
void parse_audblk( ac3dec_t * );
void parse_auxdata( ac3dec_t * );
#include "int_types.h" #include "int_types.h"
#include "ac3_decoder.h" #include "ac3_decoder.h"
#include "ac3_rematrix.h" #include "ac3_internal.h"
struct rematrix_band_s struct rematrix_band_s {
{
u32 start; u32 start;
u32 end; u32 end;
}; };
static struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}}; static struct rematrix_band_s rematrix_band[] = { {13,24}, {25,36}, {37 ,60}, {61,252}};
static __inline__ u32 min( u32 a, u32 b ) static __inline__ u32 min (u32 a, u32 b)
{ {
return( a < b ? a : b ); return (a < b ? a : b);
} }
/* This routine simply does stereo rematixing for the 2 channel /* This routine simply does stereo rematixing for the 2 channel
* stereo mode */ * stereo mode */
void rematrix( ac3dec_t * p_ac3dec ) void rematrix (ac3dec_t * p_ac3dec)
{ {
u32 num_bands; u32 num_bands;
u32 start; u32 start;
...@@ -25,23 +24,21 @@ void rematrix( ac3dec_t * p_ac3dec ) ...@@ -25,23 +24,21 @@ void rematrix( ac3dec_t * p_ac3dec )
u32 i,j; u32 i,j;
float left,right; float left,right;
if(p_ac3dec->audblk.cplinu || p_ac3dec->audblk.cplbegf > 2) if (p_ac3dec->audblk.cplinu || p_ac3dec->audblk.cplbegf > 2)
num_bands = 4; num_bands = 4;
else if (p_ac3dec->audblk.cplbegf > 0) else if (p_ac3dec->audblk.cplbegf > 0)
num_bands = 3; num_bands = 3;
else else
num_bands = 2; num_bands = 2;
for(i=0;i < num_bands; i++) for (i=0;i < num_bands; i++) {
{ if (!p_ac3dec->audblk.rematflg[i])
if(!p_ac3dec->audblk.rematflg[i])
continue; continue;
start = rematrix_band[i].start; start = rematrix_band[i].start;
end = min(rematrix_band[i].end ,12 * p_ac3dec->audblk.cplbegf + 36); end = min(rematrix_band[i].end ,12 * p_ac3dec->audblk.cplbegf + 36);
for(j=start;j < end; j++) for (j=start;j < end; j++) {
{
left = 0.5f * (p_ac3dec->coeffs.fbw[0][j] + p_ac3dec->coeffs.fbw[1][j]); left = 0.5f * (p_ac3dec->coeffs.fbw[0][j] + p_ac3dec->coeffs.fbw[1][j]);
right = 0.5f * (p_ac3dec->coeffs.fbw[0][j] - p_ac3dec->coeffs.fbw[1][j]); right = 0.5f * (p_ac3dec->coeffs.fbw[0][j] - p_ac3dec->coeffs.fbw[1][j]);
p_ac3dec->coeffs.fbw[0][j] = left; p_ac3dec->coeffs.fbw[0][j] = left;
......
void rematrix( ac3dec_t * );
...@@ -1074,8 +1074,10 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input, ...@@ -1074,8 +1074,10 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
break; break;
case AC3_AUDIO_ES: case AC3_AUDIO_ES:
#if 0
/* we skip 4 bytes at the beginning of the AC3 payload */ /* we skip 4 bytes at the beginning of the AC3 payload */
p_ts->i_payload_start += 4; p_ts->i_payload_start += 4;
#endif
p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo); p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
break; break;
......
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