[vlc-devel] [PATCH 04/10] Add additional SPU clock to synchronize secondary subtitles
Roland Bewick
roland.bewick at gmail.com
Sun May 5 12:01:44 CEST 2019
---
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);
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
More information about the vlc-devel
mailing list