[vlc-commits] vout: spu: move clock into channels
Thomas Guillem
git at videolan.org
Tue Jun 11 07:58:51 CEST 2019
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Tue Jun 4 11:02:21 2019 +0200| [b755c331741e965e86e18a4a581f1eb30696c51d] | committer: Thomas Guillem
vout: spu: move clock into channels
This pave the way to multiple subtitles: each registered spu channel has now
its own clock.
And fixes OSD subpictures date being messed up by the decoder clock.
Fixes #22273
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b755c331741e965e86e18a4a581f1eb30696c51d
---
include/vlc_spu.h | 2 +-
modules/stream_out/transcode/video.c | 2 +-
src/input/decoder.c | 29 +++++++-------
src/video_output/video_output.c | 47 +++++++++++------------
src/video_output/vout_internal.h | 14 +++----
src/video_output/vout_subpictures.c | 74 ++++++++++++++++++++++--------------
6 files changed, 90 insertions(+), 78 deletions(-)
diff --git a/include/vlc_spu.h b/include/vlc_spu.h
index 00ef08c71d..e4fb9a7ec1 100644
--- a/include/vlc_spu.h
+++ b/include/vlc_spu.h
@@ -74,7 +74,7 @@ VLC_API void spu_PutSubpicture( spu_t *, subpicture_t * );
*/
VLC_API subpicture_t * spu_Render( spu_t *, const vlc_fourcc_t *p_chroma_list,
const video_format_t *p_fmt_dst, const video_format_t *p_fmt_src,
- vlc_tick_t system_now, vlc_tick_t pts, float rate,
+ vlc_tick_t system_now, vlc_tick_t pts,
bool ignore_osd, bool external_scale );
/**
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index ef64cf7539..9f1f72b8cf 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -378,7 +378,7 @@ static picture_t * RenderSubpictures( sout_stream_t *p_stream, sout_stream_id_sy
}
subpicture_t *p_subpic = spu_Render( id->p_spu, NULL, &fmt,
- &outfmt, vlc_tick_now(), p_pic->date, 1.f,
+ &outfmt, vlc_tick_now(), p_pic->date,
false, false );
/* Overlay subpicture */
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 563c1f08b9..3b19b51d66 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -617,7 +617,6 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec,
p_owner->i_spu_channel);
p_owner->i_spu_channel = -1;
}
- vout_SetSubpictureClock(p_owner->p_vout, NULL);
vlc_mutex_lock( &p_owner->lock );
vout_Release(p_owner->p_vout);
@@ -630,25 +629,20 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec,
if( p_owner->p_vout != p_vout )
{
ssize_t old_spu_channel = p_owner->i_spu_channel;
- p_owner->i_spu_channel = vout_RegisterSubpictureChannel( p_vout );
+ p_owner->i_spu_channel =
+ vout_RegisterSubpictureChannelInternal(p_vout, p_owner->p_clock);
p_owner->i_spu_order = 0;
if (p_owner->i_spu_channel != -1)
{
- if (p_owner->p_vout)
- {
- vout_SetSubpictureClock(p_owner->p_vout, NULL);
- if (old_spu_channel != -1)
- vout_UnregisterSubpictureChannel(p_owner->p_vout,
- old_spu_channel);
- }
+ if (p_owner->p_vout && old_spu_channel != -1)
+ vout_UnregisterSubpictureChannel(p_owner->p_vout,
+ old_spu_channel);
vlc_mutex_lock(&p_owner->lock);
if (p_owner->p_vout)
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);
}
}
else
@@ -1547,7 +1541,11 @@ static void OutputChangeRate( decoder_t *p_dec, float rate )
break;
case SPU_ES:
if( p_owner->p_vout != NULL )
- vout_ChangeSpuRate( p_owner->p_vout, rate );
+ {
+ assert(p_owner->i_spu_channel != -1);
+ vout_ChangeSpuRate(p_owner->p_vout, p_owner->i_spu_channel,
+ rate );
+ }
break;
default:
vlc_assert_unreachable();
@@ -1573,7 +1571,11 @@ 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 );
+ {
+ assert(p_owner->i_spu_channel != -1);
+ vout_ChangeSpuDelay(p_owner->p_vout, p_owner->i_spu_channel,
+ delay);
+ }
break;
default:
vlc_assert_unreachable();
@@ -1990,7 +1992,6 @@ static void DeleteDecoder( decoder_t * p_dec )
assert( p_owner->i_spu_channel > 0 );
vout_UnregisterSubpictureChannel( p_owner->p_vout,
p_owner->i_spu_channel );
- vout_SetSubpictureClock(p_owner->p_vout, NULL);
vout_Release(p_owner->p_vout);
}
break;
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 1f0a2391dd..6583511f6e 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -280,20 +280,24 @@ ssize_t vout_RegisterSubpictureChannel( vout_thread_t *vout )
return channel;
}
-void vout_UnregisterSubpictureChannel( vout_thread_t *vout, size_t channel )
+ssize_t vout_RegisterSubpictureChannelInternal(vout_thread_t *vout,
+ vlc_clock_t *clock)
{
assert(!vout->p->dummy);
+ ssize_t channel = VOUT_SPU_CHANNEL_INVALID;
if (vout->p->spu)
- spu_UnregisterChannel(vout->p->spu, channel);
+ channel = spu_RegisterChannelInternal(vout->p->spu, clock);
+
+ return channel;
}
-void vout_SetSubpictureClock( vout_thread_t *vout, vlc_clock_t *clock )
+void vout_UnregisterSubpictureChannel( vout_thread_t *vout, size_t channel )
{
assert(!vout->p->dummy);
+ assert(vout->p->spu);
vlc_mutex_lock(&vout->p->spu_lock);
- if (vout->p->spu)
- spu_clock_Set(vout->p->spu, clock);
+ spu_UnregisterChannel(vout->p->spu, channel);
vlc_mutex_unlock(&vout->p->spu_lock);
}
@@ -301,10 +305,10 @@ void vout_FlushSubpictureChannel( vout_thread_t *vout, size_t channel )
{
vout_thread_sys_t *sys = vout->p;
assert(!sys->dummy);
+ assert(sys->spu);
vlc_mutex_lock(&sys->spu_lock);
- if (sys->spu != NULL)
- spu_ClearChannel(vout->p->spu, channel);
+ spu_ClearChannel(vout->p->spu, channel);
vlc_mutex_unlock(&sys->spu_lock);
}
@@ -1081,7 +1085,7 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
subpicture_t *subpic = spu_Render(sys->spu,
subpicture_chromas, &fmt_spu_rot,
&vd->source, system_now,
- render_subtitle_date, sys->spu_rate,
+ render_subtitle_date,
do_snapshot, vd->info.can_scale_spu);
/*
* Perform rendering
@@ -1313,14 +1317,6 @@ static void vout_FlushUnlocked(vout_thread_t *vout, bool below,
vlc_clock_Reset(vout->p->clock);
vlc_clock_SetDelay(vout->p->clock, vout->p->delay);
-
- 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);
- }
- vlc_mutex_unlock(&vout->p->spu_lock);
}
void vout_Flush(vout_thread_t *vout, vlc_tick_t date)
@@ -1378,21 +1374,22 @@ 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, size_t channel_id,
+ vlc_tick_t delay)
{
assert(!vout->p->dummy);
+ assert(vout->p->spu);
vlc_mutex_lock(&vout->p->spu_lock);
- if (vout->p->spu)
- spu_clock_SetDelay(vout->p->spu, delay);
- vout->p->spu_delay = delay;
+ spu_SetClockDelay(vout->p->spu, channel_id, delay);
vlc_mutex_unlock(&vout->p->spu_lock);
}
-void vout_ChangeSpuRate(vout_thread_t *vout, float rate)
+void vout_ChangeSpuRate(vout_thread_t *vout, size_t channel_id, float rate)
{
assert(!vout->p->dummy);
+ assert(vout->p->spu);
vlc_mutex_lock(&vout->p->spu_lock);
- vout->p->spu_rate = rate;
+ spu_SetClockRate(vout->p->spu, channel_id, rate);
vlc_mutex_unlock(&vout->p->spu_lock);
}
@@ -1946,10 +1943,10 @@ int vout_Request(const vout_configuration_t *cfg, input_thread_t *input)
} else
vout_UpdateWindowSizeLocked(vout);
- sys->delay = sys->spu_delay = 0;
- sys->rate = sys->spu_rate = 1.f;
+ sys->delay = 0;
+ sys->rate = 1.f;
sys->clock = cfg->clock;
- sys->delay = sys->spu_delay = 0;
+ sys->delay = 0;
vlc_mutex_unlock(&sys->window_lock);
diff --git a/src/video_output/vout_internal.h b/src/video_output/vout_internal.h
index 56b4876f8b..1103d04d04 100644
--- a/src/video_output/vout_internal.h
+++ b/src/video_output/vout_internal.h
@@ -72,9 +72,7 @@ struct vout_thread_sys_t
vlc_clock_t *clock;
float rate;
- float spu_rate;
vlc_tick_t delay;
- vlc_tick_t spu_delay;
/* */
video_format_t original; /* Original format ie coming from the decoder */
@@ -262,12 +260,12 @@ 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);
+ssize_t vout_RegisterSubpictureChannelInternal( vout_thread_t *, vlc_clock_t *clock );
+ssize_t spu_RegisterChannelInternal( spu_t *, vlc_clock_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_SetClockDelay(spu_t *spu, size_t channel_id, vlc_tick_t delay);
+void spu_SetClockRate(spu_t *spu, size_t channel_id, float rate);
void spu_ChangeMargin(spu_t *, int);
void spu_SetHighlight(spu_t *, const vlc_spu_highlight_t*);
@@ -293,12 +291,12 @@ void vout_ChangeDelay( vout_thread_t *, vlc_tick_t delay );
* This function will change the rate of the spu channel
* It is thread safe
*/
-void vout_ChangeSpuRate( vout_thread_t *, float rate );
+void vout_ChangeSpuRate( vout_thread_t *, size_t channel_id, float rate );
/**
* This function will change the delay of the spu channel
* It is thread safe
*/
-void vout_ChangeSpuDelay( vout_thread_t *, vlc_tick_t delay );
+void vout_ChangeSpuDelay( vout_thread_t *, size_t channel_id, vlc_tick_t delay );
/**
diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c
index 17cc6a7b77..f65b08019c 100644
--- a/src/video_output/vout_subpictures.c
+++ b/src/video_output/vout_subpictures.c
@@ -62,6 +62,9 @@ typedef struct {
struct spu_channel {
subpicture_t *entries[VOUT_MAX_SUBPICTURES];
size_t id;
+ vlc_clock_t *clock;
+ vlc_tick_t delay;
+ float rate;
};
typedef struct VLC_VECTOR(struct spu_channel) spu_channel_vector;
@@ -71,7 +74,6 @@ struct spu_private_t {
input_thread_t *input;
spu_channel_vector channels;
- vlc_clock_t *clock;
int channel; /**< number of subpicture channels registered */
filter_t *text; /**< text renderer module */
@@ -102,9 +104,13 @@ struct spu_private_t {
vout_thread_t *vout;
};
-static void spu_channel_Init(struct spu_channel *channel, size_t id)
+static void spu_channel_Init(struct spu_channel *channel, size_t id,
+ vlc_clock_t *clock)
{
channel->id = id;
+ channel->clock = clock;
+ channel->delay = 0;
+ channel->rate = 1.f;
for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++)
channel->entries[i] = NULL;
@@ -563,10 +569,8 @@ static int SpuRenderCmp(const void *s0, const void *s1)
}
static int spu_channel_ConvertDates(struct spu_channel *channel,
- vlc_clock_t *clock,
vlc_tick_t system_now,
- spu_render_entry_t *render_entries,
- float rate)
+ spu_render_entry_t *render_entries)
{
/* Put every spu start and stop ts into the same array to convert them in
* one shot */
@@ -587,9 +591,9 @@ static int spu_channel_ConvertDates(struct spu_channel *channel,
return 0;
/* Convert all spu ts */
- if (clock)
- vlc_clock_ConvertArrayToSystem(clock, system_now, date_array,
- entry_count * 2, rate);
+ if (channel->clock)
+ vlc_clock_ConvertArrayToSystem(channel->clock, system_now, date_array,
+ entry_count * 2, channel->rate);
/* Put back the converted ts into the output spu_render_entry_t struct */
entry_count = 0;
@@ -623,7 +627,7 @@ static int spu_channel_ConvertDates(struct spu_channel *channel,
*****************************************************************************/
static spu_render_entry_t *
spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
- vlc_tick_t render_subtitle_date, float rate,
+ vlc_tick_t render_subtitle_date,
bool ignore_osd, size_t *subpicture_count)
{
spu_private_t *sys = spu->p;
@@ -653,8 +657,7 @@ spu_SelectSubpictures(spu_t *spu, vlc_tick_t system_now,
int64_t ephemer_subtitle_order = INT64_MIN;
int64_t ephemer_system_order = INT64_MIN;
- if (spu_channel_ConvertDates(channel, sys->clock, system_now, render_entries,
- rate) == 0)
+ if (spu_channel_ConvertDates(channel, system_now, render_entries) == 0)
continue;
/* Select available pictures */
@@ -836,7 +839,6 @@ static void SpuRenderRegion(spu_t *spu,
spu_area_t display = spu_area_create(0, 0, fmt->i_visible_width,
fmt->i_visible_height,
spu_scale_unit());
- //fprintf("
SpuAreaFitInside(&restrained, &display);
/* Fix the position for the current scale_size */
@@ -1405,15 +1407,13 @@ spu_t *spu_Create(vlc_object_t *object, vout_thread_t *vout)
for (size_t i = 0; i < VOUT_SPU_CHANNEL_OSD_COUNT; ++i)
{
struct spu_channel channel;
- spu_channel_Init(&channel, i);
+ spu_channel_Init(&channel, i, NULL);
vlc_vector_push(&sys->channels, channel);
}
/* Initialize private fields */
vlc_mutex_init(&sys->lock);
- sys->clock = NULL;
-
atomic_init(&sys->margin, var_InheritInteger(spu, "sub-margin"));
sys->source_chain_update = NULL;
@@ -1522,21 +1522,27 @@ 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_SetClockDelay(spu_t *spu, size_t channel_id, vlc_tick_t delay)
{
- spu->p->clock = clock;
-}
+ spu_private_t *sys = spu->p;
-void spu_clock_Reset(spu_t *spu)
-{
- if (spu->p->clock)
- vlc_clock_Reset(spu->p->clock);
+ vlc_mutex_lock(&sys->lock);
+ struct spu_channel *channel = spu_GetChannel(spu, channel_id);
+ assert(channel->clock);
+ vlc_clock_SetDelay(channel->clock, delay);
+ channel->delay = delay;
+ vlc_mutex_unlock(&sys->lock);
}
-void spu_clock_SetDelay(spu_t *spu, vlc_tick_t delay)
+void spu_SetClockRate(spu_t *spu, size_t channel_id, float rate)
{
- if (spu->p->clock)
- vlc_clock_SetDelay(spu->p->clock, delay);
+ spu_private_t *sys = spu->p;
+
+ vlc_mutex_lock(&sys->lock);
+ struct spu_channel *channel = spu_GetChannel(spu, channel_id);
+ assert(channel->clock);
+ channel->rate = rate;
+ vlc_mutex_unlock(&sys->lock);
}
/**
@@ -1639,7 +1645,7 @@ subpicture_t *spu_Render(spu_t *spu,
const video_format_t *fmt_dst,
const video_format_t *fmt_src,
vlc_tick_t system_now,
- vlc_tick_t render_subtitle_date, float rate,
+ vlc_tick_t render_subtitle_date,
bool ignore_osd,
bool external_scale)
{
@@ -1697,7 +1703,7 @@ subpicture_t *spu_Render(spu_t *spu,
/* Get an array of subpictures to render */
spu_render_entry_t *subpicture_array =
- spu_SelectSubpictures(spu, system_now, render_subtitle_date, rate,
+ spu_SelectSubpictures(spu, system_now, render_subtitle_date,
ignore_osd, &subpicture_count);
if (!subpicture_array)
{
@@ -1747,7 +1753,7 @@ subpicture_t *spu_Render(spu_t *spu,
return render;
}
-ssize_t spu_RegisterChannel(spu_t *spu)
+ssize_t spu_RegisterChannelInternal(spu_t *spu, vlc_clock_t *clock)
{
spu_private_t *sys = spu->p;
@@ -1758,7 +1764,7 @@ ssize_t spu_RegisterChannel(spu_t *spu)
if (channel_id != VOUT_SPU_CHANNEL_INVALID)
{
struct spu_channel channel;
- spu_channel_Init(&channel, channel_id);
+ spu_channel_Init(&channel, channel_id, clock);
if (vlc_vector_push(&sys->channels, channel))
{
vlc_mutex_unlock(&sys->lock);
@@ -1771,6 +1777,11 @@ ssize_t spu_RegisterChannel(spu_t *spu)
return VOUT_SPU_CHANNEL_INVALID;
}
+ssize_t spu_RegisterChannel(spu_t *spu)
+{
+ return spu_RegisterChannelInternal(spu, NULL);
+}
+
static void spu_channel_Clear(struct spu_channel *channel)
{
for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++)
@@ -1783,6 +1794,11 @@ void spu_ClearChannel(spu_t *spu, size_t channel_id)
vlc_mutex_lock(&sys->lock);
struct spu_channel *channel = spu_GetChannel(spu, channel_id);
spu_channel_Clear(channel);
+ if (channel->clock)
+ {
+ vlc_clock_Reset(channel->clock);
+ vlc_clock_SetDelay(channel->clock, channel->delay);
+ }
vlc_mutex_unlock(&sys->lock);
}
More information about the vlc-commits
mailing list