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"
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} 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} 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"
......
......@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output
*****************************************************************************
* 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>
*
......@@ -146,6 +146,9 @@ struct aout_input_t
/* Mixer information */
byte_t * p_first_byte_to_mix;
/* Is the input dead ? */
vlc_bool_t b_error;
};
/*****************************************************************************
......@@ -211,7 +214,7 @@ struct aout_instance_t
* Prototypes
*****************************************************************************/
/* 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 );
/* From filters.c : */
......
......@@ -2,7 +2,7 @@
* audio_output.h : audio output interface
*****************************************************************************
* 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>
*
......@@ -174,7 +174,7 @@ VLC_EXPORT( aout_instance_t *, __aout_NewInstance, ( vlc_object_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( 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_DateSet, ( 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
*****************************************************************************
* 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>
* Henri Fallon <henri@videolan.org>
......@@ -36,6 +36,10 @@
# include <unistd.h>
#endif
#ifdef HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "audio_output.h"
#include "aout_internal.h"
......@@ -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;
/* 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;
#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) );
p_in = p_swabbed + i - 1;
#else
byte_t p_tmp[2];
p_in = (s16 *)p_in_buf->p_buffer + i - 1;
#endif
while( i-- )
{
#ifndef HAVE_SWAB
p_tmp[0] = ((byte_t*)p_in)[1];
p_tmp[1] = ((byte_t*)p_in)[0];
*p_out = (float)*p_tmp / 32768.0;
p_tmp[0] = ((byte_t *)p_in)[1];
p_tmp[1] = ((byte_t *)p_in)[0];
*p_out = (float)*( *(s16 *)p_tmp ) / 32768.0;
#else
*p_out = (float)*p_in / 32768.0;
#endif
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_bytes = p_in_buf->i_nb_bytes * 2;
}
......@@ -2,7 +2,7 @@
* float32.c : precise float32 audio mixer implementation
*****************************************************************************
* 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>
*
......@@ -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_in = (float *)p_input->p_first_byte_to_mix;
if ( p_input->b_error ) continue;
for ( ; ; )
{
ptrdiff_t i_available_words = (
......
......@@ -2,7 +2,7 @@
* spdif.c : dummy mixer for S/PDIF output (1 input only)
*****************************************************************************
* 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>
*
......@@ -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 )
{
aout_input_t * p_input = p_aout->pp_inputs[0];
if ( p_input->b_error ) return;
aout_FifoPop( p_aout, &p_input->fifo );
}
......@@ -2,7 +2,7 @@
* trivial.c : trivial mixer plug-in (1 input, no downmixing)
*****************************************************************************
* 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>
*
......@@ -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_out = p_buffer->p_buffer;
if ( p_input->b_error ) return;
for ( ; ; )
{
ptrdiff_t i_available_bytes = (p_input->fifo.p_first->p_buffer
......
a52_SOURCES = a52.c
lpcm_SOURCES = lpcm.c
......@@ -2,7 +2,7 @@
* a52.c: A/52 basic parser
*****************************************************************************
* 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>
* Christophe Massiot <massiot@via.ecp.fr>
......@@ -43,9 +43,9 @@
#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
......@@ -56,8 +56,6 @@ typedef struct spdif_thread_s
* Input properties
*/
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;
/*
......@@ -66,7 +64,7 @@ typedef struct spdif_thread_s
aout_instance_t * p_aout; /* opaque */
aout_input_t * p_aout_input; /* opaque */
audio_sample_format_t output_format;
} spdif_thread_t;
} dec_thread_t;
/****************************************************************************
* Local prototypes
......@@ -74,8 +72,7 @@ typedef struct spdif_thread_s
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
static int InitThread ( spdif_thread_t *, decoder_fifo_t * );
static void EndThread ( spdif_thread_t * );
static void EndThread ( dec_thread_t * );
static int SyncInfo ( const byte_t *, int *, int *, int * );
......@@ -86,15 +83,10 @@ vlc_module_begin();
set_description( _("A/52 parser") );
set_capability( "decoder", 100 );
set_callbacks( OpenDecoder, NULL );
add_shortcut( "pass_through" );
add_shortcut( "pass" );
vlc_module_end();
/*****************************************************************************
* 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 )
{
......@@ -117,11 +109,11 @@ static int OpenDecoder( vlc_object_t *p_this )
****************************************************************************/
static int RunDecoder( decoder_fifo_t *p_fifo )
{
spdif_thread_t * p_dec;
dec_thread_t * p_dec;
audio_date_t end_date;
/* 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 )
{
msg_Err( p_fifo, "out of memory" );
......@@ -129,21 +121,21 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
return -1;
}
if ( InitThread( p_dec, 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;
msg_Err( p_fifo, "could not initialize thread" );
DecoderError( p_fifo );
free( p_dec );
return -1;
}
/* Init the bitstream */
InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
NULL, NULL );
/* decoder thread's main loop */
while ( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
{
int i_frame_size, i_channels, i_rate, i_bit_rate;
mtime_t pts;
/* Temporary buffer to store the raw frame to be decoded */
byte_t p_header[7];
aout_buffer_t * p_buffer;
......@@ -248,28 +240,10 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
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
*****************************************************************************/
static void EndThread( spdif_thread_t * p_dec )
static void EndThread( dec_thread_t * p_dec )
{
if ( p_dec->p_aout_input != NULL )
{
......
......@@ -2,7 +2,7 @@
* lpcm.c: lpcm decoder module
*****************************************************************************
* 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>
* Henri Fallon <henri@videolan.org>
......@@ -37,22 +37,49 @@
# include <unistd.h> /* getpid() */
#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
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
void DecodeFrame ( lpcmdec_thread_t * );
// static int InitThread ( lpcmdec_thread_t * );
static void EndThread ( lpcmdec_thread_t * );
void DecodeFrame ( dec_thread_t * );
// static int InitThread ( dec_thread_t * );
static void EndThread ( dec_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("linear PCM audio decoder") );
set_description( _("linear PCM audio parser") );
set_capability( "decoder", 100 );
set_callbacks( OpenDecoder, NULL );
vlc_module_end();
......@@ -79,133 +106,118 @@ static int OpenDecoder( vlc_object_t *p_this )
*****************************************************************************/
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 */
if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) )
== NULL)
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
return( -1 );
return -1;
}
/*
* Initialize the thread properties
*/
p_lpcmdec->p_fifo = p_fifo;
/* Initialize the thread properties */
p_dec->p_fifo = p_fifo;
/* Init the BitStream */
InitBitstream( &p_lpcmdec->bit_stream, p_lpcmdec->p_fifo,
/* Init the bitstream */
InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
NULL, NULL );
/* FIXME : I suppose the number of channel ans sampling rate
* are someway in the headers */
p_lpcmdec->output_format.i_format = AOUT_FMT_S16_BE;
p_lpcmdec->output_format.i_channels = 2;
p_lpcmdec->output_format.i_rate = 48000;
/* FIXME : I suppose the number of channel and sampling rate
* are somewhere in the headers */
p_dec->output_format.i_format = AOUT_FMT_S16_BE;
p_dec->output_format.i_channels = 2;
p_dec->output_format.i_rate = 48000;
aout_DateInit( &p_lpcmdec->end_date, 48000 );
p_lpcmdec->p_aout_input = aout_InputNew( p_lpcmdec->p_fifo,
&p_lpcmdec->p_aout,
&p_lpcmdec->output_format );
aout_DateInit( &p_dec->end_date, 48000 );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_dec->p_aout,
&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" );
p_lpcmdec->p_fifo->b_error = 1;
msg_Err( p_dec->p_fifo, "failed to create aout fifo" );
p_dec->p_fifo->b_error = 1;
return( -1 );
}
/* 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 (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 */
EndThread (p_lpcmdec);
EndThread( p_dec );
return( 0 );
return 0;
}
/*****************************************************************************
* 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;
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_lpcmdec->p_aout_input,
LPCMDEC_FRAME_SIZE/4 );
p_aout_buffer = aout_BufferNew( p_dec->p_aout,
p_dec->p_aout_input,
LPCM_FRAME_NB );
if( !p_aout_buffer )
{
msg_Err( p_lpcmdec->p_fifo, "cannot get aout buffer" );
p_lpcmdec->p_fifo->b_error = 1;
msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
p_dec->p_fifo->b_error = 1;
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,
LPCM_FRAME_NB );
p_aout_buffer->end_date = aout_DateIncrement( &p_lpcmdec->end_date,
LPCMDEC_FRAME_SIZE/4 );
b_sync = 0;
while( ( !p_lpcmdec->p_fifo->b_die ) &&
( !p_lpcmdec->p_fifo->b_error ) &&
( !b_sync ) )
{
while( ( !p_lpcmdec->p_fifo->b_die ) &&
( !p_lpcmdec->p_fifo->b_error ) &&
( GetBits( &p_lpcmdec->bit_stream, 8 ) != 0x01 ) );
b_sync = ( ShowBits( &p_lpcmdec->bit_stream, 8 ) == 0x80 );
}
/* Look for sync word - should be 0x0180 */
RealignBits( &p_dec->bit_stream );
while ( (GetBits( &p_dec->bit_stream, 16 ) ) != 0x0180 &&
(!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error));
RemoveBits( &p_lpcmdec->bit_stream, 8 );
GetChunk( &p_dec->bit_stream, p_aout_buffer->p_buffer,
LPCM_FRAME_NB * 4);
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;
}
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 );
}
/*****************************************************************************
* 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_lpcmdec->p_aout_input )
if( p_dec->p_aout_input != NULL )
{
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_lpcmdec );
free( p_dec );
}
/*****************************************************************************
* 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,
*p_samples++ = *p_right++;
}
break;
case 1:
p_dec->p_fifo->p_vlc->pf_memcpy( p_samples, p_left,
i_samples * sizeof(mad_fixed_t) );
break;
default:
msg_Err( p_dec->p_fifo, "cannot interleave %i channels",
p_pcm->channels );
......
......@@ -2,7 +2,7 @@
* audio_output.c : audio output instance miscellaneous functions
*****************************************************************************
* 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>
*
......@@ -125,7 +125,7 @@ void aout_BufferDelete( aout_instance_t * p_aout, aout_input_t * p_input,
/*****************************************************************************
* 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 )
{
if ( p_buffer->start_date == 0 )
......@@ -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. */
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. */
aout_MixerRun( p_aout );
......
......@@ -2,7 +2,7 @@
* input.c : internal management of input streams for the audio output
*****************************************************************************
* 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>
*
......@@ -81,6 +81,7 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
aout_MixerDelete( p_aout );
}
p_input->b_error = 0;
memcpy( &p_input->input, p_format,
sizeof(audio_sample_format_t) );
aout_FormatPrepare( &p_input->input );
......@@ -95,9 +96,6 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
if ( aout_MixerNew( p_aout ) < 0 )
{
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 )
{
......@@ -107,6 +105,8 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
{
aout_MixerNew( p_aout );
}
aout_FifoDestroy( p_aout, &p_input->fifo );
vlc_mutex_unlock( &p_input->lock );
vlc_mutex_destroy( &p_input->lock );
free( p_input );
......@@ -124,17 +124,24 @@ static aout_input_t * InputNew( aout_instance_t * p_aout,
{
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_destroy( &p_input->lock );
free( p_input );
vlc_mutex_unlock( &p_aout->mixer_lock );
if ( !p_aout->i_nb_inputs )
{
aout_OutputDelete( p_aout );
}
return NULL;
}
......@@ -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 );
}
/*****************************************************************************
* 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
*****************************************************************************/
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 )
{
mtime_t start_date, duration;
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
* this. We'll deal with that when pushing the buffer, and compensate
* with the next incoming buffer. */
......@@ -272,7 +328,7 @@ void aout_InputPlay( aout_instance_t * p_aout, aout_input_t * p_input,
aout_BufferFree( p_buffer );
vlc_mutex_unlock( &p_input->lock );
return;
return 0;
}
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,
aout_BufferFree( p_buffer );
vlc_mutex_unlock( &p_input->lock );
return;
return 0;
}
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,
p_buffer->end_date = start_date + duration;
aout_FifoPush( p_aout, &p_input->fifo, p_buffer );
vlc_mutex_unlock( &p_aout->input_fifos_lock );
return 0;
}
......@@ -2,7 +2,7 @@
* mixer.c : audio output mixing operations
*****************************************************************************
* 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>
*
......@@ -106,6 +106,8 @@ static int MixBuffer( aout_instance_t * p_aout )
aout_fifo_t * p_fifo = &p_input->fifo;
aout_buffer_t * p_buffer;
if ( p_input->b_error ) continue;
p_buffer = p_fifo->p_first;
if ( p_buffer == NULL )
{
......@@ -140,6 +142,8 @@ static int MixBuffer( aout_instance_t * p_aout )
mtime_t prev_date;
vlc_bool_t b_drop_buffers;
if ( p_input->b_error ) continue;
p_buffer = p_fifo->p_first;
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