Commit cfca8bcd authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

aout: split out packet-oriented output support code

This provides aout_PacketPlay(), aout_PacketPause() and
aout_PacketFlush() helpers for legacy audio outputs. They conveniently
match the callback prototypes of pf_play, pf_pause and pf_flush
respectively.
parent cbd0c5c4
...@@ -153,14 +153,6 @@ typedef int32_t vlc_fixed_t; ...@@ -153,14 +153,6 @@ typedef int32_t vlc_fixed_t;
/* Number of samples in an A/52 frame. */ /* Number of samples in an A/52 frame. */
#define A52_FRAME_NB 1536 #define A52_FRAME_NB 1536
/** audio output buffer FIFO */
struct aout_fifo_t
{
aout_buffer_t * p_first;
aout_buffer_t ** pp_last;
date_t end_date;
};
/* FIXME to remove once aout.h is cleaned a bit more */ /* FIXME to remove once aout.h is cleaned a bit more */
#include <vlc_block.h> #include <vlc_block.h>
...@@ -176,8 +168,6 @@ struct audio_output ...@@ -176,8 +168,6 @@ struct audio_output
audio_sample_format_t format; /**< Output format (plugin can modify it audio_sample_format_t format; /**< Output format (plugin can modify it
only when succesfully probed and not afterward) */ only when succesfully probed and not afterward) */
aout_fifo_t fifo;
struct aout_sys_t *sys; /**< Output plugin private data */ struct aout_sys_t *sys; /**< Output plugin private data */
void (*pf_play)(audio_output_t *, block_t *); /**< Audio buffer callback */ void (*pf_play)(audio_output_t *, block_t *); /**< Audio buffer callback */
void (* pf_pause)( audio_output_t *, bool, mtime_t ); /**< Pause/resume void (* pf_pause)( audio_output_t *, bool, mtime_t ); /**< Pause/resume
...@@ -266,4 +256,33 @@ VLC_API int aout_ChannelsRestart( vlc_object_t *, const char *, vlc_value_t, vlc ...@@ -266,4 +256,33 @@ VLC_API int aout_ChannelsRestart( vlc_object_t *, const char *, vlc_value_t, vlc
/* */ /* */
VLC_API vout_thread_t * aout_filter_RequestVout( filter_t *, vout_thread_t *p_vout, video_format_t *p_fmt ) VLC_USED; VLC_API vout_thread_t * aout_filter_RequestVout( filter_t *, vout_thread_t *p_vout, video_format_t *p_fmt ) VLC_USED;
/** Audio output buffer FIFO */
struct aout_fifo_t
{
aout_buffer_t * p_first;
aout_buffer_t ** pp_last;
date_t end_date;
};
/* Legacy packet-oriented audio output helpers */
typedef struct
{
aout_fifo_t partial; /**< Audio blocks before packetization */
aout_fifo_t fifo; /**< Packetized audio blocks */
mtime_t pause_date; /**< Date when paused or VLC_TS_INVALID */
unsigned samples; /**< Samples per packet */
bool starving;
/* Indicates whether the audio output is currently starving, to avoid
* printing a 1,000 "output is starving" messages. */
} aout_packet_t;
VLC_API void aout_PacketInit(audio_output_t *, aout_packet_t *, unsigned);
VLC_API void aout_PacketDestroy(audio_output_t *);
VLC_API void aout_PacketPlay(audio_output_t *, block_t *);
VLC_API void aout_PacketPause(audio_output_t *, bool, mtime_t);
VLC_API void aout_PacketFlush(audio_output_t *, bool);
VLC_API block_t *aout_PacketNext(audio_output_t *, mtime_t, bool) VLC_USED;
#endif /* VLC_AOUT_H */ #endif /* VLC_AOUT_H */
...@@ -361,8 +361,8 @@ static int Open (vlc_object_t *obj) ...@@ -361,8 +361,8 @@ static int Open (vlc_object_t *obj)
} }
p_aout->pf_play = Play; p_aout->pf_play = Play;
p_aout->pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
snd_pcm_hw_params_t *p_hw; snd_pcm_hw_params_t *p_hw;
snd_pcm_sw_params_t *p_sw; snd_pcm_sw_params_t *p_sw;
...@@ -522,21 +522,16 @@ error: ...@@ -522,21 +522,16 @@ error:
return VLC_EGENERIC; return VLC_EGENERIC;
} }
static void PlayIgnore( audio_output_t *p_aout, block_t *block )
{
aout_FifoPush( &p_aout->fifo, block );
}
/***************************************************************************** /*****************************************************************************
* Play: start playback * Play: start playback
*****************************************************************************/ *****************************************************************************/
static void Play( audio_output_t *p_aout, block_t *block ) static void Play( audio_output_t *p_aout, block_t *block )
{ {
p_aout->pf_play = PlayIgnore;
/* get the playing date of the first aout buffer */ /* get the playing date of the first aout buffer */
p_aout->sys->start_date = block->i_pts; p_aout->sys->start_date = block->i_pts;
aout_FifoPush( &p_aout->fifo, block );
aout_PacketPlay( p_aout, block );
p_aout->pf_play = aout_PacketPlay;
/* wake up the audio output thread */ /* wake up the audio output thread */
sem_post( &p_aout->sys->wait ); sem_post( &p_aout->sys->wait );
......
...@@ -122,9 +122,9 @@ static int Open ( vlc_object_t *p_this ) ...@@ -122,9 +122,9 @@ static int Open ( vlc_object_t *p_this )
p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT; p_aout->format.i_physical_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
p_aout->format.i_rate = 44100; p_aout->format.i_rate = 44100;
p_aout->format.i_nb_samples = FRAME_SIZE; p_aout->format.i_nb_samples = FRAME_SIZE;
p_aout->format.pf_play = Play; p_aout->pf_play = aout_PacketPlay;
p_aout->format.pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
msg_Dbg(p_aout, "Starting AudioQueue (status = %i)", status); msg_Dbg(p_aout, "Starting AudioQueue (status = %i)", status);
status = AudioQueueStart(p_sys->audioQueue, NULL); status = AudioQueueStart(p_sys->audioQueue, NULL);
...@@ -132,14 +132,6 @@ static int Open ( vlc_object_t *p_this ) ...@@ -132,14 +132,6 @@ static int Open ( vlc_object_t *p_this )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Play: play a sound samples buffer
*****************************************************************************/
static void Play( audio_output_t * p_aout, block_t *block )
{
aout_FifoPush( &p_aout->fifo, block );
}
/***************************************************************************** /*****************************************************************************
* Close: close the audio device * Close: close the audio device
*****************************************************************************/ *****************************************************************************/
......
...@@ -187,9 +187,9 @@ static int Open( vlc_object_t * p_this ) ...@@ -187,9 +187,9 @@ static int Open( vlc_object_t * p_this )
p_sys->b_changed_mixing = false; p_sys->b_changed_mixing = false;
memset( p_sys->p_remainder_buffer, 0, sizeof(uint8_t) * BUFSIZE ); memset( p_sys->p_remainder_buffer, 0, sizeof(uint8_t) * BUFSIZE );
p_aout->pf_play = Play; p_aout->pf_play = aout_PacketPlay;
p_aout->pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
aout_FormatPrint( p_aout, "VLC is looking for:", &p_aout->format ); aout_FormatPrint( p_aout, "VLC is looking for:", &p_aout->format );
...@@ -907,15 +907,6 @@ static void Close( vlc_object_t * p_this ) ...@@ -907,15 +907,6 @@ static void Close( vlc_object_t * p_this )
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* Play: nothing to do
*****************************************************************************/
static void Play( audio_output_t * p_aout, block_t *block )
{
aout_FifoPush( &p_aout->fifo, block );
}
/***************************************************************************** /*****************************************************************************
* Probe: Check which devices the OS has, and add them to our audio-device menu * Probe: Check which devices the OS has, and add them to our audio-device menu
*****************************************************************************/ *****************************************************************************/
......
...@@ -76,8 +76,6 @@ struct aout_sys_t ...@@ -76,8 +76,6 @@ struct aout_sys_t
notification_thread_t *p_notif; /* DirectSoundThread id */ notification_thread_t *p_notif; /* DirectSoundThread id */
int b_playing; /* playing status */
int i_frame_size; /* Size in bytes of one frame */ int i_frame_size; /* Size in bytes of one frame */
int i_speaker_setup; /* Speaker setup override */ int i_speaker_setup; /* Speaker setup override */
...@@ -171,11 +169,10 @@ static int OpenAudio( vlc_object_t *p_this ) ...@@ -171,11 +169,10 @@ static int OpenAudio( vlc_object_t *p_this )
p_aout->sys->p_dsobject = NULL; p_aout->sys->p_dsobject = NULL;
p_aout->sys->p_dsbuffer = NULL; p_aout->sys->p_dsbuffer = NULL;
p_aout->sys->p_notif = NULL; p_aout->sys->p_notif = NULL;
p_aout->sys->b_playing = 0;
p_aout->pf_play = Play; p_aout->pf_play = Play;
p_aout->pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
aout_VolumeSoftInit( p_aout ); aout_VolumeSoftInit( p_aout );
/* Retrieve config values */ /* Retrieve config values */
...@@ -571,21 +568,17 @@ static void Probe( audio_output_t * p_aout ) ...@@ -571,21 +568,17 @@ static void Probe( audio_output_t * p_aout )
*****************************************************************************/ *****************************************************************************/
static void Play( audio_output_t *p_aout, block_t *p_buffer ) static void Play( audio_output_t *p_aout, block_t *p_buffer )
{ {
if( !p_aout->sys->b_playing ) /* get the playing date of the first aout buffer */
{ p_aout->sys->p_notif->start_date = p_buffer->i_pts;
p_aout->sys->b_playing = 1;
/* get the playing date of the first aout buffer */ /* fill in the first samples (zeroes) */
p_aout->sys->p_notif->start_date = p_buffer->i_pts; FillBuffer( p_aout, 0, NULL );
/* fill in the first samples */ /* wake up the audio output thread */
FillBuffer( p_aout, 0, p_buffer ); SetEvent( p_aout->sys->p_notif->event );
/* wake up the audio output thread */ aout_PacketPlay( p_aout, p_buffer );
SetEvent( p_aout->sys->p_notif->event ); p_aout->pf_play = aout_PacketPlay;
}
else
aout_FifoPush( &p_aout->fifo, p_buffer );
} }
/***************************************************************************** /*****************************************************************************
...@@ -603,7 +596,8 @@ static void CloseAudio( vlc_object_t *p_this ) ...@@ -603,7 +596,8 @@ static void CloseAudio( vlc_object_t *p_this )
{ {
vlc_atomic_set(&p_aout->sys->p_notif->abort, 1); vlc_atomic_set(&p_aout->sys->p_notif->abort, 1);
/* wake up the audio thread if needed */ /* wake up the audio thread if needed */
if( !p_sys->b_playing ) SetEvent( p_sys->p_notif->event ); if( p_aout->pf_play == Play )
SetEvent( p_sys->p_notif->event );
vlc_join( p_sys->p_notif->thread, NULL ); vlc_join( p_sys->p_notif->thread, NULL );
free( p_sys->p_notif ); free( p_sys->p_notif );
......
...@@ -133,9 +133,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -133,9 +133,9 @@ static int Open( vlc_object_t *p_this )
jack_set_process_callback( p_sys->p_jack_client, Process, p_aout ); jack_set_process_callback( p_sys->p_jack_client, Process, p_aout );
jack_set_graph_order_callback ( p_sys->p_jack_client, GraphChange, p_aout ); jack_set_graph_order_callback ( p_sys->p_jack_client, GraphChange, p_aout );
p_aout->pf_play = Play; p_aout->pf_play = aout_PacketPlay;
p_aout->pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
aout_VolumeSoftInit( p_aout ); aout_VolumeSoftInit( p_aout );
/* JACK only supports fl32 format */ /* JACK only supports fl32 format */
...@@ -331,14 +331,6 @@ static int GraphChange( void *p_arg ) ...@@ -331,14 +331,6 @@ static int GraphChange( void *p_arg )
return 0; return 0;
} }
/*****************************************************************************
* Play: nothing to do
*****************************************************************************/
static void Play( audio_output_t *p_aout, block_t *block )
{
aout_FifoPush( &p_aout->fifo, block );
}
/***************************************************************************** /*****************************************************************************
* Close: close the JACK client * Close: close the JACK client
*****************************************************************************/ *****************************************************************************/
......
...@@ -298,9 +298,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -298,9 +298,9 @@ static int Open( vlc_object_t *p_this )
free( psz_device ); free( psz_device );
p_aout->pf_play = Play; p_aout->pf_play = aout_PacketPlay;
p_aout->pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
if ( var_Type( p_aout, "audio-device" ) == 0 ) if ( var_Type( p_aout, "audio-device" ) == 0 )
{ {
...@@ -517,14 +517,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -517,14 +517,6 @@ static int Open( vlc_object_t *p_this )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Play: nothing to do
*****************************************************************************/
static void Play( audio_output_t *p_aout, block_t *block )
{
aout_FifoPush( &p_aout->fifo, block );
}
/***************************************************************************** /*****************************************************************************
* Close: close the DSP audio device * Close: close the DSP audio device
*****************************************************************************/ *****************************************************************************/
......
...@@ -182,9 +182,9 @@ static int Open( vlc_object_t * p_this ) ...@@ -182,9 +182,9 @@ static int Open( vlc_object_t * p_this )
p_sys->p_aout = p_aout; p_sys->p_aout = p_aout;
p_sys->p_stream = 0; p_sys->p_stream = 0;
p_aout->sys = p_sys; p_aout->sys = p_sys;
p_aout->pf_play = Play; p_aout->pf_play = aout_PacketPlay;
p_aout->pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
/* Retrieve output device id from config */ /* Retrieve output device id from config */
p_sys->i_device_id = var_CreateGetInteger( p_aout, "portaudio-audio-device" ); p_sys->i_device_id = var_CreateGetInteger( p_aout, "portaudio-audio-device" );
...@@ -556,14 +556,6 @@ static int PAOpenStream( audio_output_t *p_aout ) ...@@ -556,14 +556,6 @@ static int PAOpenStream( audio_output_t *p_aout )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
/*****************************************************************************
* Play: play sound
*****************************************************************************/
static void Play( audio_output_t * p_aout, block_t *block )
{
aout_FifoPush( &p_aout->fifo, block );
}
#ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN #ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN
/***************************************************************************** /*****************************************************************************
* PORTAUDIOThread: all interactions with libportaudio.a are handled * PORTAUDIOThread: all interactions with libportaudio.a are handled
......
...@@ -155,8 +155,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -155,8 +155,8 @@ static int Open( vlc_object_t *p_this )
return VLC_ENOMEM; return VLC_ENOMEM;
p_aout->pf_play = Play; p_aout->pf_play = Play;
p_aout->pf_pause = NULL; p_aout->pf_pause = aout_PacketPause;
p_aout->pf_flush = NULL; p_aout->pf_flush = aout_PacketFlush;
/* /*
initialize/update Device selection List initialize/update Device selection List
...@@ -475,8 +475,6 @@ static void Probe( audio_output_t * p_aout ) ...@@ -475,8 +475,6 @@ static void Probe( audio_output_t * p_aout )
*****************************************************************************/ *****************************************************************************/
static void Play( audio_output_t *_p_aout, block_t *block ) static void Play( audio_output_t *_p_aout, block_t *block )
{ {
aout_FifoPush( &_p_aout->fifo, block );
if( !_p_aout->sys->b_playing ) if( !_p_aout->sys->b_playing )
{ {
_p_aout->sys->b_playing = 1; _p_aout->sys->b_playing = 1;
...@@ -491,6 +489,8 @@ static void Play( audio_output_t *_p_aout, block_t *block ) ...@@ -491,6 +489,8 @@ static void Play( audio_output_t *_p_aout, block_t *block )
} else { } else {
SetEvent( _p_aout->sys->new_buffer_event ); SetEvent( _p_aout->sys->new_buffer_event );
} }
aout_PacketPlay( _p_aout, block );
} }
/***************************************************************************** /*****************************************************************************
...@@ -939,7 +939,6 @@ static void* WaveOutThread( void *data ) ...@@ -939,7 +939,6 @@ static void* WaveOutThread( void *data )
#endif #endif
// means we are too early to request a new buffer? // means we are too early to request a new buffer?
waveout_warn("waiting...") waveout_warn("waiting...")
next_date = aout_FifoFirstDate( &p_aout->fifo );
mwait( next_date - AOUT_MAX_PTS_ADVANCE/4 ); mwait( next_date - AOUT_MAX_PTS_ADVANCE/4 );
next_date = mdate(); next_date = mdate();
p_buffer = aout_OutputNextBuffer( p_aout, next_date, p_buffer = aout_OutputNextBuffer( p_aout, next_date,
......
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes. * Local prototypes.
*****************************************************************************/ *****************************************************************************/
static void Play ( audio_output_t * ); static void Play( audio_output_t *, block_t * );
/***************************************************************************** /*****************************************************************************
* OpenAudio: open a dummy audio device * OpenAudio: open a dummy audio device
...@@ -75,9 +75,9 @@ int OpenAudio ( vlc_object_t * p_this ) ...@@ -75,9 +75,9 @@ int OpenAudio ( vlc_object_t * p_this )
/***************************************************************************** /*****************************************************************************
* Play: pretend to play a sound * Play: pretend to play a sound
*****************************************************************************/ *****************************************************************************/
static void Play( audio_output_t * p_aout ) static void Play( audio_output_t *aout, block_t *block )
{ {
aout_buffer_t * p_buffer = aout_FifoPop( &p_aout->fifo ); block_Release( block );
aout_BufferFree( p_buffer ); (void) aout;
} }
...@@ -108,12 +108,7 @@ typedef struct ...@@ -108,12 +108,7 @@ typedef struct
filter_t *filters[AOUT_MAX_FILTERS]; filter_t *filters[AOUT_MAX_FILTERS];
int nb_filters; int nb_filters;
/* Indicates whether the audio output is currently starving, to avoid aout_packet_t packet;
* printing a 1,000 "output is starving" messages. */
bool b_starving;
mtime_t pause_date;
aout_fifo_t partial;
} aout_owner_t; } aout_owner_t;
typedef struct typedef struct
......
...@@ -162,10 +162,7 @@ int aout_OutputNew( audio_output_t *p_aout, ...@@ -162,10 +162,7 @@ int aout_OutputNew( audio_output_t *p_aout,
aout_FormatPrint( p_aout, "output", &p_aout->format ); aout_FormatPrint( p_aout, "output", &p_aout->format );
/* Prepare FIFO. */ /* Prepare FIFO. */
aout_FifoInit (p_aout, &p_aout->fifo, p_aout->format.i_rate); aout_PacketInit (p_aout, &owner->packet, p_aout->i_nb_samples);
aout_FifoInit (p_aout, &owner->partial, p_aout->format.i_rate);
owner->pause_date = VLC_TS_INVALID;
owner->b_starving = true;
/* Choose the mixer format. */ /* Choose the mixer format. */
owner->mixer_format = p_aout->format; owner->mixer_format = p_aout->format;
...@@ -221,36 +218,30 @@ void aout_OutputDelete( audio_output_t * p_aout ) ...@@ -221,36 +218,30 @@ void aout_OutputDelete( audio_output_t * p_aout )
aout_VolumeNoneInit( p_aout ); /* clear volume callback */ aout_VolumeNoneInit( p_aout ); /* clear volume callback */
owner->module = NULL; owner->module = NULL;
aout_FiltersDestroyPipeline (owner->filters, owner->nb_filters); aout_FiltersDestroyPipeline (owner->filters, owner->nb_filters);
aout_FifoDestroy (&p_aout->fifo); aout_PacketDestroy (p_aout);
aout_FifoDestroy (&owner->partial);
} }
static block_t *aout_OutputSlice( audio_output_t *, aout_fifo_t * );
/***************************************************************************** /*****************************************************************************
* aout_OutputPlay : play a buffer * aout_OutputPlay : play a buffer
***************************************************************************** *****************************************************************************
* This function is entered with the mixer lock. * This function is entered with the mixer lock.
*****************************************************************************/ *****************************************************************************/
void aout_OutputPlay( audio_output_t * p_aout, aout_buffer_t * p_buffer ) void aout_OutputPlay (audio_output_t *aout, block_t *block)
{ {
aout_owner_t *owner = aout_owner (p_aout); aout_owner_t *owner = aout_owner (aout);
vlc_assert_locked( &p_aout->lock ); vlc_assert_locked (&aout->lock);
aout_FiltersPlay (owner->filters, owner->nb_filters, &p_buffer); aout_FiltersPlay (owner->filters, owner->nb_filters, &block);
if( !p_buffer ) if (block == NULL)
return; return;
if( p_buffer->i_buffer == 0 ) if (block->i_buffer == 0)
{ {
block_Release( p_buffer ); block_Release (block);
return; return;
} }
aout_FifoPush (&owner->partial, p_buffer ); aout->pf_play (aout, block);
while ((p_buffer = aout_OutputSlice (p_aout, &owner->partial)) != NULL)
p_aout->pf_play (p_aout, p_buffer);
} }
/** /**
...@@ -263,22 +254,6 @@ void aout_OutputPause( audio_output_t *aout, bool pause, mtime_t date ) ...@@ -263,22 +254,6 @@ void aout_OutputPause( audio_output_t *aout, bool pause, mtime_t date )
vlc_assert_locked( &aout->lock ); vlc_assert_locked( &aout->lock );
if( aout->pf_pause != NULL ) if( aout->pf_pause != NULL )
aout->pf_pause( aout, pause, date ); aout->pf_pause( aout, pause, date );
aout_owner_t *owner = aout_owner (aout);
if (pause)
{
owner->pause_date = date;
}
else
{
assert (owner->pause_date != VLC_TS_INVALID);
mtime_t duration = date - owner->pause_date;
owner->pause_date = VLC_TS_INVALID;
aout_FifoMoveDates (&owner->partial, duration);
aout_FifoMoveDates (&aout->fifo, duration);
}
} }
/** /**
...@@ -293,10 +268,6 @@ void aout_OutputFlush( audio_output_t *aout, bool wait ) ...@@ -293,10 +268,6 @@ void aout_OutputFlush( audio_output_t *aout, bool wait )
if( aout->pf_flush != NULL ) if( aout->pf_flush != NULL )
aout->pf_flush( aout, wait ); aout->pf_flush( aout, wait );
aout_owner_t *owner = aout_owner (aout);
aout_FifoReset (&aout->fifo);
aout_FifoReset (&owner->partial);
} }
...@@ -395,15 +366,84 @@ void aout_VolumeHardSet (audio_output_t *aout, float volume, bool mute) ...@@ -395,15 +366,84 @@ void aout_VolumeHardSet (audio_output_t *aout, float volume, bool mute)
} }
/*** Buffer management ***/ /*** Packet-oriented audio output support ***/
static inline aout_packet_t *aout_packet (audio_output_t *aout)
{
aout_owner_t *owner = aout_owner (aout);
return &owner->packet;
}
void aout_PacketInit (audio_output_t *aout, aout_packet_t *p, unsigned samples)
{
assert (p == aout_packet (aout));
aout_FifoInit (aout, &p->partial, aout->format.i_rate);
aout_FifoInit (aout, &p->fifo, aout->format.i_rate);
p->pause_date = VLC_TS_INVALID;
p->samples = samples;
p->starving = true;
}
void aout_PacketDestroy (audio_output_t *aout)
{
aout_packet_t *p = aout_packet (aout);
aout_FifoDestroy (&p->partial);
aout_FifoDestroy (&p->fifo);
}
static block_t *aout_OutputSlice (audio_output_t *);
void aout_PacketPlay (audio_output_t *aout, block_t *block)
{
aout_packet_t *p = aout_packet (aout);
aout_FifoPush (&p->partial, block);
while ((block = aout_OutputSlice (aout)) != NULL)
aout_FifoPush (&p->fifo, block);
}
void aout_PacketPause (audio_output_t *aout, bool pause, mtime_t date)
{
aout_packet_t *p = aout_packet (aout);
if (pause)
{
assert (p->pause_date == VLC_TS_INVALID);
p->pause_date = date;
}
else
{
assert (p->pause_date != VLC_TS_INVALID);
mtime_t duration = date - p->pause_date;
p->pause_date = VLC_TS_INVALID;
aout_FifoMoveDates (&p->partial, duration);
aout_FifoMoveDates (&p->fifo, duration);
}
}
void aout_PacketFlush (audio_output_t *aout, bool drain)
{
aout_packet_t *p = aout_packet (aout);
aout_FifoReset (&p->partial);
aout_FifoReset (&p->fifo);
(void) drain; /* TODO */
}
/** /**
* Rearranges audio blocks in correct number of samples. * Rearranges audio blocks in correct number of samples.
* @note (FIXME) This is left here for historical reasons. It belongs in the * @note (FIXME) This is left here for historical reasons. It belongs in the
* output code. Besides, this operation should be avoided if possible. * output code. Besides, this operation should be avoided if possible.
*/ */
static block_t *aout_OutputSlice (audio_output_t *p_aout, aout_fifo_t *p_fifo) static block_t *aout_OutputSlice (audio_output_t *p_aout)
{ {
aout_packet_t *p = aout_packet (p_aout);
aout_fifo_t *p_fifo = &p->partial;
const unsigned samples = p_aout->i_nb_samples; const unsigned samples = p_aout->i_nb_samples;
/* FIXME: Remove this silly constraint. Just pass buffers as they come to /* FIXME: Remove this silly constraint. Just pass buffers as they come to
* "smart" audio outputs. */ * "smart" audio outputs. */
...@@ -412,7 +452,7 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout, aout_fifo_t *p_fifo) ...@@ -412,7 +452,7 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout, aout_fifo_t *p_fifo)
vlc_assert_locked( &p_aout->lock ); vlc_assert_locked( &p_aout->lock );
/* Retrieve the date of the next buffer. */ /* Retrieve the date of the next buffer. */
date_t exact_start_date = p_aout->fifo.end_date; date_t exact_start_date = p->fifo.end_date;
mtime_t start_date = date_Get( &exact_start_date ); mtime_t start_date = date_Get( &exact_start_date );
/* See if we have enough data to prepare a new buffer for the audio output. */ /* See if we have enough data to prepare a new buffer for the audio output. */
...@@ -483,7 +523,7 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout, aout_fifo_t *p_fifo) ...@@ -483,7 +523,7 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout, aout_fifo_t *p_fifo)
if( delta < 0 ) if( delta < 0 )
{ {
/* Is it really the best way to do it ? */ /* Is it really the best way to do it ? */
aout_FifoReset( &p_aout->fifo ); aout_FifoReset (&p->fifo);
return NULL; return NULL;
} }
if( delta > 0 ) if( delta > 0 )
...@@ -559,8 +599,8 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout, ...@@ -559,8 +599,8 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
mtime_t start_date, mtime_t start_date,
bool b_can_sleek ) bool b_can_sleek )
{ {
aout_owner_t *owner = aout_owner (p_aout); aout_packet_t *p = aout_packet (p_aout);
aout_fifo_t *p_fifo = &p_aout->fifo; aout_fifo_t *p_fifo = &p->fifo;
aout_buffer_t * p_buffer; aout_buffer_t * p_buffer;
mtime_t now = mdate(); mtime_t now = mdate();
...@@ -585,11 +625,11 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout, ...@@ -585,11 +625,11 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
* to deal with this kind of starvation. */ * to deal with this kind of starvation. */
/* Set date to 0, to allow the mixer to send a new buffer ASAP */ /* Set date to 0, to allow the mixer to send a new buffer ASAP */
aout_FifoReset( &p_aout->fifo ); aout_FifoReset( &p->fifo );
if ( !p_aout->b_starving ) if ( !p->starving )
msg_Dbg( p_aout, msg_Dbg( p_aout,
"audio output is starving (no input), playing silence" ); "audio output is starving (no input), playing silence" );
p_aout->b_starving = true; p_aout->starving = true;
#endif #endif
goto out; goto out;
} }
...@@ -600,15 +640,15 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout, ...@@ -600,15 +640,15 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
*/ */
if ( 0 > delta + p_buffer->i_length ) if ( 0 > delta + p_buffer->i_length )
{ {
if (!owner->b_starving) if (!p->starving)
msg_Dbg( p_aout, "audio output is starving (%"PRId64"), " msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
"playing silence", -delta ); "playing silence", -delta );
owner->b_starving = true; p->starving = true;
p_buffer = NULL; p_buffer = NULL;
goto out; goto out;
} }
owner->b_starving = false; p->starving = false;
p_buffer = aout_FifoPop( p_fifo ); p_buffer = aout_FifoPop( p_fifo );
if( !b_can_sleek if( !b_can_sleek
...@@ -618,7 +658,7 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout, ...@@ -618,7 +658,7 @@ aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
msg_Warn( p_aout, "output date isn't PTS date, requesting " msg_Warn( p_aout, "output date isn't PTS date, requesting "
"resampling (%"PRId64")", delta ); "resampling (%"PRId64")", delta );
aout_FifoMoveDates (&owner->partial, delta); aout_FifoMoveDates (&p->partial, delta);
aout_FifoMoveDates (p_fifo, delta); aout_FifoMoveDates (p_fifo, delta);
} }
out: out:
......
...@@ -21,6 +21,9 @@ aout_FormatPrepare ...@@ -21,6 +21,9 @@ aout_FormatPrepare
aout_FormatPrint aout_FormatPrint
aout_FormatPrintChannels aout_FormatPrintChannels
aout_OutputNextBuffer aout_OutputNextBuffer
aout_PacketPlay
aout_PacketPause
aout_PacketFlush
aout_VolumeGet aout_VolumeGet
aout_VolumeSet aout_VolumeSet
aout_VolumeUp aout_VolumeUp
......
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