[vlc-devel] [PATCH] Subtitle delay : fixed sync problem that breaks audio under linux

Felix Abecassis felix.abecassis at gmail.com
Sat May 31 19:18:01 CEST 2014


This seems to be breaking regular subtitle delay (positive and negative)
with keys G and H.


2014-05-30 22:04 GMT+02:00 Pascal Thomet <pthomet at gmail.com>:

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



-- 
Félix Abecassis
http://felix.abecassis.me
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20140531/2c9be8f4/attachment.html>


More information about the vlc-devel mailing list