<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 09 Jun 2014, at 21:26, Rémi Denis-Courmont <<a href="mailto:remi@remlab.net">remi@remlab.net</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Le lundi 9 juin 2014, 21:00:23 Pascal Thomet a écrit :<br><blockquote type="cite">@@ -1067,7 +1011,30 @@ static int ActionEvent( vlc_object_t *libvlc, char<br>const *psz_var, (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 )<br>: 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></blockquote><br>Seriously, WTH is this? That seems completely out of place.<br><br></blockquote><div>Concerning the //XXXXDZ, this is a typo. Sorry for that. </div><div>If you mean that hotkey.c shall not expose a callback that displays OSD messages, I get it.</div><div><br></div><blockquote type="cite"><blockquote type="cite"> }<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..81d0a76 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<br>timestamps*/ + 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<br>i64_when); +<br>+<br>+/**************************************************************************<br>*** + * external callbacks<br>+<br>***************************************************************************<br>**/ +int subtitle_external_callback ( vlc_object_t * ,char const *,<br>vlc_value_t old_value, vlc_value_t new_value, void * callback_data); +int<br>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, "sub-bookmarkaudio") )<br>+ {<br>+ p_sys->subtitle_delaybookmarks.i_time_audio =<br>p_sys->i_last_demux_date;<br>+ var_SetString(p_demux->p_libvlc,<br>"key-osdmessage", _("Sub sync: bookmarked audio time"));<br>+ }<br>+ if ( ! strcmp(variable_name, "sub-bookmarksubtitle") )<br>+ {<br>+ p_sys->subtitle_delaybookmarks.i_time_subtitle =<br>p_sys->i_last_demux_date; + var_SetString(p_demux->p_libvlc,<br>"key-osdmessage", _("Sub sync: bookmarked subtitle time")); + }<br>+ if ( ! strcmp(variable_name, "sub-syncbookmarks") )<br>+ {<br>+ if ( (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:<br>set bookmarks first!")); + }<br>+ else<br>+ {<br>+ int64_t i_current_subdelay = var_GetTime( p_demux->p_parent,<br>"spu-delay" ); + int64_t i_additional_subdelay =<br>p_sys->subtitle_delaybookmarks.i_time_audio -<br>p_sys->subtitle_delaybookmarks.i_time_subtitle; + int64_t<br>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, "sub-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:<br>delay reset")); + 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></blockquote><br>Demuxer accessing libvlc cannot be right. </blockquote><div><br></div><div>Would it be better to store/access vars in p_demux->p_parent ? (i.e. var_SetString(p_demux->p_libvlc, …) </div><br><blockquote type="cite">Also memory accesses seem to violate <br>the concurrency model.<br></blockquote><div><br></div><div>???</div><div><br></div><br><blockquote type="cite"><br><blockquote type="cite"><br> /**************************************************************************<br>*** * Module initializer<br>@@ -249,7 +339,29 @@ 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>+ /* this is a file subtitle*/<br>+ var_SetInteger(p_demux->p_parent, "sub-isfilesub", 1);<br>+<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, "sub-bookmarkaudio", VLC_VAR_INTEGER);<br>+ var_Create(p_demux->p_parent, "sub-bookmarksubtitle", VLC_VAR_INTEGER);<br>+ var_Create(p_demux->p_parent, "sub-syncbookmarks", VLC_VAR_INTEGER); +<br> var_Create(p_demux->p_parent, "sub-syncreset", VLC_VAR_INTEGER); + <br>var_AddCallback( p_demux->p_parent, "sub-bookmarkaudio",<br>&subtitle_external_callback, p_this );<br>+ var_AddCallback(<br>p_demux->p_parent, "sub-bookmarksubtitle", &subtitle_external_callback,<br>p_this );<br>+ var_AddCallback( p_demux->p_parent, "sub-syncbookmarks",<br>&subtitle_external_callback, p_this );<br>+ var_AddCallback(<br>p_demux->p_parent, "sub-syncreset", &subtitle_external_callback, p_this );<br>+ var_AddCallback( p_demux->p_parent, "spu-delay",<br>&subtitle_external_callback, p_this );<br>+<br>+<br></blockquote><br>Hell no. That's not how the demuxer interface works.<br></blockquote><div><br></div><div><div>Any chance someone could provide some hints about how the demuxer is supposed to work?</div><div>The videolan wiki is not helpful about all these architecture aspects. How is someone supposed to get it?</div><div>The only document that I found gives which some hints on the architecture is not located on the wiki, but at : </div><div><a href="http://www.enjoythearchitecture.com/vlc-architecture">http://www.enjoythearchitecture.com/vlc-architecture</a></div></div><br><blockquote type="cite"><br><blockquote type="cite"> p_sys->psz_header = NULL;<br> p_sys->i_subtitle = 0;<br> p_sys->i_subtitles = 0;<br>@@ -579,8 +691,23 @@ 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>+ var_SetInteger(p_demux->p_parent, "sub-isfilesub", 0);<br>+<br>+ /* Remove callbacks*/<br>+ var_DelCallback( p_demux->p_parent, "sub-bookmarkaudio",<br>&subtitle_external_callback, p_this ); + var_DelCallback(<br>p_demux->p_parent, "sub-bookmarksubtitle", &subtitle_external_callback,<br>p_this ); + var_DelCallback( p_demux->p_parent, "sub-syncbookmarks",<br>&subtitle_external_callback, p_this ); + var_DelCallback(<br>p_demux->p_parent, "sub-syncreset", &subtitle_external_callback, p_this );<br>+<br>+ var_DelCallback( p_demux->p_parent, "spu-delay",<br>&subtitle_external_callback, p_this ); + var_Destroy(p_demux->p_parent,<br>"sub-bookmarkaudio");<br>+ var_Destroy(p_demux->p_parent, "sub-bookmarksubtitle");<br>+ var_Destroy(p_demux->p_parent, "sub-syncbookmarks");<br>+ var_Destroy(p_demux->p_parent, "sub-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 +718,31 @@ static void Close( vlc_object_t *p_this )<br> /**************************************************************************<br>*** * Control:<br><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 &&<br>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 +760,14 @@ static int Control( demux_t *p_demux, int i_query,<br>va_list args ) 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,<br>p_sys->subtitle[p_sys->i_subtitle].i_start); 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 =<br>&p_sys->subtitle[p_sys->i_subtitle]; -<br>- if( p_subtitle->i_start > i64 )<br>- break;<br>- if( p_subtitle->i_stop > p_subtitle->i_start &&<br>p_subtitle->i_stop > i64 ) - 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 +777,8 @@ static int Control( demux_t *p_demux, int i_query,<br>va_list args ) }<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,<br>p_sys->subtitle[p_sys->i_subtitle].i_start); + *pf =<br>(double) ( i_start_adjust ) /<br> (double)p_sys->i_length;<br> }<br> else<br>@@ -655,7 +793,7 @@ static int Control( demux_t *p_demux, int i_query,<br>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,<br>p_sys->subtitle[p_sys->i_subtitle].i_start) < i64 ) {<br> p_sys->i_subtitle++;<br> }<br>@@ -693,15 +831,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,<br>"spu-delay" );; + 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,<br>p_sys->subtitle[p_sys->i_subtitle].i_start) + 1; }<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,<br>p_sys->subtitle[p_sys->i_subtitle].i_start) < i_maxdate ) {<br> const subtitle_t *p_subtitle = &p_sys->subtitle[p_sys->i_subtitle];<br><br>@@ -721,9 +859,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,<br>p_subtitle->i_start); if( p_subtitle->i_stop >= 0 && p_subtitle->i_stop >=<br>p_subtitle->i_start ) - p_block->i_length = p_subtitle->i_stop -<br>p_subtitle->i_start; + p_block->i_length =<br>adjust_subtitle_time(p_demux, p_subtitle->i_stop) -<br>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 +871,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>***************************************************************************<br>**/ +static int64_t adjust_subtitle_time( demux_t * p_demux, int64_t<br>i64_when) +{<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>***************************************************************************<br>**/ diff --git a/src/input/input.c b/src/input/input.c<br>index 7e71d4e..ab34401 100644<br>--- a/src/input/input.c<br>+++ b/src/input/input.c<br>@@ -1103,7 +1103,14 @@ static void UpdatePtsDelay( input_thread_t *p_input )<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>+ int isfilesub =var_GetInteger(p_input, "sub-isfilesub");<br>+<br>+ mtime_t i_extra_delay;<br>+ if ( isfilesub )<br>+ i_extra_delay = i_audio_delay;<br>+ else<br>+ i_extra_delay = __MIN( i_audio_delay, i_spu_delay );<br>+<br> if( i_extra_delay < 0 )<br> i_pts_delay -= i_extra_delay;<br><br>diff --git a/src/input/var.c b/src/input/var.c<br>index 3e722f4..be3ef2a 100644<br>--- a/src/input/var.c<br>+++ b/src/input/var.c<br>@@ -195,6 +195,14 @@ void input_ControlVarInit ( input_thread_t *p_input )<br> val.i_time = 0;<br> var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );<br><br>+ /*sub-isfilesub will be<br>+ * - equal to 1 when the subtitle is read from a file (for example a<br>.srt file), + * - equal to 0 otherwise (for example dvd subtitles)*/<br>+ var_Create( p_input, "sub-isfilesub", VLC_VAR_INTEGER );<br>+ val.i_int = 0;<br>+ var_Change( p_input, "sub-isfilesub", VLC_VAR_SETVALUE, &val, 0 );<br>+<br>+<br> /* Video ES */<br> var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );<br>text.psz_string = _("Video Track");<br>@@ -789,7 +797,9 @@ static int EsDelayCallback ( vlc_object_t *p_this, char<br>const *psz_cmd, }<br> else if( !strcmp( psz_cmd, "spu-delay" ) )<br> {<br>- input_ControlPush( p_input, INPUT_CONTROL_SET_SPU_DELAY, &newval );<br>+ int isfilesub = var_GetInteger(p_input, "sub-isfilesub"); + <br>if ( ! isfilesub )<br>+ input_ControlPush( p_input, INPUT_CONTROL_SET_SPU_DELAY,<br>&newval ); }<br> return VLC_SUCCESS;<br> }<br></blockquote><br>-- <br>Rémi Denis-Courmont<br><a href="http://www.remlab.net/">http://www.remlab.net/</a><br><br>_______________________________________________<br>vlc-devel mailing list<br>To unsubscribe or modify your subscription options:<br>https://mailman.videolan.org/listinfo/vlc-devel<br></blockquote></div><br></body></html>