Commit d198a803 authored by Christophe Massiot's avatar Christophe Massiot

* Fixed miscellaneous cosmetic issues with lpcm and s16tofloat32swab modules.

* First hooks for changing the audio output plug-in and its parameters
  on-the-fly.
parent 81442b6b
...@@ -447,7 +447,7 @@ PLUGINS="${PLUGINS} misc/dummy/dummy misc/null" ...@@ -447,7 +447,7 @@ PLUGINS="${PLUGINS} misc/dummy/dummy misc/null"
PLUGINS="${PLUGINS} control/rc/rc misc/logger/logger access/file misc/memcpy/memcpy" PLUGINS="${PLUGINS} control/rc/rc misc/logger/logger access/file misc/memcpy/memcpy"
PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/mpeg_system demux/mpeg/ps demux/mpeg/ts demux/a52sys" PLUGINS="${PLUGINS} demux/mpeg/es demux/mpeg/audio demux/mpeg/mpeg_system demux/mpeg/ps demux/mpeg/ts demux/a52sys"
PLUGINS="${PLUGINS} codec/mpeg_video/idct/idct codec/mpeg_video/idct/idctclassic codec/mpeg_video/motion/motion codec/mpeg_video/mpeg_video codec/spudec/spudec codec/mpeg_audio/mpeg_audio" PLUGINS="${PLUGINS} codec/mpeg_video/idct/idct codec/mpeg_video/idct/idctclassic codec/mpeg_video/motion/motion codec/mpeg_video/mpeg_video codec/spudec/spudec codec/mpeg_audio/mpeg_audio"
PLUGINS="${PLUGINS} codec/a52old/imdct/imdct codec/a52old/downmix/downmix codec/a52old/a52old codec/a52 codec/lpcm/lpcm" PLUGINS="${PLUGINS} codec/a52old/imdct/imdct codec/a52old/downmix/downmix codec/a52old/a52old codec/a52 codec/lpcm"
PLUGINS="${PLUGINS} video_filter/deinterlace/deinterlace video_filter/invert video_filter/wall video_filter/transform video_filter/distort video_filter/clone video_filter/crop video_filter/motionblur" PLUGINS="${PLUGINS} video_filter/deinterlace/deinterlace video_filter/invert video_filter/wall video_filter/transform video_filter/distort video_filter/clone video_filter/crop video_filter/motionblur"
PLUGINS="${PLUGINS} audio_filter/converter/float32tos16 audio_filter/converter/float32tos8 audio_filter/converter/float32tou16 audio_filter/converter/float32tou8 audio_filter/converter/a52tospdif audio_filter/converter/fixed32tofloat32 audio_filter/converter/fixed32tos16 audio_filter/converter/s16tofloat32 audio_filter/converter/s16tofloat32swab" PLUGINS="${PLUGINS} audio_filter/converter/float32tos16 audio_filter/converter/float32tos8 audio_filter/converter/float32tou16 audio_filter/converter/float32tou8 audio_filter/converter/a52tospdif audio_filter/converter/fixed32tofloat32 audio_filter/converter/fixed32tos16 audio_filter/converter/s16tofloat32 audio_filter/converter/s16tofloat32swab"
PLUGINS="${PLUGINS} audio_filter/resampler/trivial audio_filter/resampler/ugly" PLUGINS="${PLUGINS} audio_filter/resampler/trivial audio_filter/resampler/ugly"
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output * aout_internal.h : internal defines for audio output
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: aout_internal.h,v 1.19 2002/09/19 21:56:39 massiot Exp $ * $Id: aout_internal.h,v 1.20 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -146,6 +146,9 @@ struct aout_input_t ...@@ -146,6 +146,9 @@ struct aout_input_t
/* Mixer information */ /* Mixer information */
byte_t * p_first_byte_to_mix; byte_t * p_first_byte_to_mix;
/* Is the input dead ? */
vlc_bool_t b_error;
}; };
/***************************************************************************** /*****************************************************************************
...@@ -211,8 +214,8 @@ struct aout_instance_t ...@@ -211,8 +214,8 @@ struct aout_instance_t
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
/* From input.c : */ /* From input.c : */
void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer ); aout_buffer_t * p_buffer );
/* From filters.c : */ /* From filters.c : */
int aout_FiltersCreatePipeline( aout_instance_t * p_aout, int aout_FiltersCreatePipeline( aout_instance_t * p_aout,
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_output.h : audio output interface * audio_output.h : audio output interface
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: audio_output.h,v 1.65 2002/09/19 21:56:39 massiot Exp $ * $Id: audio_output.h,v 1.66 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -174,7 +174,7 @@ VLC_EXPORT( aout_instance_t *, __aout_NewInstance, ( vlc_object_t * ) ); ...@@ -174,7 +174,7 @@ VLC_EXPORT( aout_instance_t *, __aout_NewInstance, ( vlc_object_t * ) );
VLC_EXPORT( void, aout_DeleteInstance, ( aout_instance_t * ) ); VLC_EXPORT( void, aout_DeleteInstance, ( aout_instance_t * ) );
VLC_EXPORT( aout_buffer_t *, aout_BufferNew, ( aout_instance_t *, aout_input_t *, size_t ) ); VLC_EXPORT( aout_buffer_t *, aout_BufferNew, ( aout_instance_t *, aout_input_t *, size_t ) );
VLC_EXPORT( void, aout_BufferDelete, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ); VLC_EXPORT( void, aout_BufferDelete, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
VLC_EXPORT( void, aout_BufferPlay, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) ); VLC_EXPORT( int, aout_BufferPlay, ( aout_instance_t *, aout_input_t *, aout_buffer_t * ) );
VLC_EXPORT( void, aout_DateInit, ( audio_date_t *, u32 ) ); VLC_EXPORT( void, aout_DateInit, ( audio_date_t *, u32 ) );
VLC_EXPORT( void, aout_DateSet, ( audio_date_t *, mtime_t ) ); VLC_EXPORT( void, aout_DateSet, ( audio_date_t *, mtime_t ) );
VLC_EXPORT( void, aout_DateMove, ( audio_date_t *, mtime_t ) ); VLC_EXPORT( void, aout_DateMove, ( audio_date_t *, mtime_t ) );
......
/***************************************************************************** /*****************************************************************************
* s16tofloat32.c : converter from signed 16 bits integer to float32 * s16tofloat32swab.c : converter from signed 16 bits integer to float32
* with endianness change * with endianness change
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: s16tofloat32swab.c,v 1.2 2002/09/18 12:20:37 sam Exp $ * $Id: s16tofloat32swab.c,v 1.3 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org> * Henri Fallon <henri@videolan.org>
...@@ -36,6 +36,10 @@ ...@@ -36,6 +36,10 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "audio_output.h" #include "audio_output.h"
#include "aout_internal.h" #include "aout_internal.h"
...@@ -94,34 +98,31 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter, ...@@ -94,34 +98,31 @@ static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
int i = p_in_buf->i_nb_samples * p_filter->input.i_channels; int i = p_in_buf->i_nb_samples * p_filter->input.i_channels;
/* We start from the end because b_in_place is true */ /* We start from the end because b_in_place is true */
s16 * p_in = (s16 *)p_in_buf->p_buffer + i - 1; s16 * p_in;
float * p_out = (float *)p_out_buf->p_buffer + i - 1; float * p_out = (float *)p_out_buf->p_buffer + i - 1;
#ifdef HAVE_SWAB #ifdef HAVE_SWAB
s16 * p_swabbed = malloc( i * sizeof(s16) ); s16 * p_swabbed = alloca( i * sizeof(s16) );
swab( p_in_buf->p_buffer, p_swabbed, i * sizeof(s16) ); swab( p_in_buf->p_buffer, p_swabbed, i * sizeof(s16) );
p_in = p_swabbed + i - 1; p_in = p_swabbed + i - 1;
#else #else
byte_t p_tmp[2]; byte_t p_tmp[2];
p_in = (s16 *)p_in_buf->p_buffer + i - 1;
#endif #endif
while( i-- ) while( i-- )
{ {
#ifndef HAVE_SWAB #ifndef HAVE_SWAB
p_tmp[0] = ((byte_t*)p_in)[1]; p_tmp[0] = ((byte_t *)p_in)[1];
p_tmp[1] = ((byte_t*)p_in)[0]; p_tmp[1] = ((byte_t *)p_in)[0];
*p_out = (float)*p_tmp / 32768.0; *p_out = (float)*( *(s16 *)p_tmp ) / 32768.0;
#else #else
*p_out = (float)*p_in / 32768.0; *p_out = (float)*p_in / 32768.0;
#endif #endif
p_in--; p_out--; p_in--; p_out--;
} }
#ifdef HAVE_SWAB
free( p_swabbed );
#endif
p_out_buf->i_nb_samples = p_in_buf->i_nb_samples; p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * 2; p_out_buf->i_nb_bytes = p_in_buf->i_nb_bytes * 2;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* float32.c : precise float32 audio mixer implementation * float32.c : precise float32 audio mixer implementation
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: float32.c,v 1.3 2002/09/19 21:56:39 massiot Exp $ * $Id: float32.c,v 1.4 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -121,6 +121,8 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) ...@@ -121,6 +121,8 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
float * p_out = (float *)p_buffer->p_buffer; float * p_out = (float *)p_buffer->p_buffer;
float * p_in = (float *)p_input->p_first_byte_to_mix; float * p_in = (float *)p_input->p_first_byte_to_mix;
if ( p_input->b_error ) continue;
for ( ; ; ) for ( ; ; )
{ {
ptrdiff_t i_available_words = ( ptrdiff_t i_available_words = (
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* spdif.c : dummy mixer for S/PDIF output (1 input only) * spdif.c : dummy mixer for S/PDIF output (1 input only)
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: spdif.c,v 1.5 2002/08/21 22:41:59 massiot Exp $ * $Id: spdif.c,v 1.6 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -74,6 +74,7 @@ static int Create( vlc_object_t *p_this ) ...@@ -74,6 +74,7 @@ static int Create( vlc_object_t *p_this )
static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
{ {
aout_input_t * p_input = p_aout->pp_inputs[0]; aout_input_t * p_input = p_aout->pp_inputs[0];
if ( p_input->b_error ) return;
aout_FifoPop( p_aout, &p_input->fifo ); aout_FifoPop( p_aout, &p_input->fifo );
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* trivial.c : trivial mixer plug-in (1 input, no downmixing) * trivial.c : trivial mixer plug-in (1 input, no downmixing)
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: trivial.c,v 1.6 2002/08/21 22:41:59 massiot Exp $ * $Id: trivial.c,v 1.7 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -77,6 +77,8 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer ) ...@@ -77,6 +77,8 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
byte_t * p_in = p_input->p_first_byte_to_mix; byte_t * p_in = p_input->p_first_byte_to_mix;
byte_t * p_out = p_buffer->p_buffer; byte_t * p_out = p_buffer->p_buffer;
if ( p_input->b_error ) return;
for ( ; ; ) for ( ; ; )
{ {
ptrdiff_t i_available_bytes = (p_input->fifo.p_first->p_buffer ptrdiff_t i_available_bytes = (p_input->fifo.p_first->p_buffer
......
a52_SOURCES = a52.c a52_SOURCES = a52.c
lpcm_SOURCES = lpcm.c
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* a52.c: A/52 basic parser * a52.c: A/52 basic parser
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2002 VideoLAN * Copyright (C) 2001-2002 VideoLAN
* $Id: a52.c,v 1.11 2002/09/16 20:46:38 massiot Exp $ * $Id: a52.c,v 1.12 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Stphane Borel <stef@via.ecp.fr> * Authors: Stphane Borel <stef@via.ecp.fr>
* Christophe Massiot <massiot@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr>
...@@ -43,9 +43,9 @@ ...@@ -43,9 +43,9 @@
#define A52_FRAME_NB 1536 #define A52_FRAME_NB 1536
/***************************************************************************** /*****************************************************************************
* spdif_thread_t : A52 pass-through thread descriptor * dec_thread_t : A52 pass-through thread descriptor
*****************************************************************************/ *****************************************************************************/
typedef struct spdif_thread_s typedef struct dec_thread_t
{ {
/* /*
* Thread properties * Thread properties
...@@ -56,8 +56,6 @@ typedef struct spdif_thread_s ...@@ -56,8 +56,6 @@ typedef struct spdif_thread_s
* Input properties * Input properties
*/ */
decoder_fifo_t * p_fifo; /* stores the PES stream data */ decoder_fifo_t * p_fifo; /* stores the PES stream data */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream; bit_stream_t bit_stream;
/* /*
...@@ -66,7 +64,7 @@ typedef struct spdif_thread_s ...@@ -66,7 +64,7 @@ typedef struct spdif_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;
} spdif_thread_t; } dec_thread_t;
/**************************************************************************** /****************************************************************************
* Local prototypes * Local prototypes
...@@ -74,8 +72,7 @@ typedef struct spdif_thread_s ...@@ -74,8 +72,7 @@ typedef struct spdif_thread_s
static int OpenDecoder ( vlc_object_t * ); static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * ); static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( spdif_thread_t *, decoder_fifo_t * ); static void EndThread ( dec_thread_t * );
static void EndThread ( spdif_thread_t * );
static int SyncInfo ( const byte_t *, int *, int *, int * ); static int SyncInfo ( const byte_t *, int *, int *, int * );
...@@ -86,15 +83,10 @@ vlc_module_begin(); ...@@ -86,15 +83,10 @@ vlc_module_begin();
set_description( _("A/52 parser") ); set_description( _("A/52 parser") );
set_capability( "decoder", 100 ); set_capability( "decoder", 100 );
set_callbacks( OpenDecoder, NULL ); set_callbacks( OpenDecoder, NULL );
add_shortcut( "pass_through" );
add_shortcut( "pass" );
vlc_module_end(); vlc_module_end();
/***************************************************************************** /*****************************************************************************
* OpenDecoder: probe the decoder and return score * OpenDecoder: probe the decoder and return score
*****************************************************************************
* Tries to launch a decoder and return score so that the interface is able
* to chose.
*****************************************************************************/ *****************************************************************************/
static int OpenDecoder( vlc_object_t *p_this ) static int OpenDecoder( vlc_object_t *p_this )
{ {
...@@ -117,11 +109,11 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -117,11 +109,11 @@ 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; dec_thread_t * p_dec;
audio_date_t end_date; 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(dec_thread_t) );
if( p_dec == NULL ) if( p_dec == NULL )
{ {
msg_Err( p_fifo, "out of memory" ); msg_Err( p_fifo, "out of memory" );
...@@ -129,21 +121,21 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -129,21 +121,21 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
return -1; return -1;
} }
if ( InitThread( p_dec, p_fifo ) ) /* Initialize the thread properties */
{ p_dec->p_aout = NULL;
p_dec->p_aout_input = NULL;
msg_Err( p_fifo, "could not initialize thread" ); p_dec->p_fifo = p_fifo;
DecoderError( p_fifo ); p_dec->output_format.i_format = AOUT_FMT_A52;
free( p_dec );
return -1; /* Init the bitstream */
} InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
NULL, NULL );
/* decoder thread's main loop */ /* decoder thread's main loop */
while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error ) while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
{ {
int i_frame_size, i_channels, i_rate, i_bit_rate; int i_frame_size, i_channels, i_rate, i_bit_rate;
mtime_t pts; mtime_t pts;
/* Temporary buffer to store the raw frame to be decoded */
byte_t p_header[7]; byte_t p_header[7];
aout_buffer_t * p_buffer; aout_buffer_t * p_buffer;
...@@ -248,28 +240,10 @@ static int RunDecoder( decoder_fifo_t *p_fifo ) ...@@ -248,28 +240,10 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
return 0; return 0;
} }
/****************************************************************************
* InitThread: initialize thread data and create output fifo
****************************************************************************/
static int InitThread( spdif_thread_t * p_dec, decoder_fifo_t * p_fifo )
{
/* Initialize the thread properties */
p_dec->p_aout = NULL;
p_dec->p_aout_input = NULL;
p_dec->p_fifo = p_fifo;
p_dec->output_format.i_format = AOUT_FMT_A52;
/* Init the Bitstream */
InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
NULL, NULL );
return 0;
}
/***************************************************************************** /*****************************************************************************
* EndThread : spdif thread destruction * EndThread : spdif thread destruction
*****************************************************************************/ *****************************************************************************/
static void EndThread( spdif_thread_t * p_dec ) static void EndThread( dec_thread_t * p_dec )
{ {
if ( p_dec->p_aout_input != NULL ) if ( p_dec->p_aout_input != NULL )
{ {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* lpcm.c: lpcm decoder module * lpcm.c: lpcm decoder module
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * Copyright (C) 1999-2001 VideoLAN
* $Id: lpcm.c,v 1.4 2002/09/18 01:28:05 henri Exp $ * $Id: lpcm.c,v 1.1 2002/09/20 23:27:03 massiot Exp $
* *
* Authors: Samuel Hocevar <sam@zoy.org> * Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org> * Henri Fallon <henri@videolan.org>
...@@ -37,22 +37,49 @@ ...@@ -37,22 +37,49 @@
# include <unistd.h> /* getpid() */ # include <unistd.h> /* getpid() */
#endif #endif
#include "lpcm.h" #define LPCM_FRAME_NB 502
/*****************************************************************************
* dec_thread_t : lpcm decoder thread descriptor
*****************************************************************************/
typedef struct dec_thread_t
{
/*
* Thread properties
*/
vlc_thread_t thread_id; /* id for thread functions */
/*
* Input properties
*/
decoder_fifo_t * p_fifo; /* stores the PES stream data */
bit_stream_t bit_stream;
int sync_ptr; /* sync ptr from lpcm magic header */
/*
* Output properties
*/
aout_instance_t *p_aout;
aout_input_t *p_aout_input;
audio_sample_format_t output_format;
audio_date_t end_date;
} dec_thread_t;
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int OpenDecoder ( vlc_object_t * ); static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * ); static int RunDecoder ( decoder_fifo_t * );
void DecodeFrame ( lpcmdec_thread_t * ); void DecodeFrame ( dec_thread_t * );
// static int InitThread ( lpcmdec_thread_t * ); // static int InitThread ( dec_thread_t * );
static void EndThread ( lpcmdec_thread_t * ); static void EndThread ( dec_thread_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
vlc_module_begin(); vlc_module_begin();
set_description( _("linear PCM audio decoder") ); set_description( _("linear PCM audio parser") );
set_capability( "decoder", 100 ); set_capability( "decoder", 100 );
set_callbacks( OpenDecoder, NULL ); set_callbacks( OpenDecoder, NULL );
vlc_module_end(); vlc_module_end();
...@@ -79,133 +106,118 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -79,133 +106,118 @@ static int OpenDecoder( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static int RunDecoder( decoder_fifo_t * p_fifo ) static int RunDecoder( decoder_fifo_t * p_fifo )
{ {
lpcmdec_thread_t * p_lpcmdec; dec_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_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) ) if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) )
== NULL) == NULL)
{ {
msg_Err( p_fifo, "out of memory" ); msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo ); DecoderError( p_fifo );
return( -1 ); return -1;
} }
/* /* Initialize the thread properties */
* Initialize the thread properties p_dec->p_fifo = p_fifo;
*/
p_lpcmdec->p_fifo = p_fifo;
/* Init the BitStream */ /* Init the bitstream */
InitBitstream( &p_lpcmdec->bit_stream, p_lpcmdec->p_fifo, InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
NULL, NULL ); NULL, NULL );
/* FIXME : I suppose the number of channel ans sampling rate /* FIXME : I suppose the number of channel and sampling rate
* are someway in the headers */ * are somewhere in the headers */
p_lpcmdec->output_format.i_format = AOUT_FMT_S16_BE; p_dec->output_format.i_format = AOUT_FMT_S16_BE;
p_lpcmdec->output_format.i_channels = 2; p_dec->output_format.i_channels = 2;
p_lpcmdec->output_format.i_rate = 48000; p_dec->output_format.i_rate = 48000;
aout_DateInit( &p_lpcmdec->end_date, 48000 ); aout_DateInit( &p_dec->end_date, 48000 );
p_lpcmdec->p_aout_input = aout_InputNew( p_lpcmdec->p_fifo, p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_lpcmdec->p_aout, &p_dec->p_aout,
&p_lpcmdec->output_format ); &p_dec->output_format );
if( p_lpcmdec->p_aout_input == NULL ) if ( p_dec->p_aout_input == NULL )
{ {
msg_Err( p_lpcmdec->p_fifo, "failed to create aout fifo" ); msg_Err( p_dec->p_fifo, "failed to create aout fifo" );
p_lpcmdec->p_fifo->b_error = 1; p_dec->p_fifo->b_error = 1;
return( -1 ); return( -1 );
} }
/* lpcm decoder thread's main loop */ /* lpcm decoder thread's main loop */
while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error)) while ( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
{ {
DecodeFrame(p_lpcmdec); DecodeFrame(p_dec);
} }
/* If b_error is set, the lpcm decoder thread enters the error loop */ /* If b_error is set, the lpcm decoder thread enters the error loop */
if (p_lpcmdec->p_fifo->b_error) if ( p_dec->p_fifo->b_error )
{ {
DecoderError( p_lpcmdec->p_fifo ); DecoderError( p_dec->p_fifo );
} }
/* End of the lpcm decoder thread */ /* End of the lpcm decoder thread */
EndThread (p_lpcmdec); EndThread( p_dec );
return( 0 ); return 0;
} }
/***************************************************************************** /*****************************************************************************
* DecodeFrame: decodes a frame. * DecodeFrame: decodes a frame.
*****************************************************************************/ *****************************************************************************/
void DecodeFrame( lpcmdec_thread_t * p_lpcmdec ) void DecodeFrame( dec_thread_t * p_dec )
{ {
byte_t buffer[LPCMDEC_FRAME_SIZE];
aout_buffer_t * p_aout_buffer; aout_buffer_t * p_aout_buffer;
mtime_t i_pts; mtime_t i_pts;
vlc_bool_t b_sync;
int i_loop;
NextPTS( &p_lpcmdec->bit_stream, &i_pts, NULL ); NextPTS( &p_dec->bit_stream, &i_pts, NULL );
if( i_pts != 0 && i_pts != aout_DateGet( &p_lpcmdec->end_date ) ) if( i_pts != 0 && i_pts != aout_DateGet( &p_dec->end_date ) )
{ {
aout_DateSet( &p_lpcmdec->end_date, i_pts ); aout_DateSet( &p_dec->end_date, i_pts );
} }
p_aout_buffer = aout_BufferNew( p_lpcmdec->p_aout, p_aout_buffer = aout_BufferNew( p_dec->p_aout,
p_lpcmdec->p_aout_input, p_dec->p_aout_input,
LPCMDEC_FRAME_SIZE/4 ); LPCM_FRAME_NB );
if( !p_aout_buffer ) if( !p_aout_buffer )
{ {
msg_Err( p_lpcmdec->p_fifo, "cannot get aout buffer" ); msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
p_lpcmdec->p_fifo->b_error = 1; p_dec->p_fifo->b_error = 1;
return; return;
} }
p_aout_buffer->start_date = aout_DateGet( &p_lpcmdec->end_date ); p_aout_buffer->start_date = aout_DateGet( &p_dec->end_date );
p_aout_buffer->end_date = aout_DateIncrement( &p_dec->end_date,
p_aout_buffer->end_date = aout_DateIncrement( &p_lpcmdec->end_date, LPCM_FRAME_NB );
LPCMDEC_FRAME_SIZE/4 );
b_sync = 0; /* Look for sync word - should be 0x0180 */
while( ( !p_lpcmdec->p_fifo->b_die ) && RealignBits( &p_dec->bit_stream );
( !p_lpcmdec->p_fifo->b_error ) && while ( (GetBits( &p_dec->bit_stream, 16 ) ) != 0x0180 &&
( !b_sync ) ) (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error));
{
while( ( !p_lpcmdec->p_fifo->b_die ) && GetChunk( &p_dec->bit_stream, p_aout_buffer->p_buffer,
( !p_lpcmdec->p_fifo->b_error ) && LPCM_FRAME_NB * 4);
( GetBits( &p_lpcmdec->bit_stream, 8 ) != 0x01 ) );
b_sync = ( ShowBits( &p_lpcmdec->bit_stream, 8 ) == 0x80 );
}
RemoveBits( &p_lpcmdec->bit_stream, 8 );
GetChunk( &p_lpcmdec->bit_stream, p_aout_buffer->p_buffer,
LPCMDEC_FRAME_SIZE);
if( p_lpcmdec->p_fifo->b_die || p_lpcmdec->p_fifo->b_error ) if( p_dec->p_fifo->b_die )
{
aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer );
return; return;
}
aout_BufferPlay( p_lpcmdec->p_aout, p_lpcmdec->p_aout_input, aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer ); p_aout_buffer );
} }
/***************************************************************************** /*****************************************************************************
* EndThread : lpcm decoder thread destruction * EndThread : lpcm decoder thread destruction
*****************************************************************************/ *****************************************************************************/
static void EndThread( lpcmdec_thread_t * p_lpcmdec ) static void EndThread( dec_thread_t * p_dec )
{ {
/* If the audio output fifo was created, we destroy it */ if( p_dec->p_aout_input != NULL )
if( p_lpcmdec->p_aout_input )
{ {
aout_InputDelete( p_lpcmdec->p_aout, p_lpcmdec->p_aout_input ); aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
} }
/* Destroy descriptor */ free( p_dec );
free( p_lpcmdec );
} }
/*****************************************************************************
* lpcm.h : lpcm decoder module
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: lpcm.h,v 1.2 2002/09/18 01:28:05 henri Exp $
*
* Authors: Samuel Hocevar <sam@zoy.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-1307, USA.
*****************************************************************************/
#define LPCMDEC_FRAME_SIZE (2008)
/*****************************************************************************
* lpcmdec_thread_t : lpcm decoder thread descriptor
*****************************************************************************/
typedef struct lpcmdec_thread_s
{
/*
* Thread properties
*/
vlc_thread_t thread_id; /* id for thread functions */
/*
* Input properties
*/
decoder_fifo_t * p_fifo; /* stores the PES stream data */
int sync_ptr; /* sync ptr from lpcm magic header */
/*
* Output properties
*/
aout_instance_t *p_aout;
aout_input_t *p_aout_input;
audio_sample_format_t output_format;
audio_date_t end_date;
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
} lpcmdec_thread_t;
/*****************************************************************************
* Prototypes
*****************************************************************************/
vlc_thread_t lpcmdec_CreateThread( decoder_fifo_t * p_fifo );
...@@ -222,9 +222,12 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header, ...@@ -222,9 +222,12 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
*p_samples++ = *p_right++; *p_samples++ = *p_right++;
} }
break; break;
case 1: case 1:
p_dec->p_fifo->p_vlc->pf_memcpy( p_samples, p_left, p_dec->p_fifo->p_vlc->pf_memcpy( p_samples, p_left,
i_samples * sizeof(mad_fixed_t) ); i_samples * sizeof(mad_fixed_t) );
break;
default: default:
msg_Err( p_dec->p_fifo, "cannot interleave %i channels", msg_Err( p_dec->p_fifo, "cannot interleave %i channels",
p_pcm->channels ); p_pcm->channels );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_output.c : audio output instance miscellaneous functions * audio_output.c : audio output instance miscellaneous functions
***************************************************************************** *****************************************************************************
* Copyright (C) 2002 VideoLAN * Copyright (C) 2002 VideoLAN
* $Id: audio_output.c,v 1.102 2002/09/16 20:46:38 massiot Exp $ * $Id: audio_output.c,v 1.103 2002/09/20 23:27:04 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -125,8 +125,8 @@ void aout_BufferDelete( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -125,8 +125,8 @@ void aout_BufferDelete( aout_instance_t * p_aout, aout_input_t * p_input,
/***************************************************************************** /*****************************************************************************
* aout_BufferPlay : filter & mix the decoded buffer * aout_BufferPlay : filter & mix the decoded buffer
*****************************************************************************/ *****************************************************************************/
void aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input, int aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer ) aout_buffer_t * p_buffer )
{ {
if ( p_buffer->start_date == 0 ) if ( p_buffer->start_date == 0 )
{ {
...@@ -143,7 +143,7 @@ void aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -143,7 +143,7 @@ void aout_BufferPlay( aout_instance_t * p_aout, aout_input_t * p_input,
/* If the buffer is too early, wait a while. */ /* If the buffer is too early, wait a while. */
mwait( p_buffer->start_date - AOUT_MAX_PREPARE_TIME ); mwait( p_buffer->start_date - AOUT_MAX_PREPARE_TIME );
aout_InputPlay( p_aout, p_input, p_buffer ); if ( aout_InputPlay( p_aout, p_input, p_buffer ) == -1 ) return -1;
/* Run the mixer if it is able to run. */ /* Run the mixer if it is able to run. */
aout_MixerRun( p_aout ); aout_MixerRun( p_aout );
......
...@@ -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.11 2002/08/30 22:22:24 massiot Exp $ * $Id: input.c,v 1.12 2002/09/20 23:27:04 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -81,6 +81,7 @@ static aout_input_t * InputNew( aout_instance_t * p_aout, ...@@ -81,6 +81,7 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
aout_MixerDelete( p_aout ); aout_MixerDelete( p_aout );
} }
p_input->b_error = 0;
memcpy( &p_input->input, p_format, memcpy( &p_input->input, p_format,
sizeof(audio_sample_format_t) ); sizeof(audio_sample_format_t) );
aout_FormatPrepare( &p_input->input ); aout_FormatPrepare( &p_input->input );
...@@ -95,9 +96,6 @@ static aout_input_t * InputNew( aout_instance_t * p_aout, ...@@ -95,9 +96,6 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
if ( aout_MixerNew( p_aout ) < 0 ) if ( aout_MixerNew( p_aout ) < 0 )
{ {
p_aout->i_nb_inputs--; p_aout->i_nb_inputs--;
aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters,
p_input->i_nb_filters );
aout_FifoDestroy( p_aout, &p_input->fifo );
if ( !p_aout->i_nb_inputs ) if ( !p_aout->i_nb_inputs )
{ {
...@@ -107,6 +105,8 @@ static aout_input_t * InputNew( aout_instance_t * p_aout, ...@@ -107,6 +105,8 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
{ {
aout_MixerNew( p_aout ); aout_MixerNew( p_aout );
} }
aout_FifoDestroy( p_aout, &p_input->fifo );
vlc_mutex_unlock( &p_input->lock ); vlc_mutex_unlock( &p_input->lock );
vlc_mutex_destroy( &p_input->lock ); vlc_mutex_destroy( &p_input->lock );
free( p_input ); free( p_input );
...@@ -124,17 +124,24 @@ static aout_input_t * InputNew( aout_instance_t * p_aout, ...@@ -124,17 +124,24 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
{ {
msg_Err( p_aout, "couldn't set an input pipeline" ); msg_Err( p_aout, "couldn't set an input pipeline" );
aout_FifoDestroy( p_aout, &p_input->fifo ); p_aout->i_nb_inputs--;
aout_MixerDelete( p_aout );
if ( !p_aout->i_nb_inputs )
{
aout_OutputDelete( p_aout );
}
else
{
aout_MixerNew( p_aout );
}
aout_FifoDestroy( p_aout, &p_input->fifo );
vlc_mutex_unlock( &p_input->lock ); vlc_mutex_unlock( &p_input->lock );
vlc_mutex_destroy( &p_input->lock ); vlc_mutex_destroy( &p_input->lock );
free( p_input ); free( p_input );
vlc_mutex_unlock( &p_aout->mixer_lock ); vlc_mutex_unlock( &p_aout->mixer_lock );
if ( !p_aout->i_nb_inputs )
{
aout_OutputDelete( p_aout );
}
return NULL; return NULL;
} }
...@@ -235,16 +242,65 @@ void aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input ) ...@@ -235,16 +242,65 @@ void aout_InputDelete( aout_instance_t * p_aout, aout_input_t * p_input )
msg_Dbg( p_aout, "input 0x%x destroyed", p_input ); msg_Dbg( p_aout, "input 0x%x destroyed", p_input );
} }
/*****************************************************************************
* aout_InputChange : recreate the pipeline framework, in case the output
* device has changed
*****************************************************************************
* You must own p_input->lock and the mixer lock before entering this function.
* It returns -1 if the input pipeline couldn't be created. Please remember
* to call aout_MixerNew() afterwards.
*****************************************************************************/
int aout_InputChange( aout_instance_t * p_aout, aout_input_t * p_input )
{
aout_FiltersDestroyPipeline( p_aout, p_input->pp_filters,
p_input->i_nb_filters );
aout_FifoDestroy( p_aout, &p_input->fifo );
aout_FifoInit( p_aout, &p_input->fifo, p_aout->mixer.mixer.i_rate );
p_input->p_first_byte_to_mix = NULL;
/* Create filters. */
if ( aout_FiltersCreatePipeline( p_aout, p_input->pp_filters,
&p_input->i_nb_filters, &p_input->input,
&p_aout->mixer.mixer ) < 0 )
{
p_input->b_error = 1;
return -1;
}
/* Prepare hints for the buffer allocator. */
p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
p_input->input_alloc.i_bytes_per_sec = -1;
aout_FiltersHintBuffers( p_aout, p_input->pp_filters,
p_input->i_nb_filters,
&p_input->input_alloc );
/* i_bytes_per_sec is still == -1 if no filters */
p_input->input_alloc.i_bytes_per_sec = __MAX(
p_input->input_alloc.i_bytes_per_sec,
p_input->input.i_bytes_per_frame
* p_input->input.i_rate
/ p_input->input.i_frame_length );
/* Allocate in the heap, it is more convenient for the decoder. */
p_input->input_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
return 0;
}
/***************************************************************************** /*****************************************************************************
* aout_InputPlay : play a buffer * aout_InputPlay : play a buffer
*****************************************************************************/ *****************************************************************************/
void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, int aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_buffer_t * p_buffer ) aout_buffer_t * p_buffer )
{ {
mtime_t start_date, duration; mtime_t start_date, duration;
vlc_mutex_lock( &p_input->lock ); vlc_mutex_lock( &p_input->lock );
if ( p_input->b_error ) return -1;
/* We don't care if someone changes the start date behind our back after /* We don't care if someone changes the start date behind our back after
* this. We'll deal with that when pushing the buffer, and compensate * this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */ * with the next incoming buffer. */
...@@ -272,7 +328,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -272,7 +328,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_BufferFree( p_buffer ); aout_BufferFree( p_buffer );
vlc_mutex_unlock( &p_input->lock ); vlc_mutex_unlock( &p_input->lock );
return; return 0;
} }
if ( start_date == 0 ) start_date = p_buffer->start_date; if ( start_date == 0 ) start_date = p_buffer->start_date;
...@@ -326,7 +382,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -326,7 +382,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_BufferFree( p_buffer ); aout_BufferFree( p_buffer );
vlc_mutex_unlock( &p_input->lock ); vlc_mutex_unlock( &p_input->lock );
return; return 0;
} }
dummy_alloc.i_alloc_type = AOUT_ALLOC_HEAP; dummy_alloc.i_alloc_type = AOUT_ALLOC_HEAP;
...@@ -372,4 +428,6 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input, ...@@ -372,4 +428,6 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
p_buffer->end_date = start_date + duration; p_buffer->end_date = start_date + duration;
aout_FifoPush( p_aout, &p_input->fifo, p_buffer ); aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
vlc_mutex_unlock( &p_aout->input_fifos_lock ); vlc_mutex_unlock( &p_aout->input_fifos_lock );
return 0;
} }
...@@ -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.13 2002/09/19 21:56:40 massiot Exp $ * $Id: mixer.c,v 1.14 2002/09/20 23:27:04 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -106,6 +106,8 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -106,6 +106,8 @@ static int MixBuffer( aout_instance_t * p_aout )
aout_fifo_t * p_fifo = &p_input->fifo; aout_fifo_t * p_fifo = &p_input->fifo;
aout_buffer_t * p_buffer; aout_buffer_t * p_buffer;
if ( p_input->b_error ) continue;
p_buffer = p_fifo->p_first; p_buffer = p_fifo->p_first;
if ( p_buffer == NULL ) if ( p_buffer == NULL )
{ {
...@@ -140,6 +142,8 @@ static int MixBuffer( aout_instance_t * p_aout ) ...@@ -140,6 +142,8 @@ static int MixBuffer( aout_instance_t * p_aout )
mtime_t prev_date; mtime_t prev_date;
vlc_bool_t b_drop_buffers; vlc_bool_t b_drop_buffers;
if ( p_input->b_error ) continue;
p_buffer = p_fifo->p_first; p_buffer = p_fifo->p_first;
if ( p_buffer == NULL ) if ( p_buffer == NULL )
{ {
......
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