vlc | branch: master | Thomas Guillem <[email protected]> | 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); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
