[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