Commit 15f3b0f6 authored by Christophe Massiot's avatar Christophe Massiot

* Miscellaneous S/PDIF fixes.

* New NextPTS() function, to replace CurrentPTS() (gives the PTS which will
  be valid for NEXT byte).
* Fixed mono mode in the builtin mpeg audio decoder.
* Various fixes related to PTS calculation in audio decoders.
parent 44fc8c89
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders * input_ext-dec.h: structures exported to the VideoLAN decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: input_ext-dec.h,v 1.69 2002/08/12 22:12:50 massiot Exp $ * $Id: input_ext-dec.h,v 1.70 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Kaempf <maxx@via.ecp.fr> * Michel Kaempf <maxx@via.ecp.fr>
...@@ -226,6 +226,7 @@ VLC_EXPORT( u32, UnalignedShowBits, ( bit_stream_t *, unsigned int ) ); ...@@ -226,6 +226,7 @@ VLC_EXPORT( u32, UnalignedShowBits, ( bit_stream_t *, unsigned int ) );
VLC_EXPORT( void, UnalignedRemoveBits, ( bit_stream_t * ) ); VLC_EXPORT( void, UnalignedRemoveBits, ( bit_stream_t * ) );
VLC_EXPORT( u32, UnalignedGetBits, ( bit_stream_t *, unsigned int ) ); VLC_EXPORT( u32, UnalignedGetBits, ( bit_stream_t *, unsigned int ) );
VLC_EXPORT( void, CurrentPTS, ( bit_stream_t *, mtime_t *, mtime_t * ) ); VLC_EXPORT( void, CurrentPTS, ( bit_stream_t *, mtime_t *, mtime_t * ) );
VLC_EXPORT( void, NextPTS, ( bit_stream_t *, mtime_t *, mtime_t * ) );
/***************************************************************************** /*****************************************************************************
* AlignWord : fill in the bit buffer so that the byte pointer be aligned * AlignWord : fill in the bit buffer so that the byte pointer be aligned
......
...@@ -78,6 +78,7 @@ struct module_symbols_t ...@@ -78,6 +78,7 @@ struct module_symbols_t
void (* CurrentPTS_inner) ( bit_stream_t *, mtime_t *, mtime_t * ) ; void (* CurrentPTS_inner) ( bit_stream_t *, mtime_t *, mtime_t * ) ;
void (* DecoderError_inner) ( decoder_fifo_t * p_fifo ) ; void (* DecoderError_inner) ( decoder_fifo_t * p_fifo ) ;
void (* InitBitstream_inner) ( bit_stream_t *, decoder_fifo_t *, void ( * )( bit_stream_t *, vlc_bool_t ), void * p_callback_arg ) ; void (* InitBitstream_inner) ( bit_stream_t *, decoder_fifo_t *, void ( * )( bit_stream_t *, vlc_bool_t ), void * p_callback_arg ) ;
void (* NextPTS_inner) ( bit_stream_t *, mtime_t *, mtime_t * ) ;
void (* UnalignedRemoveBits_inner) ( bit_stream_t * ) ; void (* UnalignedRemoveBits_inner) ( bit_stream_t * ) ;
void (* __config_PutFloat_inner) (vlc_object_t *, const char *, float) ; void (* __config_PutFloat_inner) (vlc_object_t *, const char *, float) ;
void (* __config_PutInt_inner) (vlc_object_t *, const char *, int) ; void (* __config_PutInt_inner) (vlc_object_t *, const char *, int) ;
...@@ -159,6 +160,7 @@ struct module_symbols_t ...@@ -159,6 +160,7 @@ struct module_symbols_t
# define GetLang_2T p_symbols->GetLang_2T_inner # define GetLang_2T p_symbols->GetLang_2T_inner
# define InitBitstream p_symbols->InitBitstream_inner # define InitBitstream p_symbols->InitBitstream_inner
# define NextDataPacket p_symbols->NextDataPacket_inner # define NextDataPacket p_symbols->NextDataPacket_inner
# define NextPTS p_symbols->NextPTS_inner
# define UnalignedGetBits p_symbols->UnalignedGetBits_inner # define UnalignedGetBits p_symbols->UnalignedGetBits_inner
# define UnalignedRemoveBits p_symbols->UnalignedRemoveBits_inner # define UnalignedRemoveBits p_symbols->UnalignedRemoveBits_inner
# define UnalignedShowBits p_symbols->UnalignedShowBits_inner # define UnalignedShowBits p_symbols->UnalignedShowBits_inner
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52tospdif.c : encapsulates A/52 frames into S/PDIF packets * a52tospdif.c : encapsulates A/52 frames into S/PDIF packets
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: a52tospdif.c,v 1.9 2002/08/21 22:41:59 massiot Exp $ * $Id: a52tospdif.c,v 1.10 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -98,14 +98,14 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -98,14 +98,14 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
/* Copy the S/PDIF headers. */ /* Copy the S/PDIF headers. */
memcpy( p_out, p_sync, 6 ); memcpy( p_out, p_sync, 6 );
pi_length = (u16 *)(p_out + 6); pi_length = (u16 *)(p_out + 6);
*pi_length = i_length; *pi_length = i_length * 8;
/* FIXME : if i_length is odd, the following code sucks. What should /* FIXME : if i_length is odd, the following code sucks. What should
* we do ? --Meuuh */ * we do ? --Meuuh */
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
# ifdef HAVE_SWAB # ifdef HAVE_SWAB
swab( p_out + 8, p_in, i_length ); swab( p_in, p_out + 8, i_length );
# else # else
p_out += 8; p_out += 8;
for ( i = i_length / 2 ; i-- ; ) for ( i = i_length / 2 ; i-- ; )
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (http://liba52.sf.net/). * (http://liba52.sf.net/).
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2002 VideoLAN * Copyright (C) 2001, 2002 VideoLAN
* $Id: a52.c,v 1.6 2002/08/21 22:41:59 massiot Exp $ * $Id: a52.c,v 1.7 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Gildas Bazin <gbazin@netcourrier.com> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -167,6 +167,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -167,6 +167,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
RemoveBits( &p_dec->bit_stream, 8 ); RemoveBits( &p_dec->bit_stream, 8 );
} }
/* Set the Presentation Time Stamp */
NextPTS( &p_dec->bit_stream, &pts, NULL );
if ( pts != 0 && pts != aout_DateGet( &p_dec->end_date ) )
{
aout_DateSet( &p_dec->end_date, pts );
}
/* Get A/52 frame header */ /* Get A/52 frame header */
GetChunk( &p_dec->bit_stream, p_frame_buffer, 7 ); GetChunk( &p_dec->bit_stream, p_frame_buffer, 7 );
if( p_dec->p_fifo->b_die ) break; if( p_dec->p_fifo->b_die ) break;
...@@ -207,13 +214,6 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -207,13 +214,6 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
} }
} }
/* Set the Presentation Time Stamp */
CurrentPTS( &p_dec->bit_stream, &pts, NULL );
if ( pts != 0 && pts != aout_DateGet( &p_dec->end_date ) )
{
aout_DateSet( &p_dec->end_date, pts );
}
/* Get the complete frame */ /* Get the complete frame */
GetChunk( &p_dec->bit_stream, p_frame_buffer + 7, GetChunk( &p_dec->bit_stream, p_frame_buffer + 7,
i_frame_size - 7 ); i_frame_size - 7 );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52old.c: A52 decoder module main file * a52old.c: A52 decoder module main file
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: a52old.c,v 1.4 2002/08/23 14:05:22 sam Exp $ * $Id: a52old.c,v 1.5 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Michel Lespinasse <walken@zoy.org> * Authors: Michel Lespinasse <walken@zoy.org>
* *
...@@ -186,7 +186,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -186,7 +186,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
continue; continue;
} }
CurrentPTS( &p_a52dec->bit_stream, &i_pts, NULL ); NextPTS( &p_a52dec->bit_stream, &i_pts, NULL );
if( i_pts != 0 && i_pts != aout_DateGet( &end_date ) ) if( i_pts != 0 && i_pts != aout_DateGet( &end_date ) )
{ {
aout_DateSet( &end_date, i_pts ); aout_DateSet( &end_date, i_pts );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* decoder.c: MPEG audio decoder thread * decoder.c: MPEG audio decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: decoder.c,v 1.2 2002/08/17 15:35:10 fenrir Exp $ * $Id: decoder.c,v 1.3 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#include "generic.h" #include "generic.h"
#include "decoder.h" #include "decoder.h"
#define ADEC_FRAME_SIZE 1152 /* XXX Frame size for only one channel */ #define ADEC_FRAME_NB 1152
/***************************************************************************** /*****************************************************************************
* Local Prototypes * Local Prototypes
...@@ -83,10 +83,10 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -83,10 +83,10 @@ static int OpenDecoder( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int RunDecoder( decoder_fifo_t *p_fifo ) static int RunDecoder( decoder_fifo_t *p_fifo )
{ {
adec_thread_t * p_adec; adec_thread_t * p_dec;
/* Allocate the memory needed to store the thread's structure */ /* Allocate the memory needed to store the thread's structure */
if ( (p_adec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL ) if ( (p_dec = (adec_thread_t *)malloc (sizeof(adec_thread_t))) == NULL )
{ {
msg_Err( p_fifo, "out of memory" ); msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo ); DecoderError( p_fifo );
...@@ -96,43 +96,40 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -96,43 +96,40 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
/* /*
* Initialize the thread properties * Initialize the thread properties
*/ */
p_adec->p_fifo = p_fifo; p_dec->p_fifo = p_fifo;
/* /*
* Initilize the banks * Initilize the banks
*/ */
p_adec->bank_0.actual = p_adec->bank_0.v1; p_dec->bank_0.actual = p_dec->bank_0.v1;
p_adec->bank_0.pos = 0; p_dec->bank_0.pos = 0;
p_adec->bank_1.actual = p_adec->bank_1.v1; p_dec->bank_1.actual = p_dec->bank_1.v1;
p_adec->bank_1.pos = 0; p_dec->bank_1.pos = 0;
/* /*
* Initialize bit stream * Initialize bit stream
*/ */
InitBitstream( &p_adec->bit_stream, p_adec->p_fifo, NULL, NULL ); InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, NULL, NULL );
/* We do not create the audio output fifo now, but /* We do not create the audio output fifo now, but
it will be created when the first frame is received */ it will be created when the first frame is received */
p_adec->p_aout = NULL; p_dec->p_aout = NULL;
p_adec->p_aout_input = NULL; p_dec->p_aout_input = NULL;
p_adec->i_pts = 0;
p_adec->i_sync = 0;
/* Audio decoder thread's main loop */ /* Audio decoder thread's main loop */
while( (!p_adec->p_fifo->b_die) && (!p_adec->p_fifo->b_error) ) while( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
{ {
DecodeThread( p_adec ); DecodeThread( p_dec );
} }
/* If b_error is set, the audio decoder thread enters the error loop */ /* If b_error is set, the audio decoder thread enters the error loop */
if( p_adec->p_fifo->b_error ) if( p_dec->p_fifo->b_error )
{ {
DecoderError( p_adec->p_fifo ); DecoderError( p_dec->p_fifo );
} }
/* End of the audio decoder thread */ /* End of the audio decoder thread */
EndThread( p_adec ); EndThread( p_dec );
return( 0 ); return( 0 );
} }
...@@ -144,76 +141,86 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -144,76 +141,86 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
/***************************************************************************** /*****************************************************************************
* DecodeThread: decodes a mpeg frame * DecodeThread: decodes a mpeg frame
*****************************************************************************/ *****************************************************************************/
static void DecodeThread( adec_thread_t * p_adec ) static void DecodeThread( adec_thread_t * p_dec )
{ {
mtime_t i_pts; mtime_t pts;
aout_buffer_t *p_aout_buffer; aout_buffer_t * p_aout_buffer;
adec_sync_info_t sync_info; adec_sync_info_t sync_info;
if( ! adec_SyncFrame (p_adec, &sync_info) ) /* Look for sync word - should be 0x0b77 */
RealignBits( &p_dec->bit_stream );
while( (ShowBits( &p_dec->bit_stream, 16 ) & 0xfff0) != 0xfff0 &&
(!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error))
{
RemoveBits( &p_dec->bit_stream, 8 );
}
/* Set the Presentation Time Stamp */
NextPTS( &p_dec->bit_stream, &pts, NULL );
if ( pts != 0 && pts != aout_DateGet( &p_dec->end_date ) )
{ {
aout_DateSet( &p_dec->end_date, pts );
}
if( !adec_SyncFrame( p_dec, &sync_info ) )
{
/* Create the output fifo if it doesn't exist yet */ /* Create the output fifo if it doesn't exist yet */
if( ( p_adec->p_aout_input == NULL )|| if( ( p_dec->p_aout_input == NULL )||
( p_adec->output_format.i_channels != ( sync_info.b_stereo ? 2 : 1 ) )|| ( p_dec->output_format.i_channels != ( sync_info.b_stereo ? 2 : 1 ) )||
( p_adec->output_format.i_rate != sync_info.sample_rate ) ) ( p_dec->output_format.i_rate != sync_info.sample_rate ) )
{ {
if( p_adec->p_aout_input ) if( p_dec->p_aout_input )
{ {
/* Delete old output */ /* Delete old output */
msg_Warn( p_adec->p_fifo, "opening a new aout" ); msg_Warn( p_dec->p_fifo, "opening a new aout" );
aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input ); aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
} }
/* Set output configuration */ /* Set output configuration */
p_adec->output_format.i_format = AOUT_FMT_FLOAT32; p_dec->output_format.i_format = AOUT_FMT_FLOAT32;
p_adec->output_format.i_channels = ( sync_info.b_stereo ? 2 : 1 ); p_dec->output_format.i_channels = ( sync_info.b_stereo ? 2 : 1 );
p_adec->output_format.i_rate = sync_info.sample_rate; p_dec->output_format.i_rate = sync_info.sample_rate;
p_adec->p_aout_input = aout_InputNew( p_adec->p_fifo, aout_DateInit( &p_dec->end_date, sync_info.sample_rate );
&p_adec->p_aout, p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_adec->output_format ); &p_dec->p_aout,
&p_dec->output_format );
} }
if( p_adec->p_aout_input == NULL ) if( p_dec->p_aout_input == NULL )
{ {
msg_Err( p_adec->p_fifo, "failed to create aout fifo" ); msg_Err( p_dec->p_fifo, "failed to create aout fifo" );
p_adec->p_fifo->b_error = 1; p_dec->p_fifo->b_error = 1;
return; return;
} }
p_aout_buffer = aout_BufferNew( p_adec->p_aout, if( !aout_DateGet( &p_dec->end_date ) )
p_adec->p_aout_input,
ADEC_FRAME_SIZE );
if( !p_aout_buffer )
{ {
msg_Err( p_adec->p_fifo, "cannot get aout buffer" ); /* We've just started the stream, wait for the first PTS. */
p_adec->p_fifo->b_error = 1;
return; return;
} }
p_adec->i_sync = 1; p_aout_buffer = aout_BufferNew( p_dec->p_aout,
p_dec->p_aout_input,
ADEC_FRAME_NB );
CurrentPTS( &p_adec->bit_stream, &i_pts, NULL ); if( !p_aout_buffer )
if( i_pts > 0 )
{ {
p_adec->i_pts = i_pts; msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
p_dec->p_fifo->b_error = 1;
return;
} }
p_aout_buffer->start_date = p_adec->i_pts; p_aout_buffer->start_date = aout_DateGet( &p_dec->end_date );
p_adec->i_pts += (mtime_t)1000000 * (mtime_t)ADEC_FRAME_SIZE / p_aout_buffer->end_date = aout_DateIncrement( &p_dec->end_date,
(mtime_t)p_adec->output_format.i_rate; ADEC_FRAME_NB );
p_aout_buffer->end_date = p_adec->i_pts;
if( adec_DecodeFrame (p_adec, (float*)p_aout_buffer->p_buffer ) ) if( adec_DecodeFrame (p_dec, (float*)p_aout_buffer->p_buffer ) )
{ {
/* Ouch, failed decoding... We'll have to resync */ /* Ouch, failed decoding... We'll have to resync */
p_adec->i_sync = 0; aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
aout_BufferDelete( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
} }
else else
{ {
aout_BufferPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer ); aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input, p_aout_buffer );
} }
} }
} }
...@@ -224,16 +231,16 @@ static void DecodeThread( adec_thread_t * p_adec ) ...@@ -224,16 +231,16 @@ static void DecodeThread( adec_thread_t * p_adec )
* This function is called when the thread ends after a sucessful * This function is called when the thread ends after a sucessful
* initialization. * initialization.
*****************************************************************************/ *****************************************************************************/
static void EndThread ( adec_thread_t *p_adec ) static void EndThread ( adec_thread_t *p_dec )
{ {
/* If the audio output fifo was created, we destroy it */ /* If the audio output fifo was created, we destroy it */
if( p_adec->p_aout_input ) if( p_dec->p_aout_input )
{ {
aout_InputDelete( p_adec->p_aout, p_adec->p_aout_input ); aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
} }
/* Destroy descriptor */ /* Destroy descriptor */
free( p_adec ); free( p_dec );
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mpeg_adec.h : audio decoder thread interface * mpeg_adec.h : audio decoder thread interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: decoder.h,v 1.2 2002/08/17 15:35:10 fenrir Exp $ * $Id: decoder.h,v 1.3 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* *
...@@ -52,8 +52,7 @@ typedef struct adec_thread_s ...@@ -52,8 +52,7 @@ typedef struct adec_thread_s
aout_instance_t *p_aout; /* opaque */ aout_instance_t *p_aout; /* opaque */
aout_input_t *p_aout_input; /* opaque */ aout_input_t *p_aout_input; /* opaque */
audio_sample_format_t output_format; audio_sample_format_t output_format;
mtime_t i_pts; audio_date_t end_date;
} adec_thread_t; } adec_thread_t;
/***************************************************************************** /*****************************************************************************
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* generic.c: MPEG audio decoder * generic.c: MPEG audio decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: generic.c,v 1.2 2002/08/17 15:35:10 fenrir Exp $ * $Id: generic.c,v 1.3 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -46,24 +46,24 @@ int adec_Init( adec_thread_t * p_adec ) ...@@ -46,24 +46,24 @@ int adec_Init( adec_thread_t * p_adec )
int adec_SyncFrame( adec_thread_t * p_adec, adec_sync_info_t * p_sync_info ) int adec_SyncFrame( adec_thread_t * p_adec, adec_sync_info_t * p_sync_info )
{ {
static int mpeg1_sample_rate[3] = {44100, 48000, 32000}; static const int mpeg1_sample_rate[3] = {44100, 48000, 32000};
static int mpeg1_layer1_bit_rate[15] = static const int mpeg1_layer1_bit_rate[15] =
{ {
0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448
}; };
static int mpeg1_layer2_bit_rate[15] = static const int mpeg1_layer2_bit_rate[15] =
{ {
0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384
}; };
static int mpeg2_layer1_bit_rate[15] = static const int mpeg2_layer1_bit_rate[15] =
{ {
0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256
}; };
static int mpeg2_layer2_bit_rate[15] = static const int mpeg2_layer2_bit_rate[15] =
{ {
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
}; };
static int * bit_rate_table[8] = static const int * bit_rate_table[8] =
{ {
NULL, NULL, mpeg2_layer2_bit_rate, mpeg2_layer1_bit_rate, NULL, NULL, mpeg2_layer2_bit_rate, mpeg2_layer1_bit_rate,
NULL, NULL, mpeg1_layer2_bit_rate, mpeg1_layer1_bit_rate NULL, NULL, mpeg1_layer2_bit_rate, mpeg1_layer1_bit_rate
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* layer2.c: MPEG Layer II audio decoder * layer2.c: MPEG Layer II audio decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: layer2.c,v 1.3 2002/08/17 15:35:10 fenrir Exp $ * $Id: layer2.c,v 1.4 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Michel Kaempf <maxx@via.ecp.fr> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -434,13 +434,9 @@ int adec_layer2_mono( adec_thread_t * p_adec, float * buffer ) ...@@ -434,13 +434,9 @@ int adec_layer2_mono( adec_thread_t * p_adec, float * buffer )
for (s = 0; s < 3; s++) for (s = 0; s < 3; s++)
{ {
DCT32( &p_adec->bank_0, sample[s] ); DCT32( &p_adec->bank_0, sample[s] );
PCM( &p_adec->bank_0, buffer, 2 ); PCM( &p_adec->bank_0, buffer, 1 );
/* FIXME: one shouldn't have to do it twice ! */
DCT32( &p_adec->bank_1, sample[s] );
PCM( &p_adec->bank_1, buffer + 1, 2 );
buffer += 64; buffer += 32;
} }
} }
} }
......
/***************************************************************************** /*****************************************************************************
* spdif.c: A52 pass-through to external decoder with enabled soundcard * spdif.c: A/52 pass-through to external decoder with enabled soundcard
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2002 VideoLAN * Copyright (C) 2001-2002 VideoLAN
* $Id: spdif.c,v 1.6 2002/08/19 21:31:11 massiot Exp $ * $Id: spdif.c,v 1.7 2002/08/26 23:00:22 massiot Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi> * Juha Yrjola <jyrjola@cc.hut.fi>
...@@ -117,7 +117,7 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -117,7 +117,7 @@ static int OpenDecoder( vlc_object_t *p_this )
static int RunDecoder( decoder_fifo_t *p_fifo ) static int RunDecoder( decoder_fifo_t *p_fifo )
{ {
spdif_thread_t * p_dec; spdif_thread_t * p_dec;
mtime_t last_date = 0; audio_date_t end_date;
/* Allocate the memory needed to store the thread's structure */ /* Allocate the memory needed to store the thread's structure */
p_dec = malloc( sizeof(spdif_thread_t) ); p_dec = malloc( sizeof(spdif_thread_t) );
...@@ -154,6 +154,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -154,6 +154,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
RemoveBits( &p_dec->bit_stream, 8 ); RemoveBits( &p_dec->bit_stream, 8 );
} }
/* Set the Presentation Time Stamp */
NextPTS( &p_dec->bit_stream, &pts, NULL );
if ( pts != 0 && pts != aout_DateGet( &end_date ) )
{
aout_DateSet( &end_date, pts );
}
/* Get A/52 frame header */ /* Get A/52 frame header */
GetChunk( &p_dec->bit_stream, p_header, 7 ); GetChunk( &p_dec->bit_stream, p_header, 7 );
if( p_dec->p_fifo->b_die ) break; if( p_dec->p_fifo->b_die ) break;
...@@ -183,7 +190,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -183,7 +190,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
p_dec->output_format.i_rate = i_rate; p_dec->output_format.i_rate = i_rate;
p_dec->output_format.i_bytes_per_frame = i_frame_size; p_dec->output_format.i_bytes_per_frame = i_frame_size;
p_dec->output_format.i_frame_length = A52_FRAME_NB; p_dec->output_format.i_frame_length = A52_FRAME_NB;
/* p_dec->output_format.i_channels = i_channels; */ aout_DateInit( &end_date, i_rate );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo, p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_dec->p_aout, &p_dec->p_aout,
&p_dec->output_format ); &p_dec->output_format );
...@@ -195,14 +202,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -195,14 +202,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
} }
} }
/* Set the Presentation Time Stamp */ if ( !aout_DateGet( &end_date ) )
CurrentPTS( &p_dec->bit_stream, &pts, NULL );
if ( pts != 0 )
{
last_date = pts;
}
if ( !last_date )
{ {
byte_t p_junk[3840]; byte_t p_junk[3840];
...@@ -214,10 +214,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -214,10 +214,9 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input, p_buffer = aout_BufferNew( p_dec->p_aout, p_dec->p_aout_input,
A52_FRAME_NB ); A52_FRAME_NB );
if ( p_buffer == NULL ) return -1; if ( p_buffer == NULL ) return -1;
p_buffer->start_date = last_date; p_buffer->start_date = aout_DateGet( &end_date );
last_date += (mtime_t)(A52_FRAME_NB * 1000000) p_buffer->end_date = aout_DateIncrement( &end_date,
/ p_dec->output_format.i_rate; A52_FRAME_NB );
p_buffer->end_date = last_date;
/* Get the whole frame. */ /* Get the whole frame. */
memcpy( p_buffer->p_buffer, p_header, 7 ); memcpy( p_buffer->p_buffer, p_header, 7 );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input.c : internal management of input streams for the audio output * input.c : internal management of input streams for the audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: input.c,v 1.8 2002/08/24 10:19:43 sam Exp $ * $Id: input.c,v 1.9 2002/08/26 23:00:23 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
#include <vlc/vlc.h> #include <vlc/vlc.h>
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "audio_output.h" #include "audio_output.h"
#include "aout_internal.h" #include "aout_internal.h"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* mixer.c : audio output mixing operations * mixer.c : audio output mixing operations
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: mixer.c,v 1.9 2002/08/21 22:41:59 massiot Exp $ * $Id: mixer.c,v 1.10 2002/08/26 23:00:23 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -249,10 +249,14 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -249,10 +249,14 @@ static int MixBuffer( aout_instance_t * p_aout )
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
return -1; return -1;
} }
/* This is again a bit kludgy - for the S/PDIF mixer. */
if ( p_aout->mixer.output_alloc.i_alloc_type != AOUT_ALLOC_NONE )
{
p_output_buffer->i_nb_samples = p_aout->output.i_nb_samples; p_output_buffer->i_nb_samples = p_aout->output.i_nb_samples;
p_output_buffer->i_nb_bytes = p_aout->output.i_nb_samples p_output_buffer->i_nb_bytes = p_aout->output.i_nb_samples
* p_aout->mixer.mixer.i_bytes_per_frame * p_aout->mixer.mixer.i_bytes_per_frame
/ p_aout->mixer.mixer.i_frame_length; / p_aout->mixer.mixer.i_frame_length;
}
p_output_buffer->start_date = start_date; p_output_buffer->start_date = start_date;
p_output_buffer->end_date = end_date; p_output_buffer->end_date = end_date;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ext-dec.c: services to the decoders * input_ext-dec.c: services to the decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2001 VideoLAN * Copyright (C) 1998-2001 VideoLAN
* $Id: input_ext-dec.c,v 1.33 2002/07/24 15:21:47 sam Exp $ * $Id: input_ext-dec.c,v 1.34 2002/08/26 23:00:23 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -429,7 +429,32 @@ void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts, ...@@ -429,7 +429,32 @@ void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
{ {
/* Check if the current PTS is already valid (ie. if the first byte /* Check if the current PTS is already valid (ie. if the first byte
* of the packet has already been used in the decoder). */ * of the packet has already been used in the decoder). */
ptrdiff_t p_diff = p_bit_stream->p_byte - p_bit_stream->p_pts_validity; ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte;
if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
|| (p_diff * 8) >= p_bit_stream->fifo.i_available
/* We have buffered less bytes than actually read */ )
{
*pi_pts = p_bit_stream->i_pts;
if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
p_bit_stream->i_pts = 0;
p_bit_stream->i_dts = 0;
}
else
{
*pi_pts = 0;
if( pi_dts != NULL) *pi_dts = 0;
}
}
/*****************************************************************************
* NextPTS: returns the PTS and DTS for the next starting byte
*****************************************************************************/
void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
mtime_t * pi_dts )
{
/* Check if the current PTS is already valid (ie. if the first byte
* of the packet has already been used in the decoder). */
ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte - 1;
if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */ if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
|| (p_diff * 8) >= p_bit_stream->fifo.i_available || (p_diff * 8) >= p_bit_stream->fifo.i_available
/* We have buffered less bytes than actually read */ ) /* We have buffered less bytes than actually read */ )
......
...@@ -214,6 +214,7 @@ static const char * module_error( char *psz_buffer ) ...@@ -214,6 +214,7 @@ static const char * module_error( char *psz_buffer )
(p_symbols)->UnalignedRemoveBits_inner = UnalignedRemoveBits; \ (p_symbols)->UnalignedRemoveBits_inner = UnalignedRemoveBits; \
(p_symbols)->UnalignedGetBits_inner = UnalignedGetBits; \ (p_symbols)->UnalignedGetBits_inner = UnalignedGetBits; \
(p_symbols)->CurrentPTS_inner = CurrentPTS; \ (p_symbols)->CurrentPTS_inner = CurrentPTS; \
(p_symbols)->NextPTS_inner = NextPTS; \
(p_symbols)->DecoderError_inner = DecoderError; \ (p_symbols)->DecoderError_inner = DecoderError; \
(p_symbols)->__input_SetStatus_inner = __input_SetStatus; \ (p_symbols)->__input_SetStatus_inner = __input_SetStatus; \
(p_symbols)->__input_Seek_inner = __input_Seek; \ (p_symbols)->__input_Seek_inner = __input_Seek; \
......
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