[vlc-devel] [WIP/PATCH] Audio decoder: output buffered decoded frames on EOF
Rafaël Carré
funman at videolan.org
Wed Oct 16 19:42:18 CEST 2013
If EOF happens during buffering, the buffered frames will be flushed
and never played back.
This should only be visible for very short files such as:
http://streams.videolan.org/issues/9195/73ms-VLC-KO.wav
Note, pulse will lose the audio for such short files, alsa and afile work better
---
TODO: verify that the core decoder changes do not affect video / subs
I will be happy to test with very short videos/subs if you have such files
Also, the amount of buffered data can be controlled with --foo-caching
src/input/decoder.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/src/input/decoder.c b/src/input/decoder.c
index b7e2ff9..e3a5896 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -63,7 +63,7 @@ static void DecoderProcess( decoder_t *, block_t * );
static void DecoderError( decoder_t *p_dec, block_t *p_block );
static void DecoderOutputChangePause( decoder_t *, bool b_paused, mtime_t i_date );
static void DecoderFlush( decoder_t * );
-static void DecoderSignalBuffering( decoder_t *, bool );
+static void DecoderSignalBuffering( decoder_t * );
static void DecoderFlushBuffering( decoder_t * );
static void DecoderUnsupportedCodec( decoder_t *, vlc_fourcc_t );
@@ -422,6 +422,9 @@ bool input_DecoderIsEmpty( decoder_t * p_dec )
assert( !p_owner->b_buffering );
bool b_empty = block_FifoCount( p_dec->p_owner->p_fifo ) <= 0;
+ if (p_owner->buffer.i_count) /* buffered frames */
+ b_empty = false;
+
if( b_empty )
{
vlc_mutex_lock( &p_owner->lock );
@@ -923,7 +926,11 @@ static void *DecoderThread( void *p_data )
/* Make sure there is no cancellation point other than this one^^.
* If you need one, be sure to push cleanup of p_block. */
- DecoderSignalBuffering( p_dec, p_block == NULL );
+ if (p_block == NULL || p_block->i_flags & BLOCK_FLAG_CORE_EOS) {
+ /* Stop buffering if we're at end of stream */
+ DecoderSignalBuffering( p_dec );
+ input_DecoderStopBuffering( p_dec );
+ }
if( p_block )
{
@@ -986,7 +993,7 @@ static void DecoderFlush( decoder_t *p_dec )
vlc_cond_wait( &p_owner->wait_acknowledge, &p_owner->lock );
}
-static void DecoderSignalBuffering( decoder_t *p_dec, bool b_full )
+static void DecoderSignalBuffering( decoder_t *p_dec )
{
decoder_owner_sys_t *p_owner = p_dec->p_owner;
@@ -994,8 +1001,7 @@ static void DecoderSignalBuffering( decoder_t *p_dec, bool b_full )
if( p_owner->b_buffering )
{
- if( b_full )
- p_owner->buffer.b_full = true;
+ p_owner->buffer.b_full = true;
vlc_cond_signal( &p_owner->wait_acknowledge );
}
@@ -1164,7 +1170,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
audio_output_t *p_aout = p_owner->p_aout;
/* */
- if( p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
+ if( p_audio && p_audio->i_pts <= VLC_TS_INVALID ) // FIXME --VLC_TS_INVALID verify audio_output/*
{
msg_Warn( p_dec, "non-dated audio buffer received" );
*pi_lost_sum += 1;
@@ -1175,7 +1181,7 @@ static void DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
/* */
vlc_mutex_lock( &p_owner->lock );
- if( p_owner->b_buffering || p_owner->buffer.p_audio )
+ if( p_audio && (p_owner->b_buffering || p_owner->buffer.p_audio) )
{
p_audio->p_next = NULL;
@@ -1263,7 +1269,11 @@ static void DecoderDecodeAudio( decoder_t *p_dec, block_t *p_block )
int i_lost = 0;
int i_played = 0;
- while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
+ if (!p_block) {
+ /* Play a NULL block to output buffered frames */
+ DecoderPlayAudio( p_dec, NULL, &i_played, &i_lost );
+ }
+ else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )
{
if( DecoderIsExitRequested( p_dec ) )
{
@@ -1889,7 +1899,7 @@ static void DecoderProcessAudio( decoder_t *p_dec, block_t *p_block, bool b_flus
DecoderDecodeAudio( p_dec, p_null );
}
}
- else if( p_block )
+ else
{
DecoderDecodeAudio( p_dec, p_block );
}
@@ -2411,7 +2421,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
return NULL;
/* */
- DecoderSignalBuffering( p_dec, true );
+ DecoderSignalBuffering( p_dec );
/* Check the decoder doesn't leak pictures */
vout_FixLeaks( p_owner->p_vout );
--
1.8.3.2
More information about the vlc-devel
mailing list