[vlc-devel] [PATCH 3/4] es_out: add controls to cycle through programs
Thomas Guillem
thomas at gllm.fr
Wed Nov 14 17:50:17 CET 2018
With 2 new internal controls: ES_OUT_SET_GROUP_NEXT, and ES_OUT_SET_GROUP_PREV.
This will fix a TOCTOU issue when selecting next or previous programs.
---
src/input/es_out.c | 55 ++++++++++++++++++++++++++++++++++++
src/input/es_out.h | 3 ++
src/input/es_out_timeshift.c | 2 ++
3 files changed, 60 insertions(+)
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 2960374175..893bde7630 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -2461,6 +2461,53 @@ static int EsOutControlCycleEsLocked(es_out_t *out, enum es_format_category_e ca
}
}
+static int EsOutControlCycleGroupLocked(es_out_t *out, bool next, int *new_id)
+{
+ es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
+ es_out_pgrm_t *pgrm;
+ es_out_pgrm_t *new_pgrm = NULL;
+
+ if (next)
+ {
+ vlc_list_foreach(pgrm, &p_sys->programs, node)
+ {
+ if (pgrm == p_sys->p_pgrm)
+ {
+ new_pgrm = vlc_list_next_entry_or_null(&p_sys->programs, pgrm,
+ es_out_pgrm_t, node);
+ if (new_pgrm == NULL)
+ new_pgrm = vlc_list_first_entry_or_null(&p_sys->programs,
+ es_out_pgrm_t, node);
+ break;
+ }
+ }
+ }
+ else
+ {
+ vlc_list_foreach(pgrm, &p_sys->programs, node)
+ {
+ es_out_pgrm_t *next_pgrm =
+ vlc_list_next_entry_or_null(&p_sys->programs, pgrm,
+ es_out_pgrm_t, node);
+ if (next_pgrm == p_sys->p_pgrm)
+ {
+ new_pgrm = pgrm;
+ break;
+ }
+ }
+ if (new_pgrm == NULL)
+ new_pgrm = vlc_list_last_entry_or_null(&p_sys->programs,
+ es_out_pgrm_t, node);
+ }
+ if (new_pgrm && new_pgrm != p_sys->p_pgrm)
+ {
+ EsOutProgramSelect(out, new_pgrm);
+ *new_id = new_pgrm->i_id;
+ return VLC_SUCCESS;
+ }
+ return VLC_EGENERIC;
+}
+
/**
* Control query handler
*
@@ -2840,6 +2887,14 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
}
return VLC_EGENERIC;
}
+ case ES_OUT_SET_GROUP_NEXT:
+ case ES_OUT_SET_GROUP_PREV:
+ {
+ int *new_id = va_arg(args, int *);
+ return EsOutControlCycleGroupLocked(out,
+ i_query == ES_OUT_SET_GROUP_NEXT,
+ new_id);
+ }
case ES_OUT_SET_ES_FMT:
{
diff --git a/src/input/es_out.h b/src/input/es_out.h
index 5f216905bd..8964839610 100644
--- a/src/input/es_out.h
+++ b/src/input/es_out.h
@@ -53,6 +53,9 @@ enum es_out_query_private_e
ES_OUT_SET_ES_NEXT, /* arg1=es_category_e, arg2= vlc_es_id_t **, res=can fail */
ES_OUT_SET_ES_PREV, /* arg1=es_category_e, arg2= vlc_es_id_t **, res=can fail */
+ ES_OUT_SET_GROUP_NEXT, /* arg1=int *, res= can fail */
+ ES_OUT_SET_GROUP_PREV, /* arg1=int *, res= can fail */
+
/* Stop all selected ES and save the stopped state in a context. free the
* context or call ES_OUT_STOP_ALL_ES */
ES_OUT_STOP_ALL_ES, /* arg1=void ** */
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 5e7ffcd8e6..9a565e77bc 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -742,6 +742,8 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
case ES_OUT_SET_ES_BY_ID:
case ES_OUT_SET_ES_NEXT:
case ES_OUT_SET_ES_PREV:
+ case ES_OUT_SET_GROUP_NEXT:
+ case ES_OUT_SET_GROUP_PREV:
case ES_OUT_RESTART_ES_BY_ID:
case ES_OUT_SET_ES_DEFAULT_BY_ID:
case ES_OUT_GET_ES_OBJECTS_BY_ID:
--
2.19.1
More information about the vlc-devel
mailing list