[vlc-devel] Set subtitle delay to the next/previous subtitle line

Aurélien Aptel aurelien.aptel at gmail.com
Sun Jan 15 17:36:28 CET 2012


I've settled to using a new vlc integer var, "sub-line-jump" which set
to 0 to jump to the previous line and 1 to the next. I've replaced h/g
hotkey for testing purpose.
While doing this I found a bug: if a the subtitle delay (spu-delay) is
a "large" negative number (eg -100s), the video freeze for that much
time (100s). I've filled a new ticket (
https://trac.videolan.org/vlc/ticket/5863 ).

diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c
index 74e74f0..ce4a580 100644
--- a/modules/control/hotkeys.c
+++ b/modules/control/hotkeys.c
@@ -756,22 +756,20 @@ static int PutAction( intf_thread_t *p_intf, int
i_action )

             else if( i_action == ACTIONID_SUBDELAY_DOWN )
             {
+                var_SetInteger(p_input, "sub-line-jump", 0);
                 int64_t i_delay = var_GetTime( p_input, "spu-delay" );
-                i_delay -= 50000;    /* 50 ms */
-                var_SetTime( p_input, "spu-delay", i_delay );
                 ClearChannels( p_intf, p_vout );
                 DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL,
-                                _( "Subtitle delay %i ms" ),
+                                _( "PREV Subtitle delay %i ms" ),
                                 (int)(i_delay/1000) );
             }
             else if( i_action == ACTIONID_SUBDELAY_UP )
             {
+                var_SetInteger(p_input, "sub-line-jump", 1);
                 int64_t i_delay = var_GetTime( p_input, "spu-delay" );
-                i_delay += 50000;    /* 50 ms */
-                var_SetTime( p_input, "spu-delay", i_delay );
                 ClearChannels( p_intf, p_vout );
                 DisplayMessage( p_vout, SPU_DEFAULT_CHANNEL,
-                                _( "Subtitle delay %i ms" ),
+                                _( "NEXT Subtitle delay %i ms" ),
                                  (int)(i_delay/1000) );
             }
             else if( ( i_action == ACTIONID_SUBPOS_DOWN ||
diff --git a/modules/demux/subtitle.c b/modules/demux/subtitle.c
index 18aeaa9..a88c249 100644
--- a/modules/demux/subtitle.c
+++ b/modules/demux/subtitle.c
@@ -219,6 +219,12 @@ static const struct
  * to src/input/subtitles.c to enable auto-detection.
  */

+enum {
+    SUB_LINE_PREV,
+    SUB_LINE_NEXT,
+};
+static int SubLineJumpCallback (vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void *);
+
 static int Demux( demux_t * );
 static int Control( demux_t *, int, va_list );

@@ -273,6 +279,10 @@ static int Open ( vlc_object_t *p_this )
         msg_Dbg( p_demux, "Override subtitle fps %f", f_fps );
     }

+    /* Set 'delay by line' trigger */
+    var_Create(p_demux->p_parent, "sub-line-jump", VLC_VAR_VOID);
+    var_AddCallback(p_demux->p_parent, "sub-line-jump",
SubLineJumpCallback, (void*)p_demux);
+
     /* Get or probe the type */
     p_sys->i_type = SUB_TYPE_UNKNOWN;
     psz_type = var_CreateGetString( p_demux, "sub-type" );
@@ -658,7 +668,7 @@ static int Demux( demux_t *p_demux )
     if( p_sys->i_subtitle >= p_sys->i_subtitles )
         return 0;

-    i_maxdate = p_sys->i_next_demux_date - var_GetTime(
p_demux->p_parent, "spu-delay" );;
+    i_maxdate = p_sys->i_next_demux_date - var_GetTime(
p_demux->p_parent, "spu-delay" );
     if( i_maxdate <= 0 && p_sys->i_subtitle < p_sys->i_subtitles )
     {
         /* Should not happen */
@@ -703,6 +713,60 @@ static int Demux( demux_t *p_demux )
     return 1;
 }

+
+
+int SubLineJumpCallback ( vlc_object_t *p_this, char const *psz_var,
+                          vlc_value_t old, vlc_value_t new, void *p_data )
+{
+    VLC_UNUSED(p_this); VLC_UNUSED(psz_var); VLC_UNUSED(old);
+
+    demux_t *p_demux = (demux_t*)p_data;
+    demux_sys_t *p_sys = p_demux->p_sys;
+    bool b_next = new.i_int == SUB_LINE_NEXT;
+
+    int i_subsize = p_sys->i_subtitles;
+    int i_prev, i_next, i_new;
+
+    int64_t t_delay = var_GetTime(p_demux->p_parent, "spu-delay");
+    int64_t t_next_demux = p_sys->i_next_demux_date;
+    int64_t t_now = t_next_demux;
+
+    i_prev = i_next = i_new = -1;
+
+    /* find next & prev sub (taking into account current delay) */
+    for( int i = 0; i < i_subsize; i++ )
+    {
+        const subtitle_t *p_sub = &p_sys->subtitle[i];
+
+        if( t_now < p_sub->i_start+t_delay )
+        {
+            i_prev = i-1;
+            i_next = i;
+            break;
+        }
+
+        if( t_now <= p_sub->i_stop+t_delay )
+        {
+            i_prev = i-1;
+            i_next = i+1;
+            break;
+        }
+    }
+
+    i_new = b_next ? i_next : i_prev;
+
+    if( i_new < 0 || i_new >= i_subsize )
+        return VLC_EGENERIC;
+
+    msg_Err(p_demux, "jump to %d", i_new);
+    t_delay = t_now - p_sys->subtitle[i_new].i_start;
+    p_sys->i_subtitle = i_new;
+    var_SetTime(p_demux->p_parent, "spu-delay", t_delay);
+
+    return VLC_SUCCESS;
+}
+
+
 /*****************************************************************************
  * Fix: fix time stamp and order of subtitle
  *****************************************************************************/



More information about the vlc-devel mailing list