* 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.
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 */
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 )
{
/* 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 )
{
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 )
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 */
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 */
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 )
{
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
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);
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 )
{
}
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
// 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), \
/* 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 )
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 == 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;
+ 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));
}
- 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 "
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