<div dir="ltr">This seems to be breaking regular subtitle delay (positive and negative) with keys G and H.<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-05-30 22:04 GMT+02:00 Pascal Thomet <span dir="ltr"><<a href="mailto:pthomet@gmail.com" target="_blank">pthomet@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is a follow-up to a patch I made last year<br>
(f7211d5efa4cd9ef392230d85fdf3470edefab39)<br>
When developping it I stumbled upon a prexisting bug that I could<br>
not correct at that time.<br>
<br>
I now propose a correction for this bug, as well as tooltip that better<br>
explain the use of the hotkeys introduced by f7211d5efa4cd9ef392230d85fdf3470edefab39<br>
<br>
tests passed / compile and runs correctly in debug & release modes<br>
under linux & OSX<br>
<br>
1) Bug correction info :<br>
* * * * * * * * *<br>
<br>
Bug reproduction step : *under linux* (will not happen under OSX)<br>
- launch a video that has a subtitle,<br>
- press Shift-H ("bookmark audio time"),<br>
- wait 5 seconds<br>
- press Shift-J ("bookmark subtitle time")<br>
- press Shift-K ("sync bookmarks")<br>
==> the audio is broken...<br>
(AFAIK this bug seems not to be mentioned on <a href="http://trac.videolan.org" target="_blank">trac.videolan.org</a>)<br>
<br>
The subtitle delay ("spu-delay") was previously implemented by<br>
i) setting a variable spu-delay<br>
(var_SetTime(... , "spu-delay", ... ))<br>
ii) this change raised a callback that finaly lead to calling<br>
UpdatePtsDelay().<br>
<br>
The reason UpdatePtsDelay() was called is that the subtitle delay<br>
was programed the same way as the audio delay (for which it is required<br>
to wait until the audio is actually demuxed)<br>
<br>
*However* the situation for subtitles is quite different, as they are all in memory<br>
(no need to wait until they are demuxed !)<br>
<br>
The code is now more simple (and the bug is fixed !) :<br>
- no more delay calculations inside hotkeys.c, everything is handled<br>
inside subtitle.c through callbacks<br>
- inside subtitle.c :<br>
* adjust_subtitle_time() receives a subtitle timestamp as input and returns<br>
that timestamp corrected by spu-delay<br>
* set_current_subtitle_by_time() is called when spu-delay is changed<br>
<br>
2) Tooltip<br>
* * * *<br>
<br>
This adds a tooltip in the "Track Synchronization" window<br>
on the "subtitle track sycnhronization" label and widget.<br>
It explains better the use of the subtitle sync hotkeys<br>
(Shift H/J/K)<br>
<br>
Also tested under Linux & OSX.<br>
---<br>
include/vlc_input.h | 2 -<br>
modules/control/hotkeys.c | 113 +++++---------<br>
modules/demux/subtitle.c | 205 +++++++++++++++++++++----<br>
modules/gui/macosx/TrackSynchronization.m | 17 +-<br>
modules/gui/macosx/intf.m | 1 -<br>
modules/gui/qt4/components/extended_panels.cpp | 16 +-<br>
modules/gui/qt4/input_manager.cpp | 1 -<br>
src/input/event.c | 10 --<br>
src/input/event.h | 1 -<br>
src/input/input.c | 10 +-<br>
src/input/input_internal.h | 1 -<br>
src/input/var.c | 5 -<br>
12 files changed, 250 insertions(+), 132 deletions(-)<br>
<br>
diff --git a/include/vlc_input.h b/include/vlc_input.h<br>
index 88bfe65..043414e 100644<br>
--- a/include/vlc_input.h<br>
+++ b/include/vlc_input.h<br>
@@ -380,8 +380,6 @@ typedef enum input_event_type_e<br>
<br>
/* "audio-delay" has changed */<br>
INPUT_EVENT_AUDIO_DELAY,<br>
- /* "spu-delay" has changed */<br>
- INPUT_EVENT_SUBTITLE_DELAY,<br>
<br>
/* "bookmark" has changed */<br>
INPUT_EVENT_BOOKMARK,<br>
diff --git a/modules/control/hotkeys.c b/modules/control/hotkeys.c<br>
index 1e7fcdf..eb00c57 100644<br>
--- a/modules/control/hotkeys.c<br>
+++ b/modules/control/hotkeys.c<br>
@@ -48,13 +48,6 @@ struct intf_sys_t<br>
{<br>
vout_thread_t *p_last_vout;<br>
int slider_chan;<br>
-<br>
- /*subtitle_delaybookmarks: placeholder for storing subtitle sync timestamps*/<br>
- struct<br>
- {<br>
- int64_t i_time_subtitle;<br>
- int64_t i_time_audio;<br>
- } subtitle_delaybookmarks;<br>
};<br>
<br>
/*****************************************************************************<br>
@@ -108,10 +101,14 @@ static int Open( vlc_object_t *p_this )<br>
p_intf->p_sys = p_sys;<br>
<br>
p_sys->p_last_vout = NULL;<br>
- p_sys->subtitle_delaybookmarks.i_time_audio = 0;<br>
- p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;<br>
<br>
+ /* key-osdmessage : variable to be used from external modules<br>
+ * in order to display an osd message<br>
+ * as an informative response after a hotkey press */<br>
+ var_Create (p_intf->p_libvlc, "key-osdmessage", VLC_VAR_STRING);<br>
+ var_AddCallback( p_intf->p_libvlc, "key-osdmessage", ActionEvent, p_intf );<br>
var_AddCallback( p_intf->p_libvlc, "key-action", ActionEvent, p_intf );<br>
+<br>
return VLC_SUCCESS;<br>
}<br>
<br>
@@ -123,6 +120,8 @@ static void Close( vlc_object_t *p_this )<br>
intf_thread_t *p_intf = (intf_thread_t *)p_this;<br>
intf_sys_t *p_sys = p_intf->p_sys;<br>
<br>
+ var_Destroy( p_intf->p_libvlc, "key-osdmessage" );<br>
+ var_DelCallback( p_intf->p_libvlc, "key-osdmessage", ActionEvent, p_intf );<br>
var_DelCallback( p_intf->p_libvlc, "key-action", ActionEvent, p_intf );<br>
<br>
/* Destroy structure */<br>
@@ -404,76 +403,21 @@ static int PutAction( intf_thread_t *p_intf, int i_action )<br>
break;<br>
<br>
case ACTIONID_SUBSYNC_MARKAUDIO:<br>
- {<br>
- p_sys->subtitle_delaybookmarks.i_time_audio = mdate();<br>
- DisplayMessage( p_vout, _("Sub sync: bookmarked audio time"));<br>
+ /* trigger callback in module subtitle.c */<br>
+ var_SetInteger(p_input, "spu-bookmarkaudio", mdate());<br>
break;<br>
- }<br>
case ACTIONID_SUBSYNC_MARKSUB:<br>
- if( p_input )<br>
- {<br>
- vlc_value_t val, list, list2;<br>
- int i_count;<br>
- var_Get( p_input, "spu-es", &val );<br>
-<br>
- var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,<br>
- &list, &list2 );<br>
- i_count = list.p_list->i_count;<br>
- if( i_count < 1 || val.i_int < 0 )<br>
- {<br>
- DisplayMessage( p_vout, _("No active subtitle") );<br>
- var_FreeList( &list, &list2 );<br>
- break;<br>
- }<br>
- p_sys->subtitle_delaybookmarks.i_time_subtitle = mdate();<br>
- DisplayMessage( p_vout,<br>
- _("Sub sync: bookmarked subtitle time"));<br>
- var_FreeList( &list, &list2 );<br>
- }<br>
+ /* trigger callback in module subtitle.c */<br>
+ var_SetInteger(p_input, "spu-bookmarksubtitle", mdate());<br>
break;<br>
case ACTIONID_SUBSYNC_APPLY:<br>
- {<br>
- /* Warning! Can yield a pause in the playback.<br>
- * For example, the following succession of actions will yield a 5 second delay :<br>
- * - Pressing Shift-H (ACTIONID_SUBSYNC_MARKAUDIO)<br>
- * - wait 5 second<br>
- * - Press Shift-J (ACTIONID_SUBSYNC_MARKSUB)<br>
- * - Press Shift-K (ACTIONID_SUBSYNC_APPLY)<br>
- * --> 5 seconds pause<br>
- * This is due to var_SetTime() (and ultimately UpdatePtsDelay())<br>
- * which causes the video to pause for an equivalent duration<br>
- * (This problem is also present in the "Track synchronization" window) */<br>
- if ( p_input )<br>
- {<br>
- if ( (p_sys->subtitle_delaybookmarks.i_time_audio == 0) || (p_sys->subtitle_delaybookmarks.i_time_subtitle == 0) )<br>
- {<br>
- DisplayMessage( p_vout, _( "Sub sync: set bookmarks first!" ) );<br>
- }<br>
- else<br>
- {<br>
- int64_t i_current_subdelay = var_GetTime( p_input, "spu-delay" );<br>
- int64_t i_additional_subdelay = p_sys->subtitle_delaybookmarks.i_time_audio - p_sys->subtitle_delaybookmarks.i_time_subtitle;<br>
- int64_t i_total_subdelay = i_current_subdelay + i_additional_subdelay;<br>
- var_SetTime( p_input, "spu-delay", i_total_subdelay);<br>
- ClearChannels( p_intf, p_vout );<br>
- DisplayMessage( p_vout, _( "Sub sync: corrected %i ms (total delay = %i ms)" ),<br>
- (int)(i_additional_subdelay / 1000),<br>
- (int)(i_total_subdelay / 1000) );<br>
- p_sys->subtitle_delaybookmarks.i_time_audio = 0;<br>
- p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;<br>
- }<br>
- }<br>
+ /* trigger callback in module subtitle.c */<br>
+ var_SetInteger(p_input, "spu-syncbookmarks", mdate());<br>
break;<br>
- }<br>
case ACTIONID_SUBSYNC_RESET:<br>
- {<br>
- var_SetTime( p_input, "spu-delay", 0);<br>
- ClearChannels( p_intf, p_vout );<br>
- DisplayMessage( p_vout, _( "Sub sync: delay reset" ) );<br>
- p_sys->subtitle_delaybookmarks.i_time_audio = 0;<br>
- p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;<br>
+ /* trigger callback in module subtitle.c */<br>
+ var_SetInteger(p_input, "spu-syncreset", mdate());<br>
break;<br>
- }<br>
<br>
case ACTIONID_SUBDELAY_DOWN:<br>
case ACTIONID_SUBDELAY_UP:<br>
@@ -1067,7 +1011,30 @@ static int ActionEvent( vlc_object_t *libvlc, char const *psz_var,<br>
(void)psz_var;<br>
(void)oldval;<br>
<br>
- return PutAction( p_intf, newval.i_int );<br>
+ if ( strcmp( psz_var, "key-osdmessage") == 0)<br>
+ {<br>
+ if ( strlen(newval.psz_string) > 0 )<br>
+ {<br>
+ playlist_t *p_playlist = pl_Get( p_intf );<br>
+ input_thread_t *p_input = playlist_CurrentInput( p_playlist );<br>
+ if (p_input)<br>
+ {<br>
+ vout_thread_t *p_vout = p_input ? input_GetVout( p_input ) : NULL;// XXXXDZFEEGVDS<br>
+ if( p_vout )<br>
+ {<br>
+ DisplayMessage(p_vout, "%s", newval.psz_string);<br>
+ vlc_object_release( p_vout );<br>
+ }<br>
+ vlc_object_release(p_input);<br>
+ }<br>
+<br>
+ }<br>
+ return VLC_SUCCESS;<br>
+ }<br>
+ else<br>
+ {<br>
+ return PutAction( p_intf, newval.i_int );<br>
+ }<br>
}<br>
<br>
static void PlayBookmark( intf_thread_t *p_intf, int i_num )<br>
diff --git a/modules/demux/subtitle.c b/modules/demux/subtitle.c<br>
index 29922cc..3ed2040 100644<br>
--- a/modules/demux/subtitle.c<br>
+++ b/modules/demux/subtitle.c<br>
@@ -35,6 +35,7 @@<br>
#include <vlc_plugin.h><br>
#include <vlc_input.h><br>
#include <vlc_memory.h><br>
+#include <vlc_interface.h><br>
<br>
#include <ctype.h><br>
<br>
@@ -127,6 +128,16 @@ static void TextUnload( text_t * );<br>
<br>
typedef struct<br>
{<br>
+ /*<br>
+ * i_start and i_stop are the original subtitle timestamps.<br>
+ *<br>
+ * In order to take into account the subtitle delay (spu-delay),<br>
+ * please use<br>
+ * adjust_subtitle_time(p_demux, my_subtitle_t.i_start)<br>
+ * instead of<br>
+ * my_subtitle_t.i_start<br>
+ * (same goes for i_stop)<br>
+ */<br>
int64_t i_start;<br>
int64_t i_stop;<br>
<br>
@@ -141,6 +152,7 @@ struct demux_sys_t<br>
es_out_id_t *es;<br>
<br>
int64_t i_next_demux_date;<br>
+ int64_t i_last_demux_date;<br>
int64_t i_microsecperframe;<br>
<br>
char *psz_header;<br>
@@ -166,6 +178,14 @@ struct demux_sys_t<br>
float f_total;<br>
float f_factor;<br>
} mpsub;<br>
+<br>
+ /*subtitle_delaybookmarks: placeholder for storing subtitle sync timestamps*/<br>
+ struct<br>
+ {<br>
+ int64_t i_time_subtitle;<br>
+ int64_t i_time_audio;<br>
+ } subtitle_delaybookmarks;<br>
+<br>
};<br>
<br>
static int ParseMicroDvd ( demux_t *, subtitle_t *, int );<br>
@@ -224,6 +244,76 @@ static int Control( demux_t *, int, va_list );<br>
<br>
static void Fix( demux_t * );<br>
static char * get_language_from_filename( const char * );<br>
+static int64_t adjust_subtitle_time( demux_t *, int64_t);<br>
+static int set_current_subtitle_by_time(demux_t *p_demux, int64_t i64_when);<br>
+<br>
+<br>
+/*****************************************************************************<br>
+ * external callbacks<br>
+ *****************************************************************************/<br>
+int subtitle_external_callback ( vlc_object_t * ,char const *, vlc_value_t old_value, vlc_value_t new_value, void * callback_data);<br>
+int subtitle_external_callback (<br>
+ vlc_object_t * object,<br>
+ char const * variable_name,<br>
+ vlc_value_t old_value,<br>
+ vlc_value_t new_value,<br>
+ void * callback_data_p_demux)<br>
+{<br>
+ demux_t *p_demux = (demux_t*)callback_data_p_demux;<br>
+ (void)object;<br>
+ (void)old_value;<br>
+ (void)new_value;<br>
+<br>
+ demux_sys_t *p_sys = p_demux->p_sys;<br>
+<br>
+ if ( ! strcmp(variable_name, "spu-bookmarkaudio") )<br>
+ {<br>
+ p_sys->subtitle_delaybookmarks.i_time_audio = p_sys->i_last_demux_date;<br>
+ var_SetString(p_demux->p_libvlc, "key-osdmessage", _("Sub sync: bookmarked audio time"));<br>
+ }<br>
+ if ( ! strcmp(variable_name, "spu-bookmarksubtitle") )<br>
+ {<br>
+ p_sys->subtitle_delaybookmarks.i_time_subtitle = p_sys->i_last_demux_date;<br>
+ var_SetString(p_demux->p_libvlc, "key-osdmessage", _("Sub sync: bookmarked subtitle time"));<br>
+ }<br>
+ if ( ! strcmp(variable_name, "spu-syncbookmarks") )<br>
+ {<br>
+ if ( (p_sys->subtitle_delaybookmarks.i_time_audio == 0) || (p_sys->subtitle_delaybookmarks.i_time_subtitle == 0) )<br>
+ {<br>
+ var_SetString(p_demux->p_libvlc, "key-osdmessage", _("Sub sync: set bookmarks first!"));<br>
+ }<br>
+ else<br>
+ {<br>
+ int64_t i_current_subdelay = var_GetTime( p_demux->p_parent, "spu-delay" );<br>
+ int64_t i_additional_subdelay = p_sys->subtitle_delaybookmarks.i_time_audio - p_sys->subtitle_delaybookmarks.i_time_subtitle;<br>
+ int64_t i_total_subdelay = i_current_subdelay + i_additional_subdelay;<br>
+ var_SetTime( p_demux->p_parent, "spu-delay", i_total_subdelay);<br>
+ char message[150];<br>
+ snprintf(message, 150,<br>
+ _( "Sub sync: corrected %i ms (total delay = %i ms)" ),<br>
+ (int)(i_additional_subdelay / 1000),<br>
+ (int)(i_total_subdelay / 1000) );<br>
+ var_SetString(p_demux->p_libvlc, "key-osdmessage", message);<br>
+ p_sys->subtitle_delaybookmarks.i_time_audio = 0;<br>
+ p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;<br>
+ }<br>
+ }<br>
+ if ( ! strcmp(variable_name, "spu-syncreset") )<br>
+ {<br>
+ var_SetTime( p_demux->p_parent, "spu-delay", 0);<br>
+ p_sys->subtitle_delaybookmarks.i_time_audio = 0;<br>
+ p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;<br>
+ var_SetString(p_demux->p_libvlc, "key-osdmessage", _("Sub sync: delay reset"));<br>
+ return VLC_SUCCESS;<br>
+ }<br>
+ if ( ! strcmp(variable_name, "spu-delau") )<br>
+ {<br>
+ set_current_subtitle_by_time(p_demux, p_sys->i_last_demux_date);<br>
+ }<br>
+ return VLC_SUCCESS;<br>
+}<br>
+<br>
+<br>
<br>
/*****************************************************************************<br>
* Module initializer<br>
@@ -249,7 +339,26 @@ static int Open ( vlc_object_t *p_this )<br>
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );<br>
if( p_sys == NULL )<br>
return VLC_ENOMEM;<br>
-<br>
+<br>
+ /* reset spu-delay at Open*/<br>
+ var_SetTime( p_demux->p_parent, "spu-delay", 0 );<br>
+<br>
+ p_sys->subtitle_delaybookmarks.i_time_audio = 0;<br>
+ p_sys->subtitle_delaybookmarks.i_time_subtitle = 0;<br>
+<br>
+<br>
+ /* Add callbacks*/<br>
+ var_Create(p_demux->p_parent, "spu-bookmarkaudio", VLC_VAR_INTEGER);<br>
+ var_Create(p_demux->p_parent, "spu-bookmarksubtitle", VLC_VAR_INTEGER);<br>
+ var_Create(p_demux->p_parent, "spu-syncbookmarks", VLC_VAR_INTEGER);<br>
+ var_Create(p_demux->p_parent, "spu-syncreset", VLC_VAR_INTEGER);<br>
+ var_AddCallback( p_demux->p_parent, "spu-bookmarkaudio", &subtitle_external_callback, p_this );<br>
+ var_AddCallback( p_demux->p_parent, "spu-bookmarksubtitle", &subtitle_external_callback, p_this );<br>
+ var_AddCallback( p_demux->p_parent, "spu-syncbookmarks", &subtitle_external_callback, p_this );<br>
+ var_AddCallback( p_demux->p_parent, "spu-syncreset", &subtitle_external_callback, p_this );<br>
+ var_AddCallback( p_demux->p_parent, "spu-delay", &subtitle_external_callback, p_this );<br>
+<br>
+<br>
p_sys->psz_header = NULL;<br>
p_sys->i_subtitle = 0;<br>
p_sys->i_subtitles = 0;<br>
@@ -579,8 +688,21 @@ static void Close( vlc_object_t *p_this )<br>
{<br>
demux_t *p_demux = (demux_t*)p_this;<br>
demux_sys_t *p_sys = p_demux->p_sys;<br>
- int i;<br>
<br>
+ /* Remove callbacks*/<br>
+ var_DelCallback( p_demux->p_parent, "spu-bookmarkaudio", &subtitle_external_callback, p_this );<br>
+ var_DelCallback( p_demux->p_parent, "spu-bookmarksubtitle", &subtitle_external_callback, p_this );<br>
+ var_DelCallback( p_demux->p_parent, "spu-syncbookmarks", &subtitle_external_callback, p_this );<br>
+ var_DelCallback( p_demux->p_parent, "spu-syncreset", &subtitle_external_callback, p_this );<br>
+<br>
+ var_DelCallback( p_demux->p_parent, "spu-delay", &subtitle_external_callback, p_this );<br>
+ var_Destroy(p_demux->p_parent, "spu-bookmarkaudio");<br>
+ var_Destroy(p_demux->p_parent, "spu-bookmarksubtitle");<br>
+ var_Destroy(p_demux->p_parent, "spu-syncbookmarks");<br>
+ var_Destroy(p_demux->p_parent, "spu-syncreset");<br>
+<br>
+<br>
+ int i;<br>
for( i = 0; i < p_sys->i_subtitles; i++ )<br>
free( p_sys->subtitle[i].psz_text );<br>
free( p_sys->subtitle );<br>
@@ -591,6 +713,31 @@ static void Close( vlc_object_t *p_this )<br>
/*****************************************************************************<br>
* Control:<br>
*****************************************************************************/<br>
+<br>
+/* Utlity function : sets the current subtitle index (p_sys->i_subtitle)<br>
+ * based on the time<br>
+ */<br>
+static int set_current_subtitle_by_time(demux_t *p_demux, int64_t i64_when)<br>
+{<br>
+ demux_sys_t *p_sys = p_demux->p_sys;<br>
+<br>
+ p_sys->i_subtitle = 0;<br>
+ while( p_sys->i_subtitle < p_sys->i_subtitles )<br>
+ {<br>
+ const subtitle_t *p_subtitle = &p_sys->subtitle[p_sys->i_subtitle];<br>
+ if( adjust_subtitle_time(p_demux, p_subtitle->i_start) > i64_when )<br>
+ break;<br>
+ if( p_subtitle->i_stop > p_subtitle->i_start && adjust_subtitle_time(p_demux, p_subtitle->i_stop) > i64_when )<br>
+ break;<br>
+<br>
+ p_sys->i_subtitle++;<br>
+ }<br>
+<br>
+ if( p_sys->i_subtitle >= p_sys->i_subtitles )<br>
+ return VLC_EGENERIC;<br>
+ return VLC_SUCCESS;<br>
+}<br>
+<br>
static int Control( demux_t *p_demux, int i_query, va_list args )<br>
{<br>
demux_sys_t *p_sys = p_demux->p_sys;<br>
@@ -608,29 +755,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )<br>
pi64 = (int64_t*)va_arg( args, int64_t * );<br>
if( p_sys->i_subtitle < p_sys->i_subtitles )<br>
{<br>
- *pi64 = p_sys->subtitle[p_sys->i_subtitle].i_start;<br>
+ *pi64 = adjust_subtitle_time(p_demux, p_sys->subtitle[p_sys->i_subtitle].i_start);<br>
return VLC_SUCCESS;<br>
}<br>
return VLC_EGENERIC;<br>
<br>
case DEMUX_SET_TIME:<br>
i64 = (int64_t)va_arg( args, int64_t );<br>
- p_sys->i_subtitle = 0;<br>
- while( p_sys->i_subtitle < p_sys->i_subtitles )<br>
- {<br>
- const subtitle_t *p_subtitle = &p_sys->subtitle[p_sys->i_subtitle];<br>
-<br>
- if( p_subtitle->i_start > i64 )<br>
- break;<br>
- if( p_subtitle->i_stop > p_subtitle->i_start && p_subtitle->i_stop > i64 )<br>
- break;<br>
-<br>
- p_sys->i_subtitle++;<br>
- }<br>
-<br>
- if( p_sys->i_subtitle >= p_sys->i_subtitles )<br>
- return VLC_EGENERIC;<br>
- return VLC_SUCCESS;<br>
+ return set_current_subtitle_by_time(p_demux, i64);<br>
<br>
case DEMUX_GET_POSITION:<br>
pf = (double*)va_arg( args, double * );<br>
@@ -640,7 +772,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )<br>
}<br>
else if( p_sys->i_subtitles > 0 )<br>
{<br>
- *pf = (double)p_sys->subtitle[p_sys->i_subtitle].i_start /<br>
+ int64_t i_start_adjust = adjust_subtitle_time(p_demux, p_sys->subtitle[p_sys->i_subtitle].i_start);<br>
+ *pf = (double) ( i_start_adjust ) /<br>
(double)p_sys->i_length;<br>
}<br>
else<br>
@@ -655,7 +788,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )<br>
<br>
p_sys->i_subtitle = 0;<br>
while( p_sys->i_subtitle < p_sys->i_subtitles &&<br>
- p_sys->subtitle[p_sys->i_subtitle].i_start < i64 )<br>
+ adjust_subtitle_time(p_demux, p_sys->subtitle[p_sys->i_subtitle].i_start) < i64 )<br>
{<br>
p_sys->i_subtitle++;<br>
}<br>
@@ -682,6 +815,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )<br>
}<br>
}<br>
<br>
+<br>
/*****************************************************************************<br>
* Demux: Send subtitle to decoder<br>
*****************************************************************************/<br>
@@ -693,15 +827,15 @@ static int Demux( demux_t *p_demux )<br>
if( p_sys->i_subtitle >= p_sys->i_subtitles )<br>
return 0;<br>
<br>
- i_maxdate = p_sys->i_next_demux_date - var_GetTime( p_demux->p_parent, "spu-delay" );;<br>
+ i_maxdate = p_sys->i_next_demux_date;<br>
if( i_maxdate <= 0 && p_sys->i_subtitle < p_sys->i_subtitles )<br>
{<br>
/* Should not happen */<br>
- i_maxdate = p_sys->subtitle[p_sys->i_subtitle].i_start + 1;<br>
+ i_maxdate = adjust_subtitle_time(p_demux, p_sys->subtitle[p_sys->i_subtitle].i_start) + 1;<br>
}<br>
-<br>
+<br>
while( p_sys->i_subtitle < p_sys->i_subtitles &&<br>
- p_sys->subtitle[p_sys->i_subtitle].i_start < i_maxdate )<br>
+ adjust_subtitle_time(p_demux, p_sys->subtitle[p_sys->i_subtitle].i_start) < i_maxdate )<br>
{<br>
const subtitle_t *p_subtitle = &p_sys->subtitle[p_sys->i_subtitle];<br>
<br>
@@ -721,9 +855,9 @@ static int Demux( demux_t *p_demux )<br>
}<br>
<br>
p_block->i_dts =<br>
- p_block->i_pts = VLC_TS_0 + p_subtitle->i_start;<br>
+ p_block->i_pts = VLC_TS_0 + adjust_subtitle_time(p_demux, p_subtitle->i_start);<br>
if( p_subtitle->i_stop >= 0 && p_subtitle->i_stop >= p_subtitle->i_start )<br>
- p_block->i_length = p_subtitle->i_stop - p_subtitle->i_start;<br>
+ p_block->i_length = adjust_subtitle_time(p_demux, p_subtitle->i_stop) - adjust_subtitle_time(p_demux, p_subtitle->i_start);<br>
<br>
memcpy( p_block->p_buffer, p_subtitle->psz_text, i_len );<br>
<br>
@@ -733,11 +867,28 @@ static int Demux( demux_t *p_demux )<br>
}<br>
<br>
/* */<br>
+ p_sys->i_last_demux_date = p_sys->i_next_demux_date;<br>
p_sys->i_next_demux_date = 0;<br>
<br>
return 1;<br>
}<br>
<br>
+<br>
+/*****************************************************************************<br>
+ * adjust_subtitle_time : receives a subtitle timestamp as input<br>
+ * (p_subtitle->i_start or p_subtitle->i_stop)<br>
+ * and returns that timestamp corrected<br>
+ * by spu-delay<br>
+ *****************************************************************************/<br>
+static int64_t adjust_subtitle_time( demux_t * p_demux, int64_t i64_when)<br>
+{<br>
+ int64_t spu_delay = var_GetTime( p_demux->p_parent, "spu-delay" );<br>
+ int64_t i64_adjust = i64_when + spu_delay;<br>
+ return i64_adjust;<br>
+}<br>
+<br>
+<br>
+<br>
/*****************************************************************************<br>
* Fix: fix time stamp and order of subtitle<br>
*****************************************************************************/<br>
diff --git a/modules/gui/macosx/TrackSynchronization.m b/modules/gui/macosx/TrackSynchronization.m<br>
index c0b8f3c..a5ddce3 100644<br>
--- a/modules/gui/macosx/TrackSynchronization.m<br>
+++ b/modules/gui/macosx/TrackSynchronization.m<br>
@@ -65,7 +65,22 @@ static VLCTrackSynchronization *_o_sharedInstance = nil;<br>
[o_sv_lbl setStringValue: _NS("Subtitles/Video")];<br>
[o_sv_advance_lbl setStringValue: _NS("Subtitle track synchronization:")];<br>
[[o_sv_advance_value_fld formatter] setFormat:[NSString stringWithFormat:@"#,##0.000 %@", _NS("s")]];<br>
- [o_sv_advance_value_fld setToolTip: _NS("A positive value means that the subtitles are ahead of the video")];<br>
+ [o_sv_advance_value_fld setToolTip:<br>
+ _NS(<br>
+ "A positive value means that the subtitles are ahead of the video\n"<br>
+ "\n"\<br>
+ "In order to set the subtitle track synchronization delay easily, \n"\<br>
+ "you can use the hotkeys :\n"\<br>
+ "\n"\<br>
+ "* Shift-H (audio bookmark)\n"\<br>
+ "* Shift-J (subtitle bookmark) \n"\<br>
+ "* Shift-K (sync bookmarks)\n"\<br>
+ "\n"\<br>
+ "(Command-Shift-K resets the delay)\n"\<br>
+ "\n"\<br>
+ "(Use these hotkeys directly on the video)\n"<br>
+ )<br>
+ ];<br>
[o_sv_speed_lbl setStringValue: _NS("Subtitle speed:")];<br>
[[o_sv_speed_value_fld formatter] setFormat:[NSString stringWithFormat:@"#,##0.000 %@", _NS("fps")]];<br>
[o_sv_dur_lbl setStringValue: _NS("Subtitle duration factor:")];<br>
diff --git a/modules/gui/macosx/intf.m b/modules/gui/macosx/intf.m<br>
index 8f46abb..26b6675 100644<br>
--- a/modules/gui/macosx/intf.m<br>
+++ b/modules/gui/macosx/intf.m<br>
@@ -358,7 +358,6 @@ static int InputEvent(vlc_object_t *p_this, const char *psz_var,<br>
break;<br>
<br>
case INPUT_EVENT_AUDIO_DELAY:<br>
- case INPUT_EVENT_SUBTITLE_DELAY:<br>
[[VLCMain sharedInstance] performSelectorOnMainThread:@selector(updateDelays) withObject:nil waitUntilDone:NO];<br>
break;<br>
<br>
diff --git a/modules/gui/qt4/components/extended_panels.cpp b/modules/gui/qt4/components/extended_panels.cpp<br>
index 84d16ae..4dd0f7d 100644<br>
--- a/modules/gui/qt4/components/extended_panels.cpp<br>
+++ b/modules/gui/qt4/components/extended_panels.cpp<br>
@@ -1475,7 +1475,21 @@ SyncControls::SyncControls( intf_thread_t *_p_intf, QWidget *_parent ) :<br>
<br>
subsSpin = new SyncWidget( this );<br>
subsLayout->addWidget( subsSpin, 0, 2, 1, 1 );<br>
-<br>
+ QString subsSpin_Tooltip = qtr(<br>
+ "In order to set the subtitle track synchronization delay easily, \n"\<br>
+ "you can use the hotkeys :\n"\<br>
+ "\n"\<br>
+ "* Shift-H (audio bookmark)\n"\<br>
+ "* Shift-J (subtitle bookmark) \n"\<br>
+ "* Shift-K (sync bookmarks)\n"\<br>
+ "\n"\<br>
+ "(Ctrl-Shift-K resets the delay)\n"\<br>
+ "\n"\<br>
+ "(Use these hotkeys directly on the video)\n"<br>
+ );<br>
+ subsSpin->setToolTip(subsSpin_Tooltip);<br>
+ subsLabel->setToolTip(subsSpin_Tooltip);<br>
+<br>
QLabel *subSpeedLabel = new QLabel;<br>
subSpeedLabel->setText( qtr( "Subtitle speed:" ) );<br>
subsLayout->addWidget( subSpeedLabel, 1, 0, 1, 1 );<br>
diff --git a/modules/gui/qt4/input_manager.cpp b/modules/gui/qt4/input_manager.cpp<br>
index c07f712..ef9ec66 100644<br>
--- a/modules/gui/qt4/input_manager.cpp<br>
+++ b/modules/gui/qt4/input_manager.cpp<br>
@@ -377,7 +377,6 @@ static int InputEvent( vlc_object_t *p_this, const char *,<br>
break;<br>
<br>
case INPUT_EVENT_AUDIO_DELAY:<br>
- case INPUT_EVENT_SUBTITLE_DELAY:<br>
event = new IMEvent( IMEvent::SynchroChanged );<br>
break;<br>
<br>
diff --git a/src/input/event.c b/src/input/event.c<br>
index 453e04b..f4ca0d6 100644<br>
--- a/src/input/event.c<br>
+++ b/src/input/event.c<br>
@@ -112,16 +112,6 @@ void input_SendEventAudioDelay( input_thread_t *p_input, mtime_t i_delay )<br>
Trigger( p_input, INPUT_EVENT_AUDIO_DELAY );<br>
}<br>
<br>
-void input_SendEventSubtitleDelay( input_thread_t *p_input, mtime_t i_delay )<br>
-{<br>
- vlc_value_t val;<br>
-<br>
- val.i_time = i_delay;<br>
- var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );<br>
-<br>
- Trigger( p_input, INPUT_EVENT_SUBTITLE_DELAY );<br>
-}<br>
-<br>
/* TODO and file name ? */<br>
void input_SendEventRecord( input_thread_t *p_input, bool b_recording )<br>
{<br>
diff --git a/src/input/event.h b/src/input/event.h<br>
index c8f1071..b3c4b56 100644<br>
--- a/src/input/event.h<br>
+++ b/src/input/event.h<br>
@@ -36,7 +36,6 @@ void input_SendEventLength( input_thread_t *p_input, mtime_t i_length );<br>
void input_SendEventStatistics( input_thread_t *p_input );<br>
void input_SendEventRate( input_thread_t *p_input, int i_rate );<br>
void input_SendEventAudioDelay( input_thread_t *p_input, mtime_t i_delay );<br>
-void input_SendEventSubtitleDelay( input_thread_t *p_input, mtime_t i_delay );<br>
void input_SendEventRecord( input_thread_t *p_input, bool b_recording );<br>
void input_SendEventTitle( input_thread_t *p_input, int i_title );<br>
void input_SendEventSeekpoint( input_thread_t *p_input, int i_title, int i_seekpoint );<br>
diff --git a/src/input/input.c b/src/input/input.c<br>
index 7e71d4e..6d4bc4a 100644<br>
--- a/src/input/input.c<br>
+++ b/src/input/input.c<br>
@@ -1102,8 +1102,7 @@ static void UpdatePtsDelay( input_thread_t *p_input )<br>
<br>
/* Take care of audio/spu delay */<br>
const mtime_t i_audio_delay = var_GetTime( p_input, "audio-delay" );<br>
- const mtime_t i_spu_delay = var_GetTime( p_input, "spu-delay" );<br>
- const mtime_t i_extra_delay = __MIN( i_audio_delay, i_spu_delay );<br>
+ const mtime_t i_extra_delay = i_audio_delay;<br>
if( i_extra_delay < 0 )<br>
i_pts_delay -= i_extra_delay;<br>
<br>
@@ -1112,7 +1111,6 @@ static void UpdatePtsDelay( input_thread_t *p_input )<br>
<br>
/* */<br>
es_out_SetDelay( p_input->p->p_es_out_display, AUDIO_ES, i_audio_delay );<br>
- es_out_SetDelay( p_input->p->p_es_out_display, SPU_ES, i_spu_delay );<br>
es_out_SetJitter( p_input->p->p_es_out, i_pts_delay, 0, i_cr_average );<br>
}<br>
<br>
@@ -1871,12 +1869,6 @@ static bool Control( input_thread_t *p_input,<br>
input_SendEventAudioDelay( p_input, val.i_time );<br>
UpdatePtsDelay( p_input );<br>
break;<br>
-<br>
- case INPUT_CONTROL_SET_SPU_DELAY:<br>
- input_SendEventSubtitleDelay( p_input, val.i_time );<br>
- UpdatePtsDelay( p_input );<br>
- break;<br>
-<br>
case INPUT_CONTROL_SET_TITLE:<br>
case INPUT_CONTROL_SET_TITLE_NEXT:<br>
case INPUT_CONTROL_SET_TITLE_PREV:<br>
diff --git a/src/input/input_internal.h b/src/input/input_internal.h<br>
index 9f71294..9e534d9 100644<br>
--- a/src/input/input_internal.h<br>
+++ b/src/input/input_internal.h<br>
@@ -202,7 +202,6 @@ enum input_control_e<br>
INPUT_CONTROL_RESTART_ES,<br>
<br>
INPUT_CONTROL_SET_AUDIO_DELAY,<br>
- INPUT_CONTROL_SET_SPU_DELAY,<br>
<br>
INPUT_CONTROL_ADD_SLAVE,<br>
<br>
diff --git a/src/input/var.c b/src/input/var.c<br>
index 3e722f4..293babd 100644<br>
--- a/src/input/var.c<br>
+++ b/src/input/var.c<br>
@@ -97,7 +97,6 @@ static const vlc_input_callback_t p_input_callbacks[] =<br>
CALLBACK( "title", TitleCallback ),<br>
CALLBACK( "chapter", SeekpointCallback ),<br>
CALLBACK( "audio-delay", EsDelayCallback ),<br>
- CALLBACK( "spu-delay", EsDelayCallback ),<br>
CALLBACK( "video-es", ESCallback ),<br>
CALLBACK( "audio-es", ESCallback ),<br>
CALLBACK( "spu-es", ESCallback ),<br>
@@ -787,10 +786,6 @@ static int EsDelayCallback ( vlc_object_t *p_this, char const *psz_cmd,<br>
{<br>
input_ControlPush( p_input, INPUT_CONTROL_SET_AUDIO_DELAY, &newval );<br>
}<br>
- else if( !strcmp( psz_cmd, "spu-delay" ) )<br>
- {<br>
- input_ControlPush( p_input, INPUT_CONTROL_SET_SPU_DELAY, &newval );<br>
- }<br>
return VLC_SUCCESS;<br>
}<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
1.9.1<br>
<br>
_______________________________________________<br>
vlc-devel mailing list<br>
To unsubscribe or modify your subscription options:<br>
<a href="https://mailman.videolan.org/listinfo/vlc-devel" target="_blank">https://mailman.videolan.org/listinfo/vlc-devel</a><br>
</font></span></blockquote></div><br><br clear="all"><br>-- <br>Félix Abecassis<div><a href="http://felix.abecassis.me" target="_blank">http://felix.abecassis.me</a></div>
</div>