[vlc-devel] [PATCH 04/10] Add additional SPU clock to synchronize secondary subtitles

Thomas Guillem thomas at gllm.fr
Mon May 6 09:36:09 CEST 2019


Hello,

On Sun, May 5, 2019, at 12:03, Roland Bewick wrote:
> ---
>  src/input/decoder.c                 | 15 ++++++---
>  src/video_output/video_output.c     | 17 ++++++----
>  src/video_output/vout_internal.h    | 14 ++++----
>  src/video_output/vout_subpictures.c | 50 +++++++++++++++++------------
>  4 files changed, 59 insertions(+), 37 deletions(-)
> 
> diff --git a/src/input/decoder.c b/src/input/decoder.c
> index b5fe1c2ca3..b699e52a67 100644
> --- a/src/input/decoder.c
> +++ b/src/input/decoder.c
> @@ -612,7 +612,8 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec,
>          if( p_owner->p_vout )
>          {
>              vlc_mutex_lock( &p_owner->lock );
> -            vout_SetSubpictureClock(p_owner->p_vout, NULL);
> +            vout_SetSubpictureClock(p_owner->p_vout, NULL,
> +                                    p_owner->b_secondary);

I would prefer something like
 int vout_AddSubpictureClock(vlc_clock_t *);
 void vout_RemoveSubpictureClock(vlc_clock_t *),

We won't have to change if we need to handle 3 SPUS. The vout can just keep an array of 2 clocks and return an error if it receive a third vout_AddSubpictureClock().

>              vout_Release(p_owner->p_vout);
>              p_owner->p_vout = NULL;
>              vlc_mutex_unlock( &p_owner->lock );
> @@ -628,13 +629,15 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec,
>          vlc_mutex_lock( &p_owner->lock );
>          if( p_owner->p_vout )
>          {
> -            vout_SetSubpictureClock(p_owner->p_vout, NULL);
> +            vout_SetSubpictureClock(p_owner->p_vout, NULL,
> +                                    p_owner->b_secondary);
>              vout_Release(p_owner->p_vout);
>          }
>          p_owner->p_vout = p_vout;
>          vlc_mutex_unlock( &p_owner->lock );
>  
> -        vout_SetSubpictureClock( p_vout, p_owner->p_clock );
> +        vout_SetSubpictureClock( p_vout, p_owner->p_clock,
> +                                 p_owner->b_secondary);
>      }
>      else
>          vout_Release(p_vout);
> @@ -1556,7 +1559,8 @@ static void OutputChangeDelay( decoder_t *p_dec, 
> vlc_tick_t delay )
>              break;
>          case SPU_ES:
>              if( p_owner->p_vout != NULL )
> -                vout_ChangeSpuDelay( p_owner->p_vout, delay );
> +                vout_ChangeSpuDelay( p_owner->p_vout, delay,
> +                                     p_owner->b_secondary );
>              break;
>          default:
>              vlc_assert_unreachable();
> @@ -1973,7 +1977,8 @@ static void DeleteDecoder( decoder_t * p_dec )
>              {
>                  vout_FlushSubpictureChannel( p_owner->p_vout,
>                                               p_owner->i_spu_channel );
> -                vout_SetSubpictureClock(p_owner->p_vout, NULL);
> +                vout_SetSubpictureClock(p_owner->p_vout, NULL,
> +                                        p_owner->b_secondary);
>                  vout_Release(p_owner->p_vout);
>              }
>              break;
> diff --git a/src/video_output/video_output.c 
> b/src/video_output/video_output.c
> index b64c35bdec..23ab21b536 100644
> --- a/src/video_output/video_output.c
> +++ b/src/video_output/video_output.c
> @@ -272,11 +272,12 @@ int vout_RegisterSubpictureChannel( vout_thread_t 
> *vout )
>      return channel;
>  }
>  
> -void vout_SetSubpictureClock( vout_thread_t *vout, vlc_clock_t *clock )
> +void vout_SetSubpictureClock( vout_thread_t *vout, vlc_clock_t *clock,
> +                              bool b_secondary )
>  {
>      vlc_mutex_lock(&vout->p->spu_lock);
>      if (vout->p->spu)
> -        spu_clock_Set(vout->p->spu, clock);
> +        spu_clock_Set(vout->p->spu, clock, b_secondary);
>      vlc_mutex_unlock(&vout->p->spu_lock);
>  }
>  
> @@ -1278,8 +1279,11 @@ static void vout_FlushUnlocked(vout_thread_t 
> *vout, bool below,
>      vlc_mutex_lock(&vout->p->spu_lock);
>      if (vout->p->spu)
>      {
> -        spu_clock_Reset(vout->p->spu);
> -        spu_clock_SetDelay(vout->p->spu, vout->p->spu_delay);
> +        for (int i = 0; i < 2; i++)
> +        {
> +            spu_clock_Reset(vout->p->spu, i);
> +            spu_clock_SetDelay(vout->p->spu, vout->p->spu_delay, i);
> +        }
>      }
>      vlc_mutex_unlock(&vout->p->spu_lock);
>  }
> @@ -1335,11 +1339,12 @@ void vout_ChangeRate(vout_thread_t *vout, float 
> rate)
>      vout_control_Release(&sys->control);
>  }
>  
> -void vout_ChangeSpuDelay(vout_thread_t *vout, vlc_tick_t delay)
> +void vout_ChangeSpuDelay(vout_thread_t *vout, vlc_tick_t delay,
> +                         bool b_secondary)
>  {
>      vlc_mutex_lock(&vout->p->spu_lock);
>      if (vout->p->spu)
> -        spu_clock_SetDelay(vout->p->spu, delay);
> +        spu_clock_SetDelay(vout->p->spu, delay, b_secondary);
>      vout->p->spu_delay = delay;
>      vlc_mutex_unlock(&vout->p->spu_lock);
>  }
> diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
> index 295c35d61c..43ad5e83b2 100644
> --- a/src/video_output/vout_internal.h
> +++ b/src/video_output/vout_internal.h
> @@ -252,13 +252,14 @@ int vout_OpenWrapper(vout_thread_t *, const char *,
>  void vout_CloseWrapper(vout_thread_t *);
>  
>  /* */
> -void vout_SetSubpictureClock(vout_thread_t *vout, vlc_clock_t *clock);
> +void vout_SetSubpictureClock(vout_thread_t *vout, vlc_clock_t *clock,
> +                             bool b_secondary);
>  int spu_ProcessMouse(spu_t *, const vlc_mouse_t *, const video_format_t *);
>  void spu_Attach( spu_t *, input_thread_t *input );
>  void spu_Detach( spu_t * );
> -void spu_clock_Set(spu_t *, vlc_clock_t *);
> -void spu_clock_Reset(spu_t *);
> -void spu_clock_SetDelay(spu_t *spu, vlc_tick_t delay);
> +void spu_clock_Set(spu_t *, vlc_clock_t *, bool b_secondary);
> +void spu_clock_Reset(spu_t *, bool b_secondary);
> +void spu_clock_SetDelay(spu_t *spu, vlc_tick_t delay, bool b_secondary);
>  void spu_ChangeMargin(spu_t *, int);
>  void spu_SetHighlight(spu_t *, const vlc_spu_highlight_t*);
>  
> @@ -286,10 +287,11 @@ void vout_ChangeDelay( vout_thread_t *, 
> vlc_tick_t delay );
>   */
>  void vout_ChangeSpuRate( vout_thread_t *, float rate );
>  /**
> - * This function will change the delay of the spu channel
> + * This function will change the delay of the primary or secondary spu 
> channel
>   * It is thread safe
>   */
> -void vout_ChangeSpuDelay( vout_thread_t *, vlc_tick_t delay );
> +void vout_ChangeSpuDelay( vout_thread_t *, vlc_tick_t delay,
> +                          bool b_secondary );
>  
>  
>  /**
> diff --git a/src/video_output/vout_subpictures.c 
> b/src/video_output/vout_subpictures.c
> index 742a93cf14..86f7496442 100644
> --- a/src/video_output/vout_subpictures.c
> +++ b/src/video_output/vout_subpictures.c
> @@ -72,7 +72,7 @@ struct spu_private_t {
>      vlc_mutex_t  lock;            /* lock to protect all followings 
> fields */
>      input_thread_t *input;
>  
> -    vlc_clock_t *clock;
> +    vlc_clock_t *clocks[2];  /* clocks for primary and secondary subtitles */
>  
>      spu_heap_t   heap;
>  
> @@ -541,10 +541,14 @@ static int SpuConvertDates(spu_t *spu, vlc_tick_t 
> system_now,
>  {
>      spu_private_t *sys = spu->p;
>  
> -    /* Put every spu start and stop ts into the same array to convert 
> them in
> -     * one shot */
> -    vlc_tick_t date_array[VOUT_MAX_SUBPICTURES *2];
> +    /* Put every spu start and stop ts into an array based on which 
> +     * clock the spu entry belongs to.
> +     * All start and stop times can then be converted together
> +     * with a maximum of two calls. */
> +    vlc_tick_t date_array[2][VOUT_MAX_SUBPICTURES *2];
>      size_t entry_count = 0;
> +    bool hasEntry[2] = {false, false};
> +
>      for (size_t index = 0; index < VOUT_MAX_SUBPICTURES; index++)
>      {
>          spu_heap_entry_t *entry = &sys->heap.entry[index];
> @@ -553,17 +557,21 @@ static int SpuConvertDates(spu_t *spu, vlc_tick_t 
> system_now,
>          if (!current)
>              continue;
>  
> -        date_array[entry_count * 2] = current->i_start;
> -        date_array[entry_count * 2 + 1] = current->i_stop;
> +        hasEntry[current->b_secondary] = true;
> +        date_array[current->b_secondary][entry_count * 2] = 
> current->i_start;
> +        date_array[current->b_secondary][entry_count * 2 + 1] = 
> current->i_stop;
>          entry_count++;
>      }
>      if (entry_count == 0)
>          return 0;
>  
>      /* Convert all spu ts */
> -    if (sys->clock)
> -        vlc_clock_ConvertArrayToSystem(sys->clock, system_now, 
> date_array,
> -                                       entry_count * 2, rate);
> +    for (int i = 0; i < 2; i++)
> +    {
> +        if (hasEntry[i] && sys->clocks[i])
> +            vlc_clock_ConvertArrayToSystem(sys->clocks[i], system_now, 
> date_array[i],
> +                                        entry_count * 2, rate);
> +    }
>  
>      /* Put back the converted ts into the output spu_render_entry_t 
> struct */
>      entry_count = 0;
> @@ -578,8 +586,10 @@ static int SpuConvertDates(spu_t *spu, vlc_tick_t 
> system_now,
>          else
>          {
>              render_entry->subpicture = current;
> -            render_entry->start = date_array[entry_count * 2];
> -            render_entry->stop = date_array[entry_count * 2 + 1];
> +            render_entry->start =
> +                date_array[current->b_secondary][entry_count * 2];
> +            render_entry->stop =
> +                date_array[current->b_secondary][entry_count * 2 + 1];
>              entry_count++;
>          }
>      }
> @@ -1397,7 +1407,7 @@ spu_t *spu_Create(vlc_object_t *object, 
> vout_thread_t *vout)
>  
>      SpuHeapInit(&sys->heap);
>  
> -    sys->clock = NULL;
> +    sys->clocks[0] = sys->clocks[1] = NULL;
>      sys->text = NULL;
>      sys->scale = NULL;
>      sys->scale_yuvp = NULL;
> @@ -1507,21 +1517,21 @@ void spu_Detach(spu_t *spu)
>      vlc_mutex_unlock(&spu->p->lock);
>  }
>  
> -void spu_clock_Set(spu_t *spu, vlc_clock_t *clock)
> +void spu_clock_Set(spu_t *spu, vlc_clock_t *clock, bool b_secondary)
>  {
> -    spu->p->clock = clock;
> +    spu->p->clocks[b_secondary] = clock;
>  }
>  
> -void spu_clock_Reset(spu_t *spu)
> +void spu_clock_Reset(spu_t *spu, bool b_secondary)
>  {
> -    if (spu->p->clock)
> -        vlc_clock_Reset(spu->p->clock);
> +    if (spu->p->clocks[b_secondary])
> +        vlc_clock_Reset(spu->p->clocks[b_secondary]);
>  }
>  
> -void spu_clock_SetDelay(spu_t *spu, vlc_tick_t delay)
> +void spu_clock_SetDelay(spu_t *spu, vlc_tick_t delay, bool b_secondary)
>  {
> -    if (spu->p->clock)
> -        vlc_clock_SetDelay(spu->p->clock, delay);
> +    if (spu->p->clocks[b_secondary])
> +        vlc_clock_SetDelay(spu->p->clocks[b_secondary], delay);
>  }
>  
>  /**
> -- 
> 2.17.1
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list