vlc | branch: master | Thomas Guillem <[email protected]> | Mon Jun 3 15:11:30 2019 +0200| [9d592a58e454c8c42a21d9b59f1f6c7d6639b93e] | committer: Thomas Guillem
vout: spu: rework channel registration Every registered channels need to be unregistered. The first 3 OSD channels don't need to be unregistered since they are automatically registered. sput_t now use a vector of struct spu_channel to keep its channels. This struct will contain parameters specific to a channel like the clock/delay/rate. The channel_id is now a ssize_t, -1 being invalid, 0, 1, 2 being the OSD channels, and [3; SSIZE_MAX] being registered spu channels. ES_OUT_VOUT_FLUSH_OVERLAY is renamed to ES_OUT_VOUT_DEL_OVERLAY since this control is only used to delete an overlay. Refs #22273 > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=9d592a58e454c8c42a21d9b59f1f6c7d6639b93e --- include/vlc_es_out.h | 7 +- include/vlc_spu.h | 7 +- include/vlc_subpicture.h | 2 +- include/vlc_vout.h | 13 ++-- modules/access/bluray.c | 2 +- modules/lua/libs/osd.c | 6 +- src/input/decoder.c | 60 +++++++++++----- src/input/decoder.h | 4 +- src/input/es_out.c | 8 +-- src/input/es_out_timeshift.c | 8 +-- src/libvlccore.sym | 2 + src/video_output/video_output.c | 14 +++- src/video_output/vout_subpictures.c | 137 +++++++++++++++++++++++++++++------- 13 files changed, 197 insertions(+), 73 deletions(-) diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h index b690d570e9..06b6a8f338 100644 --- a/include/vlc_es_out.h +++ b/include/vlc_es_out.h @@ -104,10 +104,9 @@ enum es_out_query_e ES_OUT_VOUT_ADD_OVERLAY, /* arg1= es_out_id_t* (video es), * arg2= subpicture_t *, - * arg3= int * (channel id), res= can fail */ - - ES_OUT_VOUT_FLUSH_OVERLAY, /* arg1= es_out_id_t* (video es), - * arg2= int (channel id), res= can fail */ + * arg3= size_t * (channel id), res= can fail */ + ES_OUT_VOUT_DEL_OVERLAY, /* arg1= es_out_id_t* (video es), + * arg2= size_t (channel id), res= can fail */ ES_OUT_SPU_SET_HIGHLIGHT, /* arg1= es_out_id_t* (spu es), arg2= const vlc_spu_highlight_t *, res=can fail */ diff --git a/include/vlc_spu.h b/include/vlc_spu.h index ee6c68f784..00ef08c71d 100644 --- a/include/vlc_spu.h +++ b/include/vlc_spu.h @@ -50,7 +50,7 @@ struct spu_t spu_private_t *p; }; - VLC_API spu_t * spu_Create( vlc_object_t *, vout_thread_t * ); +VLC_API spu_t * spu_Create( vlc_object_t *, vout_thread_t * ); #define spu_Create(a,b) spu_Create(VLC_OBJECT(a),b) VLC_API void spu_Destroy( spu_t * ); @@ -80,12 +80,13 @@ VLC_API subpicture_t * spu_Render( spu_t *, const vlc_fourcc_t *p_chroma_list, /** * It registers a new SPU channel. */ -VLC_API int spu_RegisterChannel( spu_t * ); +VLC_API ssize_t spu_RegisterChannel( spu_t * ); +VLC_API void spu_UnregisterChannel( spu_t *, size_t ); /** * It clears all subpictures associated to a SPU channel. */ -VLC_API void spu_ClearChannel( spu_t *, int ); +VLC_API void spu_ClearChannel( spu_t *, size_t ); /** * It changes the sub sources list diff --git a/include/vlc_subpicture.h b/include/vlc_subpicture.h index ea618e8aa1..606eb451e1 100644 --- a/include/vlc_subpicture.h +++ b/include/vlc_subpicture.h @@ -165,7 +165,7 @@ struct subpicture_t { /** \name Channel ID */ /**@{*/ - int i_channel; /**< subpicture channel ID */ + ssize_t i_channel; /**< subpicture channel ID */ /**@}*/ /** \name Type and flags diff --git a/include/vlc_vout.h b/include/vlc_vout.h index 88f825d3fa..da1a3a836c 100644 --- a/include/vlc_vout.h +++ b/include/vlc_vout.h @@ -110,15 +110,16 @@ VLC_API void vout_PutPicture( vout_thread_t *, picture_t * ); /* Subpictures channels ID */ #define VOUT_SPU_CHANNEL_INVALID (-1) /* Always fails in comparison */ -#define VOUT_SPU_CHANNEL_OSD 1 /* OSD channel is automatically cleared */ -#define VOUT_SPU_CHANNEL_OSD_HSLIDER 2 -#define VOUT_SPU_CHANNEL_OSD_VSLIDER 3 -#define VOUT_SPU_CHANNEL_AVAIL_FIRST 8 /* Registerable channels from this offset */ +#define VOUT_SPU_CHANNEL_OSD 0 /* OSD channel is automatically cleared */ +#define VOUT_SPU_CHANNEL_OSD_HSLIDER 1 +#define VOUT_SPU_CHANNEL_OSD_VSLIDER 2 +#define VOUT_SPU_CHANNEL_OSD_COUNT 3 /* */ VLC_API void vout_PutSubpicture( vout_thread_t *, subpicture_t * ); -VLC_API int vout_RegisterSubpictureChannel( vout_thread_t * ); -VLC_API void vout_FlushSubpictureChannel( vout_thread_t *, int ); +VLC_API ssize_t vout_RegisterSubpictureChannel( vout_thread_t * ); +VLC_API void vout_UnregisterSubpictureChannel( vout_thread_t *, size_t ); +VLC_API void vout_FlushSubpictureChannel( vout_thread_t *, size_t ); /** * This function will ensure that all ready/displayed pictures have at most * the provided date. diff --git a/modules/access/bluray.c b/modules/access/bluray.c index c452327aeb..4e21ddbed1 100644 --- a/modules/access/bluray.c +++ b/modules/access/bluray.c @@ -1531,7 +1531,7 @@ static int bluray_esOutControl(es_out_t *p_out, int i_query, va_list args) i_plane < MAX_OVERLAY && esout_priv->overlay.channels[i_plane] != VOUT_SPU_CHANNEL_INVALID) { - i_ret = es_out_Control(esout_priv->p_dst_out, ES_OUT_VOUT_FLUSH_OVERLAY, + i_ret = es_out_Control(esout_priv->p_dst_out, ES_OUT_VOUT_DEL_OVERLAY, esout_priv->overlay.p_video_es, esout_priv->overlay.channels[i_plane]); esout_priv->overlay.channels[i_plane] = VOUT_SPU_CHANNEL_INVALID; diff --git a/modules/lua/libs/osd.c b/modules/lua/libs/osd.c index 0131c8edf6..6aa3257e98 100644 --- a/modules/lua/libs/osd.c +++ b/modules/lua/libs/osd.c @@ -166,7 +166,7 @@ static int vlclua_spu_channel_register( lua_State *L ) if( !p_vout ) return luaL_error( L, "Unable to find vout." ); - int i_chan = vout_RegisterSubpictureChannel( p_vout ); + ssize_t i_chan = vout_RegisterSubpictureChannel( p_vout ); vout_Release( p_vout ); lua_pushinteger( L, i_chan ); return 1; @@ -174,12 +174,12 @@ static int vlclua_spu_channel_register( lua_State *L ) static int vlclua_spu_channel_clear( lua_State *L ) { - int i_chan = luaL_checkinteger( L, 1 ); + ssize_t i_chan = luaL_checkinteger( L, 1 ); vout_thread_t *p_vout = vlclua_get_vout_internal(L); if( !p_vout ) return luaL_error( L, "Unable to find vout." ); - vout_FlushSubpictureChannel( p_vout, i_chan ); + vout_UnregisterSubpictureChannel( p_vout, i_chan ); vout_Release(p_vout); return 0; } diff --git a/src/input/decoder.c b/src/input/decoder.c index 53fd02376d..563c1f08b9 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -71,7 +71,7 @@ struct decoder_owner input_resource_t*p_resource; vlc_clock_t *p_clock; - int i_spu_channel; + ssize_t i_spu_channel; int64_t i_spu_order; sout_instance_t *p_sout; @@ -611,8 +611,15 @@ static subpicture_t *spu_new_buffer( decoder_t *p_dec, msg_Warn( p_dec, "no vout found, dropping subpicture" ); if( p_owner->p_vout ) { - vlc_mutex_lock( &p_owner->lock ); + if (p_owner->i_spu_channel != -1) + { + vout_UnregisterSubpictureChannel(p_owner->p_vout, + 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); p_owner->p_vout = NULL; vlc_mutex_unlock( &p_owner->lock ); @@ -622,19 +629,27 @@ 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_order = 0; - vlc_mutex_lock( &p_owner->lock ); - if( p_owner->p_vout ) + if (p_owner->i_spu_channel != -1) { - vout_SetSubpictureClock(p_owner->p_vout, NULL); - vout_Release(p_owner->p_vout); - } - p_owner->p_vout = p_vout; - vlc_mutex_unlock( &p_owner->lock ); + 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); + } + 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 ); + vout_SetSubpictureClock(p_vout, p_owner->p_clock); + } } else vout_Release(p_vout); @@ -1483,7 +1498,10 @@ static void DecoderProcessFlush( decoder_t *p_dec ) else if( p_dec->fmt_out.i_cat == SPU_ES ) { if( p_owner->p_vout ) + { + assert( p_owner->i_spu_channel >= 0 ); vout_FlushSubpictureChannel( p_owner->p_vout, p_owner->i_spu_channel ); + } } p_owner->i_preroll_end = (vlc_tick_t)INT64_MIN; @@ -1782,7 +1800,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, p_owner->p_resource = p_resource; p_owner->p_aout = NULL; p_owner->p_vout = NULL; - p_owner->i_spu_channel = 0; + p_owner->i_spu_channel = -1; p_owner->i_spu_order = 0; p_owner->p_sout = p_sout; p_owner->p_sout_input = NULL; @@ -1969,8 +1987,9 @@ static void DeleteDecoder( decoder_t * p_dec ) { if( p_owner->p_vout ) { - vout_FlushSubpictureChannel( p_owner->p_vout, - p_owner->i_spu_channel ); + 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); } @@ -2528,7 +2547,7 @@ void input_DecoderSetVoutMouseEvent( decoder_t *dec, vlc_mouse_event mouse_event } int input_DecoderAddVoutOverlay( decoder_t *dec, subpicture_t *sub, - int *channel ) + size_t *channel ) { struct decoder_owner *owner = dec_get_owner( dec ); assert( dec->fmt_in.i_cat == VIDEO_ES ); @@ -2541,8 +2560,15 @@ int input_DecoderAddVoutOverlay( decoder_t *dec, subpicture_t *sub, vlc_mutex_unlock( &owner->lock ); return VLC_EGENERIC; } + ssize_t channel_id = + vout_RegisterSubpictureChannel( owner->p_vout ); + if (channel_id == -1) + { + vlc_mutex_unlock( &owner->lock ); + return VLC_EGENERIC; + } sub->i_start = sub->i_stop = vlc_tick_now(); - sub->i_channel = *channel = vout_RegisterSubpictureChannel( owner->p_vout ); + sub->i_channel = *channel = channel_id; sub->i_order = 0; sub->b_ephemer = true; vout_PutSubpicture( owner->p_vout, sub ); @@ -2551,7 +2577,7 @@ int input_DecoderAddVoutOverlay( decoder_t *dec, subpicture_t *sub, return VLC_SUCCESS; } -int input_DecoderFlushVoutOverlay( decoder_t *dec, int channel ) +int input_DecoderDelVoutOverlay( decoder_t *dec, size_t channel ) { struct decoder_owner *owner = dec_get_owner( dec ); assert( dec->fmt_in.i_cat == VIDEO_ES ); @@ -2563,7 +2589,7 @@ int input_DecoderFlushVoutOverlay( decoder_t *dec, int channel ) vlc_mutex_unlock( &owner->lock ); return VLC_EGENERIC; } - vout_FlushSubpictureChannel( owner->p_vout, channel ); + vout_UnregisterSubpictureChannel( owner->p_vout, channel ); vlc_mutex_unlock( &owner->lock ); return VLC_SUCCESS; diff --git a/src/input/decoder.h b/src/input/decoder.h index 0ac021e9b2..fbb266e139 100644 --- a/src/input/decoder.h +++ b/src/input/decoder.h @@ -110,7 +110,7 @@ bool input_DecoderHasFormatChanged( decoder_t *p_dec, es_format_t *p_fmt, vlc_me size_t input_DecoderGetFifoSize( decoder_t *p_dec ); void input_DecoderSetVoutMouseEvent( decoder_t *, vlc_mouse_event, void * ); -int input_DecoderAddVoutOverlay( decoder_t *, subpicture_t *, int * ); -int input_DecoderFlushVoutOverlay( decoder_t *, int ); +int input_DecoderAddVoutOverlay( decoder_t *, subpicture_t *, size_t * ); +int input_DecoderDelVoutOverlay( decoder_t *, size_t ); #endif diff --git a/src/input/es_out.c b/src/input/es_out.c index 6f35f2c323..6a76dead3f 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -3131,17 +3131,17 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) { es_out_id_t *p_es = va_arg( args, es_out_id_t * ); subpicture_t *sub = va_arg( args, subpicture_t * ); - int *channel = va_arg( args, int * ); + size_t *channel = va_arg( args, size_t * ); if( p_es && p_es->fmt.i_cat == VIDEO_ES && p_es->p_dec ) return input_DecoderAddVoutOverlay( p_es->p_dec, sub, channel ); return VLC_EGENERIC; } - case ES_OUT_VOUT_FLUSH_OVERLAY: + case ES_OUT_VOUT_DEL_OVERLAY: { es_out_id_t *p_es = va_arg( args, es_out_id_t * ); - int channel = va_arg( args, int ); + size_t channel = va_arg( args, size_t ); if( p_es && p_es->fmt.i_cat == VIDEO_ES && p_es->p_dec ) - return input_DecoderFlushVoutOverlay( p_es->p_dec, channel ); + return input_DecoderDelVoutOverlay( p_es->p_dec, channel ); return VLC_EGENERIC; } case ES_OUT_SPU_SET_HIGHLIGHT: diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c index 5adbbc23e4..09482a2a10 100644 --- a/src/input/es_out_timeshift.c +++ b/src/input/es_out_timeshift.c @@ -662,15 +662,15 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args ) { es_out_id_t *p_es = va_arg( args, es_out_id_t * ); subpicture_t *sub = va_arg( args, subpicture_t * ); - int *channel = va_arg( args, int * ); + size_t *channel = va_arg( args, size_t * ); return es_out_Control( p_sys->p_out, ES_OUT_VOUT_ADD_OVERLAY, p_es->p_es, sub, channel ); } - case ES_OUT_VOUT_FLUSH_OVERLAY: + case ES_OUT_VOUT_DEL_OVERLAY: { es_out_id_t *p_es = va_arg( args, es_out_id_t * ); - int channel = va_arg( args, int ); - return es_out_Control( p_sys->p_out, ES_OUT_VOUT_FLUSH_OVERLAY, + size_t channel = va_arg( args, size_t ); + return es_out_Control( p_sys->p_out, ES_OUT_VOUT_DEL_OVERLAY, p_es->p_es, channel ); } case ES_OUT_SPU_SET_HIGHLIGHT: diff --git a/src/libvlccore.sym b/src/libvlccore.sym index d32515dc6c..d6a524e248 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -349,6 +349,7 @@ spu_ChangeSources spu_ChangeFilters spu_Render spu_RegisterChannel +spu_UnregisterChannel spu_ClearChannel vlc_stream_directory_Attach vlc_stream_extractor_Attach @@ -697,6 +698,7 @@ vout_GetPicture vout_PutPicture vout_PutSubpicture vout_RegisterSubpictureChannel +vout_UnregisterSubpictureChannel vout_FlushSubpictureChannel vout_Flush vout_GetSnapshot diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 524135f013..1f0a2391dd 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -267,10 +267,10 @@ void vout_PutSubpicture( vout_thread_t *vout, subpicture_t *subpic ) vlc_mutex_unlock(&sys->spu_lock); } -int vout_RegisterSubpictureChannel( vout_thread_t *vout ) +ssize_t vout_RegisterSubpictureChannel( vout_thread_t *vout ) { assert(!vout->p->dummy); - int channel = VOUT_SPU_CHANNEL_AVAIL_FIRST; + ssize_t channel = VOUT_SPU_CHANNEL_INVALID; vlc_mutex_lock(&vout->p->spu_lock); if (vout->p->spu) @@ -280,6 +280,14 @@ int vout_RegisterSubpictureChannel( vout_thread_t *vout ) return channel; } +void vout_UnregisterSubpictureChannel( vout_thread_t *vout, size_t channel ) +{ + assert(!vout->p->dummy); + + if (vout->p->spu) + spu_UnregisterChannel(vout->p->spu, channel); +} + void vout_SetSubpictureClock( vout_thread_t *vout, vlc_clock_t *clock ) { assert(!vout->p->dummy); @@ -289,7 +297,7 @@ void vout_SetSubpictureClock( vout_thread_t *vout, vlc_clock_t *clock ) vlc_mutex_unlock(&vout->p->spu_lock); } -void vout_FlushSubpictureChannel( vout_thread_t *vout, int channel ) +void vout_FlushSubpictureChannel( vout_thread_t *vout, size_t channel ) { vout_thread_sys_t *sys = vout->p; assert(!sys->dummy); diff --git a/src/video_output/vout_subpictures.c b/src/video_output/vout_subpictures.c index 247321f29c..108e0a46c6 100644 --- a/src/video_output/vout_subpictures.c +++ b/src/video_output/vout_subpictures.c @@ -38,6 +38,7 @@ #include <vlc_vout.h> #include <vlc_filter.h> #include <vlc_spu.h> +#include <vlc_vector.h> #include "../libvlc.h" #include "vout_internal.h" @@ -62,10 +63,17 @@ typedef struct { subpicture_t *entries[VOUT_MAX_SUBPICTURES]; } spu_heap_t; +struct spu_channel { + size_t id; +}; + +typedef struct VLC_VECTOR(struct spu_channel) spu_channel_vector; + struct spu_private_t { vlc_mutex_t lock; /* lock to protect all followings fields */ input_thread_t *input; + spu_channel_vector channels; vlc_clock_t *clock; spu_heap_t heap; @@ -152,6 +160,42 @@ static void SpuHeapClean(spu_heap_t *heap) } } +static struct spu_channel *spu_GetChannel(spu_t *spu, size_t channel_id) +{ + spu_private_t *sys = spu->p; + + for (size_t i = 0; i < sys->channels.size; ++i) + if (sys->channels.data[i].id == channel_id) + return &sys->channels.data[i]; + + vlc_assert_unreachable(); +} + +static ssize_t spu_GetFreeChannelId(spu_t *spu) +{ + spu_private_t *sys = spu->p; + + if (unlikely(sys->channels.size) > SSIZE_MAX) + return VOUT_SPU_CHANNEL_INVALID; + + size_t id; + for (id = VOUT_SPU_CHANNEL_OSD_COUNT; id < sys->channels.size + 1; ++id) + { + bool used = false; + for (size_t i = VOUT_SPU_CHANNEL_OSD_COUNT; i < sys->channels.size; ++i) + { + if (sys->channels.data[i].id == id) + { + used = true; + break; + } + } + if (!used) + return id; + } + return VOUT_SPU_CHANNEL_INVALID; +} + static void FilterRelease(filter_t *filter) { if (filter->p_module) @@ -491,6 +535,11 @@ static int IntegerCmp(int64_t i0, int64_t i1) { return i0 < i1 ? -1 : i0 > i1 ? 1 : 0; } + +static int SSizeCmp(ssize_t i0, ssize_t i1) +{ + return i0 < i1 ? -1 : i0 > i1 ? 1 : 0; +} /** * This function compares 2 subpictures using the following properties * (ordered by priority) @@ -514,7 +563,7 @@ static int SpuRenderCmp(const void *s0, const void *s1) if (!r) r = IntegerCmp(render_entry0->start, render_entry1->start); if (!r) - r = IntegerCmp(subpic0->i_channel, subpic1->i_channel); + r = SSizeCmp(subpic0->i_channel, subpic1->i_channel); if (!r) r = IntegerCmp(subpic0->i_order, subpic1->i_order); return r; @@ -595,14 +644,14 @@ static void SpuSelectSubpictures(spu_t *spu, return; /* Create a list of channels */ - int channel[VOUT_MAX_SUBPICTURES]; - int channel_count = 0; + ssize_t channel[VOUT_MAX_SUBPICTURES]; + size_t channel_count = 0; for (int index = 0; index < VOUT_MAX_SUBPICTURES; index++) { if (!sys->heap.entries[index]) continue; const int i_channel = sys->heap.entries[index]->i_channel; - int i; + size_t i; for (i = 0; i < channel_count; i++) { if (channel[i] == i_channel) break; @@ -612,7 +661,7 @@ static void SpuSelectSubpictures(spu_t *spu, } /* Fill up the subpicture_array arrays with relevant pictures */ - for (int i = 0; i < channel_count; i++) { + for (size_t i = 0; i < channel_count; i++) { spu_render_entry_t available_entries[VOUT_MAX_SUBPICTURES]; bool is_available_late[VOUT_MAX_SUBPICTURES]; size_t available_count = 0; @@ -1257,7 +1306,7 @@ static void UpdateSPU(spu_t *spu, const vlc_spu_highlight_t *hl) static subpicture_t *sub_new_buffer(filter_t *filter) { - int channel = *(int *)filter->owner.sys; + ssize_t channel = *(ssize_t *)filter->owner.sys; subpicture_t *subpicture = subpicture_New(NULL); if (subpicture) @@ -1272,7 +1321,7 @@ static const struct filter_subpicture_callbacks sub_cbs = { static int SubSourceInit(filter_t *filter, void *data) { spu_t *spu = data; - int *channel = malloc(sizeof (int)); + ssize_t *channel = malloc(sizeof (ssize_t)); if (unlikely(channel == NULL)) return VLC_ENOMEM; @@ -1285,7 +1334,7 @@ static int SubSourceInit(filter_t *filter, void *data) static int SubSourceClean(filter_t *filter, void *data) { spu_t *spu = data; - int *channel = filter->owner.sys; + ssize_t *channel = filter->owner.sys; spu_ClearChannel(spu, *channel); free(channel); @@ -1361,6 +1410,21 @@ spu_t *spu_Create(vlc_object_t *object, vout_thread_t *vout) /* Initialize spu fields */ spu_private_t *sys = spu->p = (spu_private_t*)&spu[1]; + vlc_vector_init(&sys->channels); + if (!vlc_vector_reserve(&sys->channels, VOUT_SPU_CHANNEL_OSD_COUNT)) + { + vlc_object_delete(spu); + return NULL; + } + for (size_t i = 0; i < VOUT_SPU_CHANNEL_OSD_COUNT; ++i) + { + struct spu_channel channel = { + .id = i, + }; + bool success = vlc_vector_push(&sys->channels, channel); + assert(success); /* already reserved */ + } + /* Initialize private fields */ vlc_mutex_init(&sys->lock); @@ -1370,9 +1434,6 @@ spu_t *spu_Create(vlc_object_t *object, vout_thread_t *vout) atomic_init(&sys->margin, var_InheritInteger(spu, "sub-margin")); - /* Register the default subpicture channel */ - sys->channel = VOUT_SPU_CHANNEL_AVAIL_FIRST; - sys->source_chain_update = NULL; sys->filter_chain_update = NULL; vlc_mutex_init(&sys->filter_chain_lock); @@ -1443,6 +1504,8 @@ void spu_Destroy(spu_t *spu) /* Destroy all remaining subpictures */ SpuHeapClean(&sys->heap); + vlc_vector_destroy(&sys->channels); + vlc_mutex_destroy(&sys->lock); vlc_object_delete(spu); @@ -1712,36 +1775,60 @@ void spu_OffsetSubtitleDate(spu_t *spu, vlc_tick_t duration) vlc_mutex_unlock(&sys->lock); } -int spu_RegisterChannel(spu_t *spu) +ssize_t spu_RegisterChannel(spu_t *spu) { spu_private_t *sys = spu->p; vlc_mutex_lock(&sys->lock); - int channel = sys->channel++; + + ssize_t channel_id = spu_GetFreeChannelId(spu); + + if (channel_id != VOUT_SPU_CHANNEL_INVALID) + { + struct spu_channel channel = { + .id = channel_id, + }; + if (vlc_vector_push(&sys->channels, channel)) + { + vlc_mutex_unlock(&sys->lock); + return channel_id; + } + } + vlc_mutex_unlock(&sys->lock); - return channel; + return VOUT_SPU_CHANNEL_INVALID; } -void spu_ClearChannel(spu_t *spu, int channel) +static void spu_ClearChannelLocked(spu_t *spu, size_t channel_id) { spu_private_t *sys = spu->p; - vlc_mutex_lock(&sys->lock); - - for (int i = 0; i < VOUT_MAX_SUBPICTURES; i++) + for (size_t i = 0; i < VOUT_MAX_SUBPICTURES; i++) { subpicture_t *subpic = sys->heap.entries[i]; - if (!subpic) - continue; - if (subpic->i_channel != channel && - (channel != VOUT_SPU_CHANNEL_INVALID || subpic->i_channel == VOUT_SPU_CHANNEL_OSD)) - continue; - - SpuHeapDeleteAt(&sys->heap, i); + if (subpic && subpic->i_channel >= 0 + && (size_t) subpic->i_channel == channel_id) + SpuHeapDeleteAt(&sys->heap, i); } +} + +void spu_ClearChannel(spu_t *spu, size_t channel_id) +{ + spu_private_t *sys = spu->p; + vlc_mutex_lock(&sys->lock); + spu_ClearChannelLocked(spu, channel_id); + vlc_mutex_unlock(&sys->lock); +} +void spu_UnregisterChannel(spu_t *spu, size_t channel_id) +{ + spu_private_t *sys = spu->p; + + vlc_mutex_lock(&sys->lock); + spu_ClearChannelLocked(spu, channel_id); + vlc_vector_remove(&sys->channels, channel_id); vlc_mutex_unlock(&sys->lock); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
