[vlc-commits] [Git][videolan/vlc][master] 4 commits: decoder: move code up

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat Mar 11 17:21:20 UTC 2023



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
378db759 by Thomas Guillem at 2023-03-11T16:51:11+00:00
decoder: move code up

To avoid forward declarations in next commits.

- - - - -
74adb26c by Thomas Guillem at 2023-03-11T16:51:11+00:00
decoder: rename some functions

These functions can be called from any threads, if the lock is held.

- - - - -
a89b5d6b by Thomas Guillem at 2023-03-11T16:51:11+00:00
decoder: rename request_rate to rate

Use the same naming that paused and delay.

- - - - -
63488e04 by Thomas Guillem at 2023-03-11T16:51:11+00:00
decoder: update the state directly when creating an output

Threading changed, it is now possible.

This fixes the video or audio output that can render the first frames in
the initial state, leading to audio/video glitches (if a delay is
applied after).

For example, audio with clock-master=input:

[00007fc4a4311760] main decoder: vlc_input_decoder_ChangeDelay():
000055ad16120e60] main audio output error: Play in 133193
[000055ad16120e60] main audio output error: Play in 156331
[000055ad16120e60] main audio output error: Play in 179508
[000055ad16120e60] main audio output error: Play in 202699
[000055ad16120e60] main audio output error: Play in 225891
[00007fc4a4311760] main decoder: changing delay(2): -2000000
[000055ad16120e60] main audio output error: Play in -1750921

Refs #27918

- - - - -


1 changed file:

- src/input/decoder.c


Changes:

=====================================
src/input/decoder.c
=====================================
@@ -193,12 +193,11 @@ struct vlc_input_decoder_t
 #define PREROLL_FORCED VLC_TICK_MAX
 
     /* Pause & Rate */
-    bool reset_out_state;
     vlc_tick_t pause_date;
-    vlc_tick_t delay;
-    float request_rate, output_rate;
+    vlc_tick_t delay, output_delay;
+    float rate, output_rate;
     unsigned frames_countdown;
-    bool paused;
+    bool paused, output_paused;
 
     bool error;
 
@@ -262,6 +261,105 @@ static inline bool vlc_input_decoder_IsSynchronous( const vlc_input_decoder_t *d
     return dec->p_sout != NULL;
 }
 
