[vlc-commits] [Git][videolan/vlc][master] 2 commits: input: decoder: remove decoder thread in sout scenarios
Hugo Beauzée-Luyssen (@chouquette)
gitlab at videolan.org
Thu May 19 18:24:27 UTC 2022
Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC
Commits:
82ba705d by Alaric Senat at 2022-05-19T18:06:49+00:00
input: decoder: remove decoder thread in sout scenarios
Currently, a decoder thread is spawned to handle both the display and
the stream output. The decoder thread is actually unneeded by the stream
output as packetizing is the only task to do before forwarding the data
to the stream output. No heavy decoding is involved.
In addition to make the runtime lighter for stream output, having the
sout handling synchronous would help a lot for the implementation of
`PCR` forwarding in stream output (see !1394) as the asynchronous
`SetPCR` handling could be then managed in transcode only.
This patch removes the decoder thread usage in stream output scenarios
directly in the `vlc_input_decoder`. While this is far from ideal and
looks hacky, it's the best way I found to not change the code base too
much and not introduce unseen regressions right before 4.0 release.
These changes can be considered temporary as the plan in the long run
(after 4.0) is to remove stream output mention from `vlc_input_decoder`
and create a stream output specific `es_out` implementation.
Refs #26870 #26825
- - - - -
f7848ef0 by Alaric Senat at 2022-05-19T18:06:49+00:00
input: decoder: remove `DecoderThread_PlaySout()`
As it has become a one-liner function.
`assert( !sout_frame->p_next );` is irrelevant as `sout_frame->p_next`
is guaranteed to be NULL by the calling code anyway.
- - - - -
1 changed file:
- src/input/decoder.c
Changes:
=====================================
src/input/decoder.c
=====================================
@@ -200,6 +200,19 @@ static inline vlc_input_decoder_t *dec_get_owner( decoder_t *p_dec )
return container_of( p_dec, vlc_input_decoder_t, dec );
}
+/**
+ * When the input decoder is being used only for packetizing (happen in stream output
+ * configuration.), there's no need to spawn a decoder thread. The input_decoder is then considered
+ * *synchronous*.
+ *
+ * @retval true When no decoder thread will be spawned.
+ * @retval false When a decoder thread will be spawned.
+ */
+static inline bool vlc_input_decoder_IsSynchronous( const vlc_input_decoder_t *dec )
+{
+ return dec->p_sout != NULL;
+}
+
/**
* Load a decoder module
*/
@@ -871,21 +884,6 @@ static inline void DecoderUpdatePreroll( vlc_tick_t *pi_preroll, const vlc_frame
}
#ifdef ENABLE_SOUT
-static int DecoderThread_PlaySout( vlc_input_decoder_t *p_owner, vlc_frame_t *sout_frame )
-{
- assert( !sout_frame->p_next );
-
- vlc_mutex_lock( &p_owner->lock );
-
- DecoderWaitUnblock( p_owner );
-
- vlc_mutex_unlock( &p_owner->lock );
-
- /* FIXME --VLC_TICK_INVALID inspect stream_output*/
- return sout_InputSendBuffer( p_owner->p_sout, p_owner->p_sout_input,
- sout_frame );
-}
-
/* This function process a frame for sout
*/
static void DecoderThread_ProcessSout( vlc_input_decoder_t *p_owner, vlc_frame_t *frame )
@@ -969,7 +967,9 @@ static void DecoderThread_ProcessSout( vlc_input_decoder_t *p_owner, vlc_frame_t
}
}
- if( DecoderThread_PlaySout( p_owner, sout_frame ) == VLC_EGENERIC )
+ /* FIXME --VLC_TICK_INVALID inspect stream_output*/
+ if ( sout_InputSendBuffer( p_owner->p_sout, p_owner->p_sout_input, sout_frame ) ==
+ VLC_EGENERIC )
{
msg_Err( p_dec, "cannot continue streaming due to errors with codec %4.4s",
(char *)&p_owner->fmt.i_codec );
@@ -2128,12 +2128,15 @@ decoder_New( vlc_object_t *p_parent, const struct vlc_input_decoder_cfg *cfg )
}
#endif
- /* Spawn the decoder thread */
- if( vlc_clone( &p_owner->thread, DecoderThread, p_owner ) )
+ if( !vlc_input_decoder_IsSynchronous( p_owner ) )
{
- msg_Err( p_dec, "cannot spawn decoder thread" );
- DeleteDecoder( p_owner, p_dec->fmt_in.i_cat );
- return NULL;
+ /* Spawn the decoder thread in asynchronous scenario. */
+ if( vlc_clone( &p_owner->thread, DecoderThread, p_owner ) )
+ {
+ msg_Err( p_dec, "cannot spawn decoder thread" );
+ DeleteDecoder( p_owner, p_dec->fmt_in.i_cat );
+ return NULL;
+ }
}
return p_owner;
@@ -2226,7 +2229,8 @@ void vlc_input_decoder_Delete( vlc_input_decoder_t *p_owner )
}
vlc_mutex_unlock( &p_owner->lock );
- vlc_join( p_owner->thread, NULL );
+ if( !vlc_input_decoder_IsSynchronous( p_owner ) )
+ vlc_join( p_owner->thread, NULL );
/* */
if( p_owner->cc.b_supported )
@@ -2249,6 +2253,14 @@ void vlc_input_decoder_Delete( vlc_input_decoder_t *p_owner )
void vlc_input_decoder_Decode( vlc_input_decoder_t *p_owner, vlc_frame_t *frame,
bool b_do_pace )
{
+ if( vlc_input_decoder_IsSynchronous( p_owner ) )
+ {
+ /* DecoderThread's fifo should be empty as no decoder thread is running. */
+ assert( vlc_fifo_IsEmpty( p_owner->p_fifo ) );
+ DecoderThread_ProcessInput( p_owner, frame );
+ return;
+ }
+
vlc_fifo_Lock( p_owner->p_fifo );
if( !b_do_pace )
{
@@ -2317,6 +2329,13 @@ bool vlc_input_decoder_IsEmpty( vlc_input_decoder_t * p_owner )
*/
void vlc_input_decoder_Drain( vlc_input_decoder_t *p_owner )
{
+ if ( vlc_input_decoder_IsSynchronous( p_owner ) )
+ {
+ /* Process a NULL frame synchronously to signal draining to packetizer/decoder. */
+ DecoderThread_ProcessInput( p_owner, NULL );
+ return;
+ }
+
vlc_fifo_Lock( p_owner->p_fifo );
p_owner->b_draining = true;
vlc_fifo_Signal( p_owner->p_fifo );
@@ -2329,6 +2348,12 @@ void vlc_input_decoder_Drain( vlc_input_decoder_t *p_owner )
*/
void vlc_input_decoder_Flush( vlc_input_decoder_t *p_owner )
{
+ if( vlc_input_decoder_IsSynchronous( p_owner ) )
+ {
+ DecoderThread_Flush( p_owner );
+ return;
+ }
+
enum es_format_category_e cat = p_owner->dec.fmt_in.i_cat;
vlc_fifo_Lock( p_owner->p_fifo );
@@ -2510,6 +2535,9 @@ void vlc_input_decoder_ChangeDelay( vlc_input_decoder_t *owner, vlc_tick_t delay
void vlc_input_decoder_StartWait( vlc_input_decoder_t *p_owner )
{
+ if( vlc_input_decoder_IsSynchronous( p_owner ) )
+ return;
+
assert( !p_owner->b_waiting );
vlc_mutex_lock( &p_owner->lock );
@@ -2522,6 +2550,9 @@ void vlc_input_decoder_StartWait( vlc_input_decoder_t *p_owner )
void vlc_input_decoder_StopWait( vlc_input_decoder_t *p_owner )
{
+ if( vlc_input_decoder_IsSynchronous( p_owner ) )
+ return;
+
assert( p_owner->b_waiting );
vlc_mutex_lock( &p_owner->lock );
@@ -2532,6 +2563,11 @@ void vlc_input_decoder_StopWait( vlc_input_decoder_t *p_owner )
void vlc_input_decoder_Wait( vlc_input_decoder_t *p_owner )
{
+ if( vlc_input_decoder_IsSynchronous( p_owner ) )
+ {
+ /* Nothing to wait for. There's no decoder thread running. */
+ return;
+ }
assert( p_owner->b_waiting );
vlc_mutex_lock( &p_owner->lock );
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c3df9c37123acd2575b309ddc4591fc75debe57d...f7848ef09990972db8013e45e3dc342ae1c58930
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c3df9c37123acd2575b309ddc4591fc75debe57d...f7848ef09990972db8013e45e3dc342ae1c58930
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