<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>