+static void Decoder_ChangeOutputPause( vlc_input_decoder_t *p_owner, bool paused, vlc_tick_t date )
+{
+    vlc_fifo_Assert(p_owner->p_fifo);
+
+    decoder_t *p_dec = &p_owner->dec;
+
+    msg_Dbg( p_dec, "toggling %s", paused ? "resume" : "pause" );
+    switch( p_dec->fmt_in->i_cat )
+    {
+        case VIDEO_ES:
+            if( p_owner->p_vout != NULL && p_owner->vout_started )
+                vout_ChangePause( p_owner->p_vout, paused, date );
+            break;
+        case AUDIO_ES:
+            if( p_owner->p_astream != NULL )
+                vlc_aout_stream_ChangePause( p_owner->p_astream, paused, date );
+            break;
+        case SPU_ES:
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+    p_owner->output_paused = paused;
+}
+
+static void Decoder_ChangeOutputRate( vlc_input_decoder_t *p_owner, float rate )
+{
+    vlc_fifo_Assert(p_owner->p_fifo);
+
+    decoder_t *p_dec = &p_owner->dec;
+
+    msg_Dbg( p_dec, "changing rate: %f", rate );
+    switch( p_dec->fmt_in->i_cat )
+    {
+        case VIDEO_ES:
+            if( p_owner->p_vout != NULL && p_owner->vout_started )
+                vout_ChangeRate( p_owner->p_vout, rate );
+            break;
+        case AUDIO_ES:
+            if( p_owner->p_astream != NULL )
+                vlc_aout_stream_ChangeRate( p_owner->p_astream, rate );
+            break;
+        case SPU_ES:
+            if( p_owner->p_vout != NULL )
+            {
+                assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
+                vout_ChangeSpuRate(p_owner->p_vout, p_owner->i_spu_channel,
+                                   rate );
+            }
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+    p_owner->output_rate = rate;
+}
+
+static void Decoder_ChangeOutputDelay( vlc_input_decoder_t *p_owner, vlc_tick_t delay )
+{
+    vlc_fifo_Assert(p_owner->p_fifo);
+
+    decoder_t *p_dec = &p_owner->dec;
+
+    msg_Dbg( p_dec, "changing delay: %"PRId64, delay );
+    switch( p_dec->fmt_in->i_cat )
+    {
+        case VIDEO_ES:
+            if( p_owner->p_vout != NULL && p_owner->vout_started )
+                vout_ChangeDelay( p_owner->p_vout, delay );
+            break;
+        case AUDIO_ES:
+            if( p_owner->p_astream != NULL )
+                vlc_aout_stream_ChangeDelay( p_owner->p_astream, delay );
+            break;
+        case SPU_ES:
+            if( p_owner->p_vout != NULL )
+            {
+                assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
+                vout_ChangeSpuDelay(p_owner->p_vout, p_owner->i_spu_channel,
+                                    delay);
+            }
+            break;
+        default:
+            vlc_assert_unreachable();
+    }
+    p_owner->output_delay = delay;
+}
+
+static void Decoder_UpdateOutState(vlc_input_decoder_t *owner)
+{
+    if (owner->paused)
+        Decoder_ChangeOutputPause(owner, owner->paused, owner->pause_date);
+
+    if (owner->rate != 1.f)
+        Decoder_ChangeOutputRate(owner, owner->rate);
+
+    if (owner->delay != 0)
+        Decoder_ChangeOutputDelay(owner, owner->delay);
+}
+
 /**
  * Load a decoder module
  */
@@ -484,7 +582,7 @@ static int ModuleThread_UpdateAudioFormat( decoder_t *p_dec )
         p_dec->fmt_out.audio.i_frame_length =
             p_owner->fmt.audio.i_frame_length;
 
-        p_owner->reset_out_state = true;
+        Decoder_UpdateOutState( p_owner );
         vlc_fifo_Unlock( p_owner->p_fifo );
     }
     return 0;
@@ -575,7 +673,7 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *
 
         if (vout_state == INPUT_RESOURCE_VOUT_STARTED)
         {
-            p_owner->reset_out_state = true;
+            Decoder_UpdateOutState( p_owner );
             vlc_fifo_Unlock(p_owner->p_fifo);
 
             decoder_Notify(p_owner, on_vout_started, p_vout, p_owner->vout_order);
@@ -1594,91 +1692,6 @@ static void DecoderThread_Flush( vlc_input_decoder_t *p_owner )
     vlc_mutex_unlock(&p_owner->cc.lock);
 }
 
-static void DecoderThread_ChangePause( vlc_input_decoder_t *p_owner, bool paused, vlc_tick_t date )
-{
-    vlc_fifo_Assert(p_owner->p_fifo);
-
-    decoder_t *p_dec = &p_owner->dec;
-
-    msg_Dbg( p_dec, "toggling %s", paused ? "resume" : "pause" );
-    switch( p_dec->fmt_in->i_cat )
-    {
-        case VIDEO_ES:
-            if( p_owner->p_vout != NULL && p_owner->vout_started )
-                vout_ChangePause( p_owner->p_vout, paused, date );
-            break;
-        case AUDIO_ES:
-            if( p_owner->p_astream != NULL )
-                vlc_aout_stream_ChangePause( p_owner->p_astream, paused, date );
-            break;
-        case SPU_ES:
-            break;
-        default:
-            vlc_assert_unreachable();
-    }
-}
-
-static void DecoderThread_ChangeRate( vlc_input_decoder_t *p_owner, float rate )
-{
-    vlc_fifo_Assert(p_owner->p_fifo);
-
-    decoder_t *p_dec = &p_owner->dec;
-
-    msg_Dbg( p_dec, "changing rate: %f", rate );
-    switch( p_dec->fmt_in->i_cat )
-    {
-        case VIDEO_ES:
-            if( p_owner->p_vout != NULL && p_owner->vout_started )
-                vout_ChangeRate( p_owner->p_vout, rate );
-            break;
-        case AUDIO_ES:
-            if( p_owner->p_astream != NULL )
-                vlc_aout_stream_ChangeRate( p_owner->p_astream, rate );
-            break;
-        case SPU_ES:
-            if( p_owner->p_vout != NULL )
-            {
-                assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
-                vout_ChangeSpuRate(p_owner->p_vout, p_owner->i_spu_channel,
-                                   rate );
-            }
-            break;
-        default:
-            vlc_assert_unreachable();
-    }
-    p_owner->output_rate = rate;
-}
-
-static void DecoderThread_ChangeDelay( vlc_input_decoder_t *p_owner, vlc_tick_t delay )
-{
-    vlc_fifo_Assert(p_owner->p_fifo);
-
-    decoder_t *p_dec = &p_owner->dec;
-
-    msg_Dbg( p_dec, "changing delay: %"PRId64, delay );
-    switch( p_dec->fmt_in->i_cat )
-    {
-        case VIDEO_ES:
-            if( p_owner->p_vout != NULL && p_owner->vout_started )
-                vout_ChangeDelay( p_owner->p_vout, delay );
-            break;
-        case AUDIO_ES:
-            if( p_owner->p_astream != NULL )
-                vlc_aout_stream_ChangeDelay( p_owner->p_astream, delay );
-            break;
-        case SPU_ES:
-            if( p_owner->p_vout != NULL )
-            {
-                assert(p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID);
-                vout_ChangeSpuDelay(p_owner->p_vout, p_owner->i_spu_channel,
-                                    delay);
-            }
-            break;
-        default:
-            vlc_assert_unreachable();
-    }
-}
-
 /**
  * The decoding main loop
  *
@@ -1687,9 +1700,6 @@ static void DecoderThread_ChangeDelay( vlc_input_decoder_t *p_owner, vlc_tick_t
 static void *DecoderThread( void *p_data )
 {
     vlc_input_decoder_t *p_owner = (vlc_input_decoder_t *)p_data;
-    float rate = 1.f;
-    vlc_tick_t delay = 0;
-    bool paused = false;
 
     const char *thread_name;
     switch (p_owner->dec.fmt_in->i_cat)
@@ -1726,37 +1736,21 @@ static void *DecoderThread( void *p_data )
             continue;
         }
 
-        /* Reset the original pause/rate state when a new aout/vout is created:
-         * this will trigger the DecoderThread_ChangePause/DecoderThread_ChangeRate code path
-         * if needed. */
-        if( p_owner->reset_out_state )
-        {
-            rate = 1.f;
-            paused = false;
-            delay = 0;
-            p_owner->reset_out_state = false;
-        }
-
-        if( paused != p_owner->paused )
+        if( p_owner->paused != p_owner->output_paused )
         {   /* Update playing/paused status of the output */
-            vlc_tick_t date = p_owner->pause_date;
-
-            paused = p_owner->paused;
-            DecoderThread_ChangePause( p_owner, paused, date );
+            Decoder_ChangeOutputPause( p_owner, p_owner->paused, p_owner->pause_date );
             continue;
         }
 
-        if( rate != p_owner->request_rate )
+        if( p_owner->rate != p_owner->output_rate )
         {
-            rate = p_owner->request_rate;
-            DecoderThread_ChangeRate( p_owner, rate );
+            Decoder_ChangeOutputRate( p_owner, p_owner->rate );
             continue;
         }
 
-        if( delay != p_owner->delay )
+        if( p_owner->delay != p_owner->output_delay )
         {
-            delay = p_owner->delay;
-            DecoderThread_ChangeDelay( p_owner, delay );
+            Decoder_ChangeOutputDelay( p_owner, p_owner->delay );
             continue;
         }
 
@@ -1892,10 +1886,9 @@ CreateDecoder( vlc_object_t *p_parent, const struct vlc_input_decoder_cfg *cfg )
     p_owner->b_fmt_description = false;
     p_owner->p_description = NULL;
 
-    p_owner->reset_out_state = false;
-    p_owner->delay = 0;
-    p_owner->output_rate = p_owner->request_rate = 1.f;
-    p_owner->paused = false;
+    p_owner->output_delay = p_owner->delay = 0;
+    p_owner->output_rate = p_owner->rate = 1.f;
+    p_owner->output_paused = p_owner->paused = false;
     p_owner->pause_date = VLC_TICK_INVALID;
     p_owner->frames_countdown = 0;
 
@@ -2555,7 +2548,7 @@ void vlc_input_decoder_ChangePause( vlc_input_decoder_t *p_owner,
 void vlc_input_decoder_ChangeRate( vlc_input_decoder_t *owner, float rate )
 {
     vlc_fifo_Lock( owner->p_fifo );
-    owner->request_rate = rate;
+    owner->rate = rate;
     vlc_fifo_Unlock( owner->p_fifo );
 }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/656e5eb27ab1584e66efa7d132fd3b272165fbde...63488e047dfeb25e23e7a210b0c38ff609f86516

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/656e5eb27ab1584e66efa7d132fd3b272165fbde...63488e047dfeb25e23e7a210b0c38ff609f86516
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