[vlc-commits] decoder: add input_DecoderChangeRate()

Rémi Denis-Courmont git at videolan.org
Sat May 5 17:46:06 CEST 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu May  3 16:38:10 2018 +0300| [843a9b24097d7db615da06022b1bfb6881a1a7f4] | committer: Rémi Denis-Courmont

decoder: add input_DecoderChangeRate()

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=843a9b24097d7db615da06022b1bfb6881a1a7f4
---

 src/input/decoder.c | 32 +++++++++++++++++++++++++++++---
 src/input/decoder.h |  9 +++++++++
 src/input/es_out.c  | 20 +++++++++++++++++---
 3 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/src/input/decoder.c b/src/input/decoder.c
index 50d3d779cd..94b07533a8 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -111,8 +111,9 @@ struct decoder_owner_sys_t
     /* -- Theses variables need locking on read *and* write -- */
     /* Preroll */
     int64_t i_preroll_end;
-    /* Pause */
+    /* Pause & Rate */
     mtime_t pause_date;
+    float rate;
     unsigned frames_countdown;
     bool paused;
 
@@ -1186,8 +1187,6 @@ static int DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
      && i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE
      && !DecoderTimedWait( p_dec, p_audio->i_pts - AOUT_MAX_PREPARE_TIME ) )
     {
-        aout_DecChangeRate( p_aout, ((float)i_rate) / 1000.f );
-
         int status = aout_DecPlay( p_aout, p_audio );
         if( status == AOUT_DEC_CHANGED )
         {
@@ -1536,6 +1535,7 @@ static void *DecoderThread( void *p_data )
 {
     decoder_t *p_dec = (decoder_t *)p_data;
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
+    float rate = 1.f;
     bool paused = false;
 
     /* The decoder's main loop */
@@ -1585,6 +1585,21 @@ static void *DecoderThread( void *p_data )
             continue;
         }
 
+        if( rate != p_owner->rate )
+        {
+            int canc = vlc_savecancel();
+
+            rate = p_owner->rate;
+            vlc_fifo_Unlock( p_owner->p_fifo );
+
+            msg_Dbg( p_dec, "changing rate: %f", rate );
+            if( p_owner->p_aout != NULL )
+                aout_DecChangeRate( p_owner->p_aout, rate );
+
+            vlc_restorecancel( canc );
+            vlc_fifo_Lock( p_owner->p_fifo );
+        }
+
         if( p_owner->paused && p_owner->frames_countdown == 0 )
         {   /* Wait for resumption from pause */
             p_owner->b_idle = true;
@@ -1684,6 +1699,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
     p_owner->b_fmt_description = false;
     p_owner->p_description = NULL;
 
+    p_owner->rate = 1.f;
     p_owner->paused = false;
     p_owner->pause_date = VLC_TS_INVALID;
     p_owner->frames_countdown = 0;
@@ -2272,6 +2288,16 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
     vlc_fifo_Unlock( p_owner->p_fifo );
 }
 
+void input_DecoderChangeRate( decoder_t *dec, float rate )
+{
+    decoder_owner_sys_t *owner = dec->p_owner;
+
+    vlc_fifo_Lock( owner->p_fifo );
+    owner->rate = rate;
+    vlc_fifo_Signal( owner->p_fifo );
+    vlc_fifo_Unlock( owner->p_fifo );
+}
+
 void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
 {
     decoder_owner_sys_t *p_owner = p_dec->p_owner;
diff --git a/src/input/decoder.h b/src/input/decoder.h
index ccfe8ecd05..eecd68499d 100644
--- a/src/input/decoder.h
+++ b/src/input/decoder.h
@@ -39,6 +39,15 @@ decoder_t *input_DecoderNew( input_thread_t *, es_format_t *, input_clock_t *,
 void input_DecoderChangePause( decoder_t *, bool b_paused, mtime_t i_date );
 
 /**
+ * Changes the decoder rate.
+ *
+ * This function changes rate of the intended playback speed to nominal speed.
+ * \param dec decoder
+ * \param rate playback rate (default is 1)
+ */
+void input_DecoderChangeRate( decoder_t *dec, float rate );
+
+/**
  * This function changes the delay.
  */
 void input_DecoderChangeDelay( decoder_t *, mtime_t i_delay );
diff --git a/src/input/es_out.c b/src/input/es_out.c
index e0c0594a27..b424ea418d 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -588,9 +588,18 @@ static void EsOutChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
 static void EsOutChangeRate( es_out_t *out, int i_rate )
 {
     es_out_sys_t      *p_sys = out->p_sys;
+    float rate = (float)i_rate / (float)INPUT_RATE_DEFAULT;
 
     p_sys->i_rate = i_rate;
     EsOutProgramsChangeRate( out );
+
+    for( int i = 0; i < p_sys->i_es; i++ )
+    {
+        es_out_id_t *es = p_sys->es[i];
+
+        if( es->p_dec != NULL )
+            input_DecoderChangeRate( es->p_dec, rate );
+    }
 }
 
 static void EsOutChangePosition( es_out_t *out )
@@ -1683,12 +1692,16 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es )
 {
     es_out_sys_t   *p_sys = out->p_sys;
     input_thread_t *p_input = p_sys->p_input;
+    decoder_t *dec;
 
-    p_es->p_dec = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_input_clock, input_priv(p_input)->p_sout );
-    if( p_es->p_dec )
+    dec = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_input_clock,
+                            input_priv(p_input)->p_sout );
+    if( dec != NULL )
     {
+        input_DecoderChangeRate( dec, p_sys->i_rate );
+
         if( p_sys->b_buffering )
-            input_DecoderStartWait( p_es->p_dec );
+            input_DecoderStartWait( dec );
 
         if( !p_es->p_master && p_sys->p_sout_record )
         {
@@ -1697,6 +1710,7 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es )
                 input_DecoderStartWait( p_es->p_dec_record );
         }
     }
+    p_es->p_dec = dec;
 
     EsOutDecoderChangeDelay( out, p_es );
 }



More information about the vlc-commits mailing list