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

Simplify, clean up and rename aout_OutputNextBuffer()

parent 2344ab6a
...@@ -190,8 +190,6 @@ static const uint32_t pi_vlc_chan_order_wg4[] = ...@@ -190,8 +190,6 @@ static const uint32_t pi_vlc_chan_order_wg4[] =
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
VLC_API aout_buffer_t * aout_OutputNextBuffer( audio_output_t *, mtime_t, bool ) VLC_USED;
/** /**
* This function computes the reordering needed to go from pi_chan_order_in to * This function computes the reordering needed to go from pi_chan_order_in to
* pi_chan_order_out. * pi_chan_order_out.
...@@ -275,6 +273,7 @@ VLC_API void aout_PacketPlay(audio_output_t *, block_t *); ...@@ -275,6 +273,7 @@ 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_PacketPause(audio_output_t *, bool, mtime_t);
VLC_API void aout_PacketFlush(audio_output_t *, bool); VLC_API void aout_PacketFlush(audio_output_t *, bool);
VLC_API block_t *aout_PacketNext(audio_output_t *, mtime_t, bool) VLC_USED; VLC_API block_t *aout_PacketNext(audio_output_t *, mtime_t) VLC_USED;
#endif /* VLC_AOUT_H */ #endif /* VLC_AOUT_H */
...@@ -655,8 +655,7 @@ static void ALSAFill( audio_output_t * p_aout ) ...@@ -655,8 +655,7 @@ static void ALSAFill( audio_output_t * p_aout )
next_date = mdate() + delay_us; next_date = mdate() + delay_us;
} }
block_t *p_buffer = aout_OutputNextBuffer( p_aout, next_date, block_t *p_buffer = aout_PacketNext( p_aout, next_date );
(p_aout->format.i_format == VLC_CODEC_SPDIFL) );
/* Audio output buffer shortage -> stop the fill process and wait */ /* Audio output buffer shortage -> stop the fill process and wait */
if( p_buffer == NULL ) if( p_buffer == NULL )
......
...@@ -1303,7 +1303,7 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout, ...@@ -1303,7 +1303,7 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
{ {
/* We don't have enough data yet */ /* We don't have enough data yet */
aout_buffer_t * p_buffer; aout_buffer_t * p_buffer;
p_buffer = aout_OutputNextBuffer( p_aout, current_date , false ); p_buffer = aout_PacketNext( p_aout, current_date );
if( p_buffer != NULL ) if( p_buffer != NULL )
{ {
...@@ -1370,7 +1370,7 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, ...@@ -1370,7 +1370,7 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice,
AudioConvertHostTimeToNanos( inOutputTime->mHostTime ) / 1000; AudioConvertHostTimeToNanos( inOutputTime->mHostTime ) / 1000;
//- ((mtime_t) 1000000 / p_aout->format.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere //- ((mtime_t) 1000000 / p_aout->format.i_rate * 31 ); // 31 = Latency in Frames. retrieve somewhere
p_buffer = aout_OutputNextBuffer( p_aout, current_date, true ); p_buffer = aout_PacketNext( p_aout, current_date );
#define BUFFER outOutputData->mBuffers[p_sys->i_stream_index] #define BUFFER outOutputData->mBuffers[p_sys->i_stream_index]
if( p_buffer != NULL ) if( p_buffer != NULL )
......
...@@ -1006,9 +1006,6 @@ static void* DirectSoundThread( void *data ) ...@@ -1006,9 +1006,6 @@ static void* DirectSoundThread( void *data )
mtime_t last_time; mtime_t last_time;
int canc = vlc_savecancel (); int canc = vlc_savecancel ();
/* We don't want any resampling when using S/PDIF output */
bool b_sleek = (p_aout->format.i_format == VLC_CODEC_SPDIFL);
msg_Dbg( p_aout, "DirectSoundThread ready" ); msg_Dbg( p_aout, "DirectSoundThread ready" );
/* Wait here until Play() is called */ /* Wait here until Play() is called */
...@@ -1077,9 +1074,9 @@ static void* DirectSoundThread( void *data ) ...@@ -1077,9 +1074,9 @@ static void* DirectSoundThread( void *data )
for( i = 0; i < l_free_slots; i++ ) for( i = 0; i < l_free_slots; i++ )
{ {
aout_buffer_t *p_buffer = aout_OutputNextBuffer( p_aout, aout_buffer_t *p_buffer = aout_PacketNext( p_aout,
mtime + INT64_C(1000000) * (i * i_frame_siz + l_queued) / mtime + INT64_C(1000000) * (i * i_frame_siz + l_queued) /
p_aout->format.i_rate, b_sleek ); p_aout->format.i_rate );
/* If there is no audio data available and we have some buffered /* If there is no audio data available and we have some buffered
* already, then just wait for the next time */ * already, then just wait for the next time */
......
...@@ -263,7 +263,7 @@ int Process( jack_nframes_t i_frames, void *p_arg ) ...@@ -263,7 +263,7 @@ int Process( jack_nframes_t i_frames, void *p_arg )
mtime_t play_date = mdate() + (mtime_t) ( dtime ); mtime_t play_date = mdate() + (mtime_t) ( dtime );
/* Get the next audio data buffer */ /* Get the next audio data buffer */
aout_buffer_t *p_buffer = aout_OutputNextBuffer( p_aout, play_date, false ); aout_buffer_t *p_buffer = aout_PacketNext( p_aout, play_date );
if( p_buffer != NULL ) if( p_buffer != NULL )
{ {
......
...@@ -604,8 +604,7 @@ static void* OSSThread( void *obj ) ...@@ -604,8 +604,7 @@ static void* OSSThread( void *obj )
mtime_t buffered = BufferDuration( p_aout ); mtime_t buffered = BufferDuration( p_aout );
/* Next buffer will be played at mdate() + buffered */ /* Next buffer will be played at mdate() + buffered */
p_buffer = aout_OutputNextBuffer( p_aout, mdate() + buffered, p_buffer = aout_PacketNext( p_aout, mdate() + buffered );
false );
if( p_buffer == NULL && if( p_buffer == NULL &&
buffered > ( p_aout->sys->max_buffer_duration buffered > ( p_aout->sys->max_buffer_duration
...@@ -642,7 +641,7 @@ static void* OSSThread( void *obj ) ...@@ -642,7 +641,7 @@ static void* OSSThread( void *obj )
for( ;; ) for( ;; )
{ {
canc = vlc_savecancel (); canc = vlc_savecancel ();
p_buffer = aout_OutputNextBuffer( p_aout, next_date, true ); p_buffer = aout_PacketNext( p_aout );
if ( p_buffer ) if ( p_buffer )
break; break;
vlc_restorecancel (canc); vlc_restorecancel (canc);
......
...@@ -137,7 +137,7 @@ static int paCallback( const void *inputBuffer, void *outputBuffer, ...@@ -137,7 +137,7 @@ static int paCallback( const void *inputBuffer, void *outputBuffer,
out_date = mdate() + (mtime_t) ( 1000000 * out_date = mdate() + (mtime_t) ( 1000000 *
( paDate->outputBufferDacTime - paDate->currentTime ) ); ( paDate->outputBufferDacTime - paDate->currentTime ) );
p_buffer = aout_OutputNextBuffer( p_aout, out_date, true ); p_buffer = aout_PacketNext( p_aout, out_date );
if ( p_buffer != NULL ) if ( p_buffer != NULL )
{ {
...@@ -150,12 +150,6 @@ static int paCallback( const void *inputBuffer, void *outputBuffer, ...@@ -150,12 +150,6 @@ static int paCallback( const void *inputBuffer, void *outputBuffer,
} }
vlc_memcpy( outputBuffer, p_buffer->p_buffer, vlc_memcpy( outputBuffer, p_buffer->p_buffer,
framesPerBuffer * p_sys->i_sample_size ); framesPerBuffer * p_sys->i_sample_size );
/* aout_BufferFree may be dangereous here, but then so is
* aout_OutputNextBuffer (calls aout_BufferFree internally).
* one solution would be to link the no longer useful buffers
* in a second fifo (in aout_OutputNextBuffer too) and to
* wait until we are in Play to do the actual free.
*/
aout_BufferFree( p_buffer ); aout_BufferFree( p_buffer );
} }
else else
......
...@@ -898,7 +898,7 @@ static void* WaveOutThread( void *data ) ...@@ -898,7 +898,7 @@ static void* WaveOutThread( void *data )
// than wait a short time... before grabbing first frames // than wait a short time... before grabbing first frames
mwait( p_sys->start_date - AOUT_MAX_PTS_ADVANCE/4 ); mwait( p_sys->start_date - AOUT_MAX_PTS_ADVANCE/4 );
#define waveout_warn(msg) msg_Warn( p_aout, "aout_OutputNextBuffer no buffer "\ #define waveout_warn(msg) msg_Warn( p_aout, "aout_PacketNext no buffer "\
"got next_date=%d ms, "\ "got next_date=%d ms, "\
"%d frames to play, %s",\ "%d frames to play, %s",\
(int)(next_date/(mtime_t)1000), \ (int)(next_date/(mtime_t)1000), \
...@@ -927,25 +927,19 @@ static void* WaveOutThread( void *data ) ...@@ -927,25 +927,19 @@ static void* WaveOutThread( void *data )
/* Take into account the latency */ /* Take into account the latency */
p_buffer = aout_OutputNextBuffer( p_aout, p_buffer = aout_PacketNext( p_aout, next_date );
next_date,
b_sleek );
if(!p_buffer) if(!p_buffer)
{ {
#if 0 #if 0
msg_Dbg( p_aout, "aout_OutputNextBuffer no buffer " msg_Dbg( p_aout, "aout_PacketNext no buffer got "
"got next_date=%d ms, " "next_date=%"PRId64" ms, %d frames to play",
"%d frames to play", next_date/1000, i_queued_frames);
(int)(next_date/(mtime_t)1000),
i_queued_frames);
#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...")
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_PacketNext( p_aout, next_date );
b_sleek );
} }
if( !p_buffer && i_queued_frames ) if( !p_buffer && i_queued_frames )
......
...@@ -599,74 +599,67 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout) ...@@ -599,74 +599,67 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout)
return p_buffer; return p_buffer;
} }
/***************************************************************************** /**
* aout_OutputNextBuffer : give the audio output plug-in the right buffer * Dequeues the next audio packet (a.k.a. audio fragment).
***************************************************************************** * The audio output plugin must first call aout_PacketPlay() to queue the
* If b_can_sleek is 1, the aout core functions won't try to resample * decoded audio samples. Typically, audio_output_t.pf_play is set to, or calls
* new buffers to catch up - that is we suppose that the output plug-in can * aout_PacketPlay().
* compensate it by itself. S/PDIF outputs should always set b_can_sleek = 1. * @note This function is considered legacy. Please do not use this function in
* This function is entered with no lock at all :-). * new audio output plugins.
*****************************************************************************/ * @param p_aout audio output instance
aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout, * @param start_date expected PTS of the audio packet
mtime_t start_date, */
bool b_can_sleek ) block_t *aout_PacketNext (audio_output_t *p_aout, mtime_t start_date)
{ {
aout_packet_t *p = aout_packet (p_aout); aout_packet_t *p = aout_packet (p_aout);
aout_fifo_t *p_fifo = &p->fifo; aout_fifo_t *p_fifo = &p->fifo;
aout_buffer_t *p_buffer = NULL; aout_buffer_t *p_buffer = NULL;
mtime_t now = mdate(); const bool b_can_sleek = AOUT_FMT_NON_LINEAR (&p_aout->format);
const mtime_t threshold =
b_can_sleek ? start_date : mdate () - AOUT_MAX_PTS_DELAY;
vlc_mutex_lock( &p->lock ); vlc_mutex_lock( &p->lock );
if( p->pause_date != VLC_TS_INVALID ) if( p->pause_date != VLC_TS_INVALID )
goto out; goto out; /* paused: do not dequeue buffers */
/* Drop the audio sample if the audio output is really late. for (;;)
* In the case of b_can_sleek, we don't use a resampler so we need to be
* a lot more severe. */
while( ((p_buffer = p_fifo->p_first) != NULL)
&& p_buffer->i_pts < (b_can_sleek ? start_date : now) - AOUT_MAX_PTS_DELAY )
{ {
msg_Dbg( p_aout, "audio output is too slow (%"PRId64"), " p_buffer = p_fifo->p_first;
"trashing %"PRId64"us", now - p_buffer->i_pts, if (p_buffer == NULL)
p_buffer->i_length ); goto out; /* nothing to play */
aout_BufferFree( aout_FifoPop( p_fifo ) );
}
if( p_buffer == NULL ) if (p_buffer->i_pts >= threshold)
{ break;
#if 0 /* This is bad because the audio output might just be trying to fill
* in its internal buffers. And anyway, it's up to the audio output /* Drop the audio sample if the audio output is really late.
* to deal with this kind of starvation. */ * In the case of b_can_sleek, we don't use a resampler so we need to
* be a lot more severe. */
/* Set date to 0, to allow the mixer to send a new buffer ASAP */ msg_Dbg (p_aout, "audio output is too slow (%"PRId64" us): "
aout_FifoReset( &p->fifo ); " trashing %"PRId64" us", threshold - p_buffer->i_pts,
if ( !p->starving ) p_buffer->i_length);
msg_Dbg( p_aout, block_Release (aout_FifoPop (p_fifo));
"audio output is starving (no input), playing silence" );
p_aout->starving = true;
#endif
goto out;
} }
mtime_t delta = start_date - p_buffer->i_pts; mtime_t delta = p_buffer->i_pts - start_date;
/* Here we suppose that all buffers have the same duration - this is /* This assumes that all buffers have the same duration. This is true
* generally true, and anyway if it's wrong it won't be a disaster. * since aout_PacketPlay() (aout_OutputSlice()) is used. */
*/ if (delta >= p_buffer->i_length)
if ( 0 > delta + p_buffer->i_length )
{ {
if (!p->starving) if (!p->starving)
msg_Dbg( p_aout, "audio output is starving (%"PRId64"), " {
"playing silence", -delta ); msg_Dbg (p_aout, "audio output is starving (%"PRId64"), "
p->starving = true; "playing silence", delta);
p->starving = true;
}
p_buffer = NULL; p_buffer = NULL;
goto out; goto out; /* nothing to play _yet_ */
} }
p->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
&& ( delta > AOUT_MAX_PTS_DELAY || delta < -AOUT_MAX_PTS_ADVANCE ) ) && (delta > AOUT_MAX_PTS_ADVANCE || delta < -AOUT_MAX_PTS_DELAY))
{ {
/* Try to compensate the drift by doing some resampling. */ /* Try to compensate the drift by doing some resampling. */
msg_Warn( p_aout, "output date isn't PTS date, requesting " msg_Warn( p_aout, "output date isn't PTS date, requesting "
......
...@@ -17,12 +17,12 @@ aout_filter_RequestVout ...@@ -17,12 +17,12 @@ aout_filter_RequestVout
aout_FormatPrepare aout_FormatPrepare
aout_FormatPrint aout_FormatPrint
aout_FormatPrintChannels aout_FormatPrintChannels
aout_OutputNextBuffer
aout_PacketInit aout_PacketInit
aout_PacketDestroy aout_PacketDestroy
aout_PacketPlay aout_PacketPlay
aout_PacketPause aout_PacketPause
aout_PacketFlush aout_PacketFlush
aout_PacketNext
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