[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