mirror of
https://code.videolan.org/videolan/vlc
synced 2024-09-08 11:26:59 +02:00
Simplify, clean up and rename aout_OutputNextBuffer()
This commit is contained in:
parent
2344ab6ae1
commit
97521497e5
@ -190,8 +190,6 @@ static const uint32_t pi_vlc_chan_order_wg4[] =
|
||||
* 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
|
||||
* pi_chan_order_out.
|
||||
@ -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_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 */
|
||||
|
@ -655,8 +655,7 @@ static void ALSAFill( audio_output_t * p_aout )
|
||||
next_date = mdate() + delay_us;
|
||||
}
|
||||
|
||||
block_t *p_buffer = aout_OutputNextBuffer( p_aout, next_date,
|
||||
(p_aout->format.i_format == VLC_CODEC_SPDIFL) );
|
||||
block_t *p_buffer = aout_PacketNext( p_aout, next_date );
|
||||
|
||||
/* Audio output buffer shortage -> stop the fill process and wait */
|
||||
if( p_buffer == NULL )
|
||||
|
@ -1303,7 +1303,7 @@ static OSStatus RenderCallbackAnalog( vlc_object_t *_p_aout,
|
||||
{
|
||||
/* We don't have enough data yet */
|
||||
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 )
|
||||
{
|
||||
@ -1370,7 +1370,7 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice,
|
||||
AudioConvertHostTimeToNanos( inOutputTime->mHostTime ) / 1000;
|
||||
//- ((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]
|
||||
if( p_buffer != NULL )
|
||||
|
@ -1006,9 +1006,6 @@ static void* DirectSoundThread( void *data )
|
||||
mtime_t last_time;
|
||||
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" );
|
||||
|
||||
/* Wait here until Play() is called */
|
||||
@ -1077,9 +1074,9 @@ static void* DirectSoundThread( void *data )
|
||||
|
||||
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) /
|
||||
p_aout->format.i_rate, b_sleek );
|
||||
p_aout->format.i_rate );
|
||||
|
||||
/* If there is no audio data available and we have some buffered
|
||||
* already, then just wait for the next time */
|
||||
|
@ -263,7 +263,7 @@ int Process( jack_nframes_t i_frames, void *p_arg )
|
||||
mtime_t play_date = mdate() + (mtime_t) ( dtime );
|
||||
|
||||
/* 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 )
|
||||
{
|
||||
|
@ -604,8 +604,7 @@ static void* OSSThread( void *obj )
|
||||
mtime_t buffered = BufferDuration( p_aout );
|
||||
|
||||
/* Next buffer will be played at mdate() + buffered */
|
||||
p_buffer = aout_OutputNextBuffer( p_aout, mdate() + buffered,
|
||||
false );
|
||||
p_buffer = aout_PacketNext( p_aout, mdate() + buffered );
|
||||
|
||||
if( p_buffer == NULL &&
|
||||
buffered > ( p_aout->sys->max_buffer_duration
|
||||
@ -642,7 +641,7 @@ static void* OSSThread( void *obj )
|
||||
for( ;; )
|
||||
{
|
||||
canc = vlc_savecancel ();
|
||||
p_buffer = aout_OutputNextBuffer( p_aout, next_date, true );
|
||||
p_buffer = aout_PacketNext( p_aout );
|
||||
if ( p_buffer )
|
||||
break;
|
||||
vlc_restorecancel (canc);
|
||||
|
@ -137,7 +137,7 @@ static int paCallback( const void *inputBuffer, void *outputBuffer,
|
||||
|
||||
out_date = mdate() + (mtime_t) ( 1000000 *
|
||||
( 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 )
|
||||
{
|
||||
@ -150,12 +150,6 @@ static int paCallback( const void *inputBuffer, void *outputBuffer,
|
||||
}
|
||||
vlc_memcpy( outputBuffer, p_buffer->p_buffer,
|
||||
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 );
|
||||
}
|
||||
else
|
||||
|
@ -898,7 +898,7 @@ static void* WaveOutThread( void *data )
|
||||
// than wait a short time... before grabbing first frames
|
||||
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, "\
|
||||
"%d frames to play, %s",\
|
||||
(int)(next_date/(mtime_t)1000), \
|
||||
@ -927,25 +927,19 @@ static void* WaveOutThread( void *data )
|
||||
|
||||
|
||||
/* Take into account the latency */
|
||||
p_buffer = aout_OutputNextBuffer( p_aout,
|
||||
next_date,
|
||||
b_sleek );
|
||||
|
||||
p_buffer = aout_PacketNext( p_aout, next_date );
|
||||
if(!p_buffer)
|
||||
{
|
||||
#if 0
|
||||
msg_Dbg( p_aout, "aout_OutputNextBuffer no buffer "
|
||||
"got next_date=%d ms, "
|
||||
"%d frames to play",
|
||||
(int)(next_date/(mtime_t)1000),
|
||||
i_queued_frames);
|
||||
msg_Dbg( p_aout, "aout_PacketNext no buffer got "
|
||||
"next_date=%"PRId64" ms, %d frames to play",
|
||||
next_date/1000, i_queued_frames);
|
||||
#endif
|
||||
// means we are too early to request a new buffer?
|
||||
waveout_warn("waiting...")
|
||||
mwait( next_date - AOUT_MAX_PTS_ADVANCE/4 );
|
||||
next_date = mdate();
|
||||
p_buffer = aout_OutputNextBuffer( p_aout, next_date,
|
||||
b_sleek );
|
||||
p_buffer = aout_PacketNext( p_aout, next_date );
|
||||
}
|
||||
|
||||
if( !p_buffer && i_queued_frames )
|
||||
|
@ -599,74 +599,67 @@ static block_t *aout_OutputSlice (audio_output_t *p_aout)
|
||||
return p_buffer;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* aout_OutputNextBuffer : give the audio output plug-in the right buffer
|
||||
*****************************************************************************
|
||||
* If b_can_sleek is 1, the aout core functions won't try to resample
|
||||
* new buffers to catch up - that is we suppose that the output plug-in can
|
||||
* compensate it by itself. S/PDIF outputs should always set b_can_sleek = 1.
|
||||
* This function is entered with no lock at all :-).
|
||||
*****************************************************************************/
|
||||
aout_buffer_t * aout_OutputNextBuffer( audio_output_t * p_aout,
|
||||
mtime_t start_date,
|
||||
bool b_can_sleek )
|
||||
/**
|
||||
* Dequeues the next audio packet (a.k.a. audio fragment).
|
||||
* The audio output plugin must first call aout_PacketPlay() to queue the
|
||||
* decoded audio samples. Typically, audio_output_t.pf_play is set to, or calls
|
||||
* aout_PacketPlay().
|
||||
* @note This function is considered legacy. Please do not use this function in
|
||||
* new audio output plugins.
|
||||
* @param p_aout audio output instance
|
||||
* @param start_date expected PTS of the audio packet
|
||||
*/
|
||||
block_t *aout_PacketNext (audio_output_t *p_aout, mtime_t start_date)
|
||||
{
|
||||
aout_packet_t *p = aout_packet (p_aout);
|
||||
aout_fifo_t *p_fifo = &p->fifo;
|
||||
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 );
|
||||
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.
|
||||
* 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 )
|
||||
for (;;)
|
||||
{
|
||||
msg_Dbg( p_aout, "audio output is too slow (%"PRId64"), "
|
||||
"trashing %"PRId64"us", now - p_buffer->i_pts,
|
||||
p_buffer->i_length );
|
||||
aout_BufferFree( aout_FifoPop( p_fifo ) );
|
||||
p_buffer = p_fifo->p_first;
|
||||
if (p_buffer == NULL)
|
||||
goto out; /* nothing to play */
|
||||
|
||||
if (p_buffer->i_pts >= threshold)
|
||||
break;
|
||||
|
||||
/* Drop the audio sample if the audio output is really late.
|
||||
* In the case of b_can_sleek, we don't use a resampler so we need to
|
||||
* be a lot more severe. */
|
||||
msg_Dbg (p_aout, "audio output is too slow (%"PRId64" us): "
|
||||
" trashing %"PRId64" us", threshold - p_buffer->i_pts,
|
||||
p_buffer->i_length);
|
||||
block_Release (aout_FifoPop (p_fifo));
|
||||
}
|
||||
|
||||
if( p_buffer == NULL )
|
||||
{
|
||||
#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
|
||||
* to deal with this kind of starvation. */
|
||||
|
||||
/* Set date to 0, to allow the mixer to send a new buffer ASAP */
|
||||
aout_FifoReset( &p->fifo );
|
||||
if ( !p->starving )
|
||||
msg_Dbg( p_aout,
|
||||
"audio output is starving (no input), playing silence" );
|
||||
p_aout->starving = true;
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
|
||||
mtime_t delta = start_date - p_buffer->i_pts;
|
||||
/* Here we suppose that all buffers have the same duration - this is
|
||||
* generally true, and anyway if it's wrong it won't be a disaster.
|
||||
*/
|
||||
if ( 0 > delta + p_buffer->i_length )
|
||||
mtime_t delta = p_buffer->i_pts - start_date;
|
||||
/* This assumes that all buffers have the same duration. This is true
|
||||
* since aout_PacketPlay() (aout_OutputSlice()) is used. */
|
||||
if (delta >= p_buffer->i_length)
|
||||
{
|
||||
if (!p->starving)
|
||||
msg_Dbg( p_aout, "audio output is starving (%"PRId64"), "
|
||||
"playing silence", -delta );
|
||||
p->starving = true;
|
||||
{
|
||||
msg_Dbg (p_aout, "audio output is starving (%"PRId64"), "
|
||||
"playing silence", delta);
|
||||
p->starving = true;
|
||||
}
|
||||
p_buffer = NULL;
|
||||
goto out;
|
||||
goto out; /* nothing to play _yet_ */
|
||||
}
|
||||
|
||||
p->starving = false;
|
||||
p_buffer = aout_FifoPop( p_fifo );
|
||||
|
||||
if( !b_can_sleek
|
||||
&& ( delta > AOUT_MAX_PTS_DELAY || delta < -AOUT_MAX_PTS_ADVANCE ) )
|
||||
if (!b_can_sleek
|
||||
&& (delta > AOUT_MAX_PTS_ADVANCE || delta < -AOUT_MAX_PTS_DELAY))
|
||||
{
|
||||
/* Try to compensate the drift by doing some resampling. */
|
||||
msg_Warn( p_aout, "output date isn't PTS date, requesting "
|
||||
|
@ -17,12 +17,12 @@ aout_filter_RequestVout
|
||||
aout_FormatPrepare
|
||||
aout_FormatPrint
|
||||
aout_FormatPrintChannels
|
||||
aout_OutputNextBuffer
|
||||
aout_PacketInit
|
||||
aout_PacketDestroy
|
||||
aout_PacketPlay
|
||||
aout_PacketPause
|
||||
aout_PacketFlush
|
||||
aout_PacketNext
|
||||
aout_VolumeGet
|
||||
aout_VolumeSet
|
||||
aout_VolumeUp
|
||||
|
Loading…
Reference in New Issue
Block a user