[vlc-commits] [Git][videolan/vlc][master] 4 commits: decoder: add vlc_input_decoder_IsDrained()
Steve Lhomme (@robUx4)
gitlab at videolan.org
Thu Nov 27 08:46:44 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
ef85344c by Thomas Guillem at 2025-11-27T07:52:11+00:00
decoder: add vlc_input_decoder_IsDrained()
Polling is still ugly, but I don't think it's wise to change this
behavior in vout and aout for now.
- - - - -
5eb0c9c4 by Thomas Guillem at 2025-11-27T07:52:11+00:00
decoder: move draining check
No functional changes as IsDrained() is only used by IsEmpty()
internally.
- - - - -
bd68f989 by Thomas Guillem at 2025-11-27T07:52:11+00:00
es_out: use vlc_input_decoder_IsDrained() when applicable
- - - - -
82db8c43 by Thomas Guillem at 2025-11-27T07:52:11+00:00
es_out: don't flush decoders if drained
As the doc says:
"The instance must have been drained using vlc_input_decoder_Drain() or
flushed using vlc_input_decoder_Flush() after any previous call to
vlc_input_decoder_Decode() before calling the destructor."
This will allow not flushing outputs when doing gapless transition.
Fixes #28463
- - - - -
5 changed files:
- include/vlc_decoder.h
- src/input/decoder.c
- src/input/es_out.c
- src/input/test/es_out.c
- src/libvlccore.sym
Changes:
=====================================
include/vlc_decoder.h
=====================================
@@ -85,6 +85,15 @@ VLC_API void vlc_input_decoder_Decode( vlc_input_decoder_t *p_dec, struct vlc_fr
*/
VLC_API void vlc_input_decoder_Drain( vlc_input_decoder_t * );
+/**
+ * Returns the drained state
+ *
+ * @warning This function need to be polled (every few ms) to know when the
+ * decoder is drained
+ * @return true if drained (after a call to vlc_input_decoder_Drain())
+ */
+ VLC_API bool vlc_input_decoder_IsDrained( vlc_input_decoder_t * );
+
/**
* Requests that the decoder immediately discard all pending buffers.
* This is useful when seeking or when deselecting a stream.
=====================================
src/input/decoder.c
=====================================
@@ -2486,27 +2486,41 @@ void vlc_input_decoder_Decode(vlc_input_decoder_t *p_owner, vlc_frame_t *frame,
vlc_input_decoder_DecodeWithStatus(p_owner, frame, b_do_pace, NULL);
}
+static bool vlc_input_decoder_IsDrainedLocked(vlc_input_decoder_t *owner)
+{
+ vlc_fifo_Assert(owner->p_fifo);
+
+ if (owner->p_sout_input != NULL)
+ return true;
+ else if (owner->fmt.i_cat == VIDEO_ES && owner->video.vout != NULL)
+ return vout_IsEmpty(owner->video.vout);
+ else if(owner->fmt.i_cat == AUDIO_ES && owner->audio.stream != NULL)
+ return vlc_aout_stream_IsDrained( owner->audio.stream);
+ else
+ return true; /* TODO subtitles support */
+}
+
+bool vlc_input_decoder_IsDrained(vlc_input_decoder_t *owner)
+{
+ vlc_fifo_Lock(owner->p_fifo);
+ bool drained = !owner->b_draining && vlc_input_decoder_IsDrainedLocked(owner);
+ vlc_fifo_Unlock(owner->p_fifo);
+ return drained;
+}
+
bool vlc_input_decoder_IsEmpty( vlc_input_decoder_t * p_owner )
{
assert( !p_owner->b_waiting );
vlc_fifo_Lock( p_owner->p_fifo );
- if( !vlc_fifo_IsEmpty( p_owner->p_fifo ) || p_owner->b_draining )
+ if( !vlc_fifo_IsEmpty( p_owner->p_fifo ) )
{
vlc_fifo_Unlock( p_owner->p_fifo );
return false;
}
- bool b_empty;
+ bool b_empty = vlc_input_decoder_IsDrainedLocked( p_owner );
- if( p_owner->p_sout_input != NULL )
- b_empty = true;
- else if( p_owner->fmt.i_cat == VIDEO_ES && p_owner->video.vout != NULL )
- b_empty = vout_IsEmpty( p_owner->video.vout );
- else if( p_owner->fmt.i_cat == AUDIO_ES && p_owner->audio.stream != NULL )
- b_empty = vlc_aout_stream_IsDrained( p_owner->audio.stream );
- else
- b_empty = true; /* TODO subtitles support */
vlc_fifo_Unlock( p_owner->p_fifo );
return b_empty;
=====================================
src/input/es_out.c
=====================================
@@ -663,7 +663,8 @@ static void EsOutTerminate(es_out_sys_t *p_sys)
{
if (es->p_dec != NULL)
{
- vlc_input_decoder_Flush(es->p_dec);
+ if (!vlc_input_decoder_IsDrained(es->p_dec))
+ vlc_input_decoder_Flush(es->p_dec);
vlc_input_decoder_Delete(es->p_dec);
}
@@ -2455,7 +2456,8 @@ static void EsOutDestroyDecoder(es_out_sys_t *sys,
EsOutDeleteSubESes(sys, p_es);
- vlc_input_decoder_Flush(p_es->p_dec);
+ if (!vlc_input_decoder_IsDrained(p_es->p_dec))
+ vlc_input_decoder_Flush(p_es->p_dec);
vlc_input_decoder_Delete( p_es->p_dec );
p_es->p_dec = NULL;
if( p_es->p_pgrm->p_master_es_clock == p_es->p_clock )
@@ -2468,7 +2470,8 @@ static void EsOutDestroyDecoder(es_out_sys_t *sys,
if( p_es->p_dec_record )
{
- vlc_input_decoder_Flush(p_es->p_dec_record);
+ if (!vlc_input_decoder_IsDrained(p_es->p_dec_record))
+ vlc_input_decoder_Flush(p_es->p_dec_record);
vlc_input_decoder_Delete( p_es->p_dec_record );
p_es->p_dec_record = NULL;
}
@@ -3090,8 +3093,8 @@ EsOutDrainDecoder(es_out_sys_t *p_sys, es_out_id_t *es, bool wait)
* bit too long if the ES is deleted in the middle of a stream. */
while( !input_Stopped(p_sys->p_input) && !p_sys->b_buffering )
{
- if( vlc_input_decoder_IsEmpty( es->p_dec ) &&
- ( !es->p_dec_record || vlc_input_decoder_IsEmpty( es->p_dec_record ) ))
+ if( vlc_input_decoder_IsDrained( es->p_dec ) &&
+ ( !es->p_dec_record || vlc_input_decoder_IsDrained( es->p_dec_record ) ))
break;
/* FIXME there should be a way to have auto deleted es, but there will be
* a problem when another codec of the same type is created (mainly video) */
=====================================
src/input/test/es_out.c
=====================================
@@ -138,12 +138,17 @@ void vlc_input_decoder_StopWait(vlc_input_decoder_t *owner)
owner->started = true;
}
-bool vlc_input_decoder_IsEmpty(vlc_input_decoder_t *owner)
+bool vlc_input_decoder_IsDrained(vlc_input_decoder_t *owner)
{
(void)owner;
return owner->drained;
}
+bool vlc_input_decoder_IsEmpty(vlc_input_decoder_t *owner)
+{
+ return vlc_input_decoder_IsDrained(owner);
+}
+
void vlc_input_decoder_DecodeWithStatus(
vlc_input_decoder_t *owner,
vlc_frame_t *frame,
=====================================
src/libvlccore.sym
=====================================
@@ -188,6 +188,7 @@ vlc_input_decoder_Create
vlc_input_decoder_Delete
vlc_input_decoder_Decode
vlc_input_decoder_Drain
+vlc_input_decoder_IsDrained
vlc_input_decoder_Flush
vlc_input_decoder_SetSpuHighlight
vlc_input_decoder_ChangeDelay
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fd3b0b3ec5e7c4472c7894ea64a9cdfa0676bab6...82db8c43c1433ef26e1f27cd85cb54d4285135db
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fd3b0b3ec5e7c4472c7894ea64a9cdfa0676bab6...82db8c43c1433ef26e1f27cd85cb54d4285135db
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list