vlc | branch: master | Thomas Guillem <[email protected]> | Wed Nov 14 17:40:03 2018 +0100| [8eb087c18858820cfe6f1660aba2ba0e9900b0cc] | committer: Thomas Guillem
es_out: add controls to cycle through programs 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. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8eb087c18858820cfe6f1660aba2ba0e9900b0cc --- 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: _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
