[vlc-commits] input: handle "sub-fps" with a new control

Thomas Guillem git at videolan.org
Thu Oct 18 13:12:53 CEST 2018


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Wed Oct 17 14:43:14 2018 +0200| [6d97630b701e3b66f4825729cbdebde24a2b4d35] | committer: Thomas Guillem

input: handle "sub-fps" with a new control

We now change the slave demux rate according to the requested subtitle fps and
the main demuxer fps.

Example: Video is 24fps but the subtitle is 26fps. In that case, we want to
slow down the subtitle demuxer. Setting "sub-fps" to 26 will change the rate
of the subtitle demuxer to 0.92.

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

 include/vlc_input.h        |  5 +++++
 src/input/event.h          |  8 ++++++++
 src/input/input.c          | 31 +++++++++++++++++++++++++++++++
 src/input/input_internal.h |  6 ++++++
 4 files changed, 50 insertions(+)

diff --git a/include/vlc_input.h b/include/vlc_input.h
index 3633d0121a..5d9fd5fadf 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -392,6 +392,9 @@ typedef enum input_event_type_e
     INPUT_EVENT_VBI_PAGE,
     /* vbi_transparent has changed */
     INPUT_EVENT_VBI_TRANSPARENCY,
+
+    /* subs_fps has changed */
+    INPUT_EVENT_SUBS_FPS,
 } input_event_type_e;
 
 #define VLC_INPUT_CAPABILITIES_SEEKABLE (1<<0)
@@ -523,6 +526,8 @@ struct vlc_input_event
         unsigned vbi_page;
         /* INPUT_EVENT_VBI_TRANSPARENCY */
         bool vbi_transparent;
+        /* INPUT_EVENT_SUBS_FPS */
+        float subs_fps;
     };
 };
 
diff --git a/src/input/event.h b/src/input/event.h
index 211be0bdcc..0f0aa0d606 100644
--- a/src/input/event.h
+++ b/src/input/event.h
@@ -182,6 +182,14 @@ static inline void input_SendEventMetaEpg(input_thread_t *p_input)
     });
 }
 
+static inline void input_SendEventSubsFPS(input_thread_t *p_input, float fps)
+{
+    input_SendEvent(p_input, &(struct vlc_input_event) {
+        .type = INPUT_EVENT_SUBS_FPS,
+        .subs_fps = fps,
+    });
+}
+
 /*****************************************************************************
  * Event for es_out.c
  *****************************************************************************/
diff --git a/src/input/input.c b/src/input/input.c
index 0595b8e73a..57e029ebb3 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -996,6 +996,16 @@ static bool SlaveExists( input_item_slave_t **pp_slaves, int i_slaves,
     return false;
 }
 
+static void RequestSubRate( input_thread_t *p_input, float f_slave_fps )
+{
+    input_thread_private_t *priv = input_priv(p_input);
+    const float f_fps = input_priv(p_input)->master->f_fps;
+    if( f_fps > 1.f && f_slave_fps > 1.f )
+        priv->i_slave_subs_rate = INPUT_RATE_DEFAULT / ( f_fps / f_slave_fps );
+    else if ( priv->i_slave_subs_rate != 0 )
+        priv->i_slave_subs_rate = INPUT_RATE_DEFAULT;
+}
+
 static void SetSubtitlesOptions( input_thread_t *p_input )
 {
     input_thread_private_t *priv = input_priv(p_input);
@@ -1005,6 +1015,7 @@ static void SetSubtitlesOptions( input_thread_t *p_input )
     if( f_fps > 1.f )
     {
         var_SetFloat( p_input, "sub-original-fps", f_fps );
+        RequestSubRate( p_input, var_InheritFloat( p_input, "sub-fps" ) );
     }
 
     int64_t sub_delay = var_InheritInteger( p_input, "sub-delay" );
@@ -2229,6 +2240,10 @@ static bool Control( input_thread_t *p_input,
                 }
             }
             break;
+        case INPUT_CONTROL_SET_SUBS_FPS:
+            RequestSubRate( p_input, param.val.f_float );
+            input_SendEventSubsFPS( p_input, param.val.f_float );
+            break;
 
         case INPUT_CONTROL_SET_RECORD_STATE:
             val = param.val;
@@ -2846,6 +2861,7 @@ static void InputSourceMeta( input_thread_t *p_input,
 
 static void SlaveDemux( input_thread_t *p_input )
 {
+    input_thread_private_t *priv = input_priv(p_input);
     vlc_tick_t i_time;
     int i;
 
@@ -2863,6 +2879,19 @@ static void SlaveDemux( input_thread_t *p_input )
         if( in->b_eof )
             continue;
 
+        if( priv->i_slave_subs_rate != in->i_sub_rate )
+        {
+            if( in->b_slave_sub && in->b_can_rate_control )
+            {
+                if( in->i_sub_rate != 0 ) /* Don't reset when it's the first time */
+                    es_out_Control( priv->p_es_out, ES_OUT_RESET_PCR );
+                int i_new_rate = priv->i_slave_subs_rate;
+                demux_Control( in->p_demux, DEMUX_SET_RATE, &i_new_rate );
+            }
+            in->i_sub_rate = priv->i_slave_subs_rate;
+        }
+
+
         /* Call demux_Demux until we have read enough data */
         if( demux_Control( in->p_demux, DEMUX_SET_NEXT_DEMUX_TIME, i_time ) )
         {
@@ -3344,6 +3373,8 @@ static int input_SlaveSourceAdd( input_thread_t *p_input,
         /* Get meta (access and demux) */
         InputUpdateMeta( p_input, p_source->p_demux );
     }
+    else
+        p_source->b_slave_sub = true;
 
     TAB_APPEND( priv->i_slave, priv->slave, p_source );
 
diff --git a/src/input/input_internal.h b/src/input/input_internal.h
index bcc8f06a91..95d09528cf 100644
--- a/src/input/input_internal.h
+++ b/src/input/input_internal.h
@@ -69,6 +69,10 @@ typedef struct
     bool b_rescale_ts;
     double f_fps;
 
+    /* sub-fps handling */
+    bool b_slave_sub;
+    unsigned i_sub_rate;
+
     /* */
     vlc_tick_t i_pts_delay;
 
@@ -175,6 +179,7 @@ typedef struct input_thread_private_t
     /* Slave sources (subs, and others) */
     int            i_slave;
     input_source_t **slave;
+    unsigned i_slave_subs_rate;
 
     /* Last ES added */
     enum es_format_category_e i_last_es_cat;
@@ -252,6 +257,7 @@ enum input_control_e
     INPUT_CONTROL_SET_SPU_DELAY,
 
     INPUT_CONTROL_ADD_SLAVE,
+    INPUT_CONTROL_SET_SUBS_FPS,
 
     INPUT_CONTROL_SET_RECORD_STATE,
 



More information about the vlc-commits mailing list