Commit f5c7fdfa authored by Michel Kaempf's avatar Michel Kaempf

* Makefile :

- DECODER=old et non DECODER=new ;

* include/ac3_decoder.h :
- rajout, dans la structure ac3dec_thread_t, du membre b_invalid (utilis�
pour skipper une frame ac3 invalide) ;

* ac3_decoder/ac3_decoder.c :
- rajout du support de b_invalid ;

* ac3_decoder/ac3_exponent.c :
- optimisations ;

* ac3_decoder/ac3_mantissa.c :
- d�tection d'une mantisse invalide et m�j de b_invalid ;

* audio_output/audio_output.c :
- resynkro en cas de bouclage du flux ;
parent fa033ac3
......@@ -26,8 +26,8 @@ ARCH=MMX
#ARCH=PPC
# Decoder choice - ?? old decoder will be removed soon
#DECODER=old
DECODER=new
DECODER=old
#DECODER=new
# !!! don't forget to run this command after changing decoder type !!!
# touch input/input.c input/input_ctrl.c include/vlc.h include/video_decoder.h
......@@ -92,7 +92,6 @@ CCFLAGS += -D_GNU_SOURCE
CCFLAGS += -O6
CCFLAGS += -ffast-math -funroll-loops -fargument-noalias-global
CCFLAGS += -fomit-frame-pointer
#CCFLAGS += -fomit-frame-pointer -s
# Optimizations for x86 familiy, without MMX
ifeq ($(ARCH),)
......
......@@ -3,6 +3,8 @@
* (c)1999 VideoLAN
*****************************************************************************/
#define AC3_SIGSEGV
/* Exponent strategy constants */
#define EXP_REUSE (0)
#define EXP_D15 (1)
......@@ -335,6 +337,7 @@ typedef struct ac3dec_thread_s
vlc_thread_t thread_id; /* id for thread functions */
boolean_t b_die; /* `die' flag */
boolean_t b_error; /* `error' flag */
boolean_t b_invalid; /* `invalid' flag */
/*
* Input properties
......
......@@ -48,11 +48,6 @@ static void RunThread ( ac3dec_thread_t * p_adec );
static void ErrorThread ( ac3dec_thread_t * p_adec );
static void EndThread ( ac3dec_thread_t * p_adec );
//static byte_t GetByte ( bit_stream_t * p_bit_stream );
//static void NeedBits ( bit_stream_t * p_bit_stream, int i_bits );
//static void DumpBits ( bit_stream_t * p_bit_stream, int i_bits );
//static int FindHeader ( adec_thread_t * p_adec );
/*****************************************************************************
* ac3dec_CreateThread: creates an ac3 decoder thread
*****************************************************************************/
......@@ -136,6 +131,10 @@ void ac3dec_DestroyThread( ac3dec_thread_t * p_ac3dec )
*****************************************************************************/
static __inline__ int decode_find_sync( ac3dec_thread_t * p_ac3dec )
{
#ifdef AC3_SIGSEGV
int i = 0;
#endif
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
{
NeedBits( &(p_ac3dec->bit_stream), 16 );
......@@ -143,9 +142,20 @@ static __inline__ int decode_find_sync( ac3dec_thread_t * p_ac3dec )
{
DumpBits( &(p_ac3dec->bit_stream), 16 );
p_ac3dec->total_bits_read = 16;
#ifdef AC3_SIGSEGV
if ( i )
{
fprintf( stderr, "ac3dec debug: %i bit(s) skipped to synkronize\n", i );
}
#endif
return( 0 );
}
#ifdef AC3_SIGSEGV
DumpBits( &(p_ac3dec->bit_stream), 1 );
i += 1;
#else
DumpBits( &(p_ac3dec->bit_stream), 8 );
#endif
}
return( -1 );
}
......@@ -190,6 +200,10 @@ static int InitThread( ac3dec_thread_t * p_ac3dec )
*****************************************************************************/
static void RunThread( ac3dec_thread_t * p_ac3dec )
{
/*
mtime_t mdate = 0;
*/
intf_DbgMsg( "ac3dec debug: running ac3 decoder thread (%p) (pid == %i)\n", p_ac3dec, getpid() );
/* Initializing the ac3 decoder thread */
......@@ -201,8 +215,32 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
/* ac3 decoder thread's main loop */
while ( (!p_ac3dec->b_die) && (!p_ac3dec->b_error) )
{
decode_find_sync( p_ac3dec );
p_ac3dec->b_invalid = 0;
decode_find_sync( p_ac3dec );
switch ( p_ac3dec->syncinfo.fscod )
{
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:
fprintf( stderr, "ac3dec debug: invalid fscod\n" );
break;
}
/*
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = mdate;
mdate += 32000;
*/
if ( DECODER_FIFO_START(p_ac3dec->fifo)->b_has_pts )
{
p_ac3dec->p_aout_fifo->date[p_ac3dec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_ac3dec->fifo)->i_pts;
......@@ -214,26 +252,7 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
}
parse_syncinfo( p_ac3dec );
/*
switch ( p_ac3dec->syncinfo.fscod )
{
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:
fprintf( stderr, "ac3dec debug: fscod == `11' (reserved)\n" );
break;
}
*/
parse_bsi( p_ac3dec );
/* frame 1 */
......@@ -241,6 +260,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
exponent_unpack( p_ac3dec );
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
{
continue;
}
if ( p_ac3dec->bsi.acmod == 0x2 )
{
rematrix( p_ac3dec );
......@@ -256,6 +279,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
exponent_unpack( p_ac3dec );
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
{
continue;
}
if ( p_ac3dec->bsi.acmod == 0x2 )
{
rematrix( p_ac3dec );
......@@ -272,6 +299,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
exponent_unpack( p_ac3dec );
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
{
continue;
}
if ( p_ac3dec->bsi.acmod == 0x2 )
{
rematrix( p_ac3dec );
......@@ -288,6 +319,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
exponent_unpack( p_ac3dec );
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
{
continue;
}
if ( p_ac3dec->bsi.acmod == 0x2 )
{
rematrix( p_ac3dec );
......@@ -304,6 +339,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
exponent_unpack( p_ac3dec );
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
{
continue;
}
if ( p_ac3dec->bsi.acmod == 0x2 )
{
rematrix( p_ac3dec );
......@@ -320,6 +359,10 @@ static void RunThread( ac3dec_thread_t * p_ac3dec )
exponent_unpack( p_ac3dec );
bit_allocate( p_ac3dec );
mantissa_unpack( p_ac3dec );
if ( p_ac3dec->b_invalid )
{
continue;
}
if ( p_ac3dec->bsi.acmod == 0x2 )
{
rematrix( p_ac3dec );
......
......@@ -23,9 +23,17 @@
#include "ac3_decoder.h"
#include "ac3_exponent.h"
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, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 3, 3, 3 };
static const s16 exps_2[128] = { -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2, -2, -2 };
static const s16 exps_3[128] = { -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0, 1, 2, -2, -1, 0 };
/*
static const s16 exps_1[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5 };
static const s16 exps_2[128] = { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0 };
static const s16 exps_3[128] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2 };
*/
static __inline__ void exp_unpack_ch( u16 type, u16 expstr, u16 ngrps, u16 initial_exp, u16 exps[], u16 * dest )
{
......@@ -35,8 +43,10 @@ static __inline__ void exp_unpack_ch( u16 type, u16 expstr, u16 ngrps, u16 initi
s16 exp_1,exp_2,exp_3;
*/
if(expstr == EXP_REUSE)
if ( expstr == EXP_REUSE )
{
return;
}
/* Handle the initial absolute exponent */
exp_acc = initial_exp;
......@@ -44,10 +54,85 @@ static __inline__ void exp_unpack_ch( u16 type, u16 expstr, u16 ngrps, u16 initi
/* In the case of a fbw channel then the initial absolute values is
* also an exponent */
if(type != UNPACK_CPL)
if ( type != UNPACK_CPL )
{
dest[j++] = exp_acc;
}
/* Loop through the groups and fill the dest array appropriately */
switch ( expstr )
{
case EXP_D45:
for ( i = 0; i < ngrps; i++ )
{
#ifdef AC3_SIGSEGV
if ( exps[i] > 127 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
}
#endif
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
case EXP_D25:
for ( i = 0; i < ngrps; i++ )
{
#ifdef AC3_SIGSEGV
if ( exps[i] > 127 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
}
#endif
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
dest[j++] = exp_acc;
}
break;
case EXP_D15:
for ( i = 0; i < ngrps; i++ )
{
#ifdef AC3_SIGSEGV
if ( exps[i] > 127 )
{
fprintf( stderr, "ac3dec debug: invalid exponent\n" );
}
#endif
exp_acc += (exps_1[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_2[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
exp_acc += (exps_3[exps[i]] /*- 2*/);
dest[j++] = exp_acc;
}
break;
default:
fprintf( stderr, "ac3dec debug: expstr == %i <maxx@via.ecp.fr>\n", expstr );
break;
}
#if 0
for ( i = 0; i < ngrps; i++ )
{
/*
......@@ -107,21 +192,25 @@ static __inline__ void exp_unpack_ch( u16 type, u16 expstr, u16 ngrps, u16 initi
break;
}
}
#endif
}
void exponent_unpack( ac3dec_thread_t * p_ac3dec )
{
u16 i;
for(i=0; i< p_ac3dec->bsi.nfchans; i++)
exp_unpack_ch(UNPACK_FBW, p_ac3dec->audblk.chexpstr[i], p_ac3dec->audblk.nchgrps[i], p_ac3dec->audblk.exps[i][0],
&p_ac3dec->audblk.exps[i][1], p_ac3dec->audblk.fbw_exp[i]);
for ( i = 0; i < p_ac3dec->bsi.nfchans; i++ )
{
exp_unpack_ch( UNPACK_FBW, p_ac3dec->audblk.chexpstr[i], p_ac3dec->audblk.nchgrps[i], p_ac3dec->audblk.exps[i][0], &p_ac3dec->audblk.exps[i][1], p_ac3dec->audblk.fbw_exp[i] );
}
if(p_ac3dec->audblk.cplinu)
exp_unpack_ch(UNPACK_CPL, p_ac3dec->audblk.cplexpstr, p_ac3dec->audblk.ncplgrps, p_ac3dec->audblk.cplabsexp << 1,
p_ac3dec->audblk.cplexps, &p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant]);
if ( p_ac3dec->audblk.cplinu )
{
exp_unpack_ch( UNPACK_CPL, p_ac3dec->audblk.cplexpstr, p_ac3dec->audblk.ncplgrps, p_ac3dec->audblk.cplabsexp << 1, p_ac3dec->audblk.cplexps, &p_ac3dec->audblk.cpl_exp[p_ac3dec->audblk.cplstrtmant] );
}
if(p_ac3dec->bsi.lfeon)
exp_unpack_ch(UNPACK_LFE, p_ac3dec->audblk.lfeexpstr, 2, p_ac3dec->audblk.lfeexps[0],
&p_ac3dec->audblk.lfeexps[1], p_ac3dec->audblk.lfe_exp);
if ( p_ac3dec->bsi.lfeon )
{
exp_unpack_ch( UNPACK_LFE, p_ac3dec->audblk.lfeexpstr, 2, p_ac3dec->audblk.lfeexps[0], &p_ac3dec->audblk.lfeexps[1], p_ac3dec->audblk.lfe_exp );
}
}
......@@ -209,11 +209,14 @@ static __inline__ float float_get( ac3dec_thread_t * p_ac3dec, u16 bap, u16 exp
DumpBits( &(p_ac3dec->bit_stream), 5 );
p_ac3dec->total_bits_read += 5;
/*
if(group_code > 26)
#ifdef AC3_SIGSEGV
if ( group_code > 26 )
{
//FIXME do proper block error handling
fprintf( stderr, "!! Invalid mantissa !!\n" );
*/
fprintf( stderr, "ac3dec debug: invalid mantissa\n" );
p_ac3dec->b_invalid = 1;
}
#endif
//q_1[ 0 ] = q_1_0[ group_code ];
q_1[ 1 ] = q_1_1[ group_code ];
......@@ -233,11 +236,14 @@ static __inline__ float float_get( ac3dec_thread_t * p_ac3dec, u16 bap, u16 exp
DumpBits( &(p_ac3dec->bit_stream), 7 );
p_ac3dec->total_bits_read += 7;
/*
if(group_code > 124)
#ifdef AC3_SIGSEGV
if ( group_code > 124 )
{
//FIXME do proper block error handling
fprintf( stderr, "!! Invalid mantissa !!\n" );
*/
fprintf( stderr, "ac3dec debug: invalid mantissa\n" );
p_ac3dec->b_invalid = 1;
}
#endif
//q_2[ 0 ] = q_2_0[ group_code ];
q_2[ 1 ] = q_2_1[ group_code ];
......@@ -253,11 +259,14 @@ static __inline__ float float_get( ac3dec_thread_t * p_ac3dec, u16 bap, u16 exp
DumpBits( &(p_ac3dec->bit_stream), 3 );
p_ac3dec->total_bits_read += 3;
/*
if(group_code > 6)
#ifdef AC3_SIGSEGV
if ( group_code > 6 )
{
//FIXME do proper block error handling
fprintf( stderr, "!! Invalid mantissa !!\n" );
*/
fprintf( stderr, "ac3dec debug: invalid mantissa\n" );
p_ac3dec->b_invalid = 1;
}
#endif
return( q_3[group_code] * exp_lut[exp] );
......@@ -271,11 +280,14 @@ static __inline__ float float_get( ac3dec_thread_t * p_ac3dec, u16 bap, u16 exp
DumpBits( &(p_ac3dec->bit_stream), 7 );
p_ac3dec->total_bits_read += 7;
/*
if(group_code > 120)
#ifdef AC3_SIGSEGV
if ( group_code > 120 )
{
//FIXME do proper block error handling
fprintf( stderr, "!! Invalid mantissa !!\n" );
*/
fprintf( stderr, "ac3dec debug: invalid mantissa\n" );
p_ac3dec->b_invalid = 1;
}
#endif
//q_4[ 0 ] = q_4_0[ group_code ];
q_4[ 0 ] = q_4_1[ group_code ];
......@@ -290,11 +302,14 @@ static __inline__ float float_get( ac3dec_thread_t * p_ac3dec, u16 bap, u16 exp
DumpBits( &(p_ac3dec->bit_stream), 4 );
p_ac3dec->total_bits_read += 4;
/*
if(group_code > 14)
#ifdef AC3_SIGSEGV
if ( group_code > 14 )
{
//FIXME do proper block error handling
fprintf( stderr, "!! Invalid mantissa !!\n" );
*/
fprintf( stderr, "ac3dec debug: invalid mantissa\n" );
p_ac3dec->b_invalid = 1;
}
#endif
return( q_5[group_code] * exp_lut[exp] );
......
......@@ -503,13 +503,11 @@ static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo/*,
if ( aout_date < p_fifo->date[p_fifo->l_next_frame] )
{
*/
/*
if ( (p_fifo->date[p_fifo->l_next_frame] - p_fifo->date[p_fifo->l_start_frame] > 1000000) || (p_fifo->date[p_fifo->l_next_frame] <= p_fifo->date[p_fifo->l_start_frame]) )
{
fprintf( stderr, "aout debug: p_fifo->l_rate == %li\n", p_fifo->l_rate );
p_fifo->date[p_fifo->l_start_frame] = p_fifo->date[p_fifo->l_next_frame] - ((1000000 * ((mtime_t)(p_fifo->l_frame_size * ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE))) >> p_fifo->b_stereo) / ((mtime_t)p_fifo->l_rate));
}
*/
p_fifo->b_next_frame = 1;
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