vlc | branch: master | Thomas Guillem <[email protected]> | Wed Feb 26 16:20:29 2020 +0100| [33c53b0d6fdf90f42c656addac1db85868f68437] | committer: Thomas Guillem
es_out: split public and private controls Private controls are necessarily called from the input_thead_t (or via timeshift via the input_thread_t). Public controls can be called from demuxers of the input_thread_t. This separation will help the process of adding new es_out controls, specially private one that don't need to be added in public headers. Furthermore, this will help a future control ES_OUT_PRIV_SET_ES_CAT_IDS: that will be able to be executed when the input is started or not. I think that such new control should be explicitly made private. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=33c53b0d6fdf90f42c656addac1db85868f68437 --- include/vlc_es_out.h | 6 + modules/demux/timestamps_filter.h | 1 + src/input/es_out.c | 527 +++++++++++++++++---------------- src/input/es_out.h | 95 +++--- src/input/es_out_timeshift.c | 268 +++++++++++------ src/input/input.c | 36 +-- test/modules/demux/timestamps_filter.c | 1 + 7 files changed, 534 insertions(+), 400 deletions(-) diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h index 06b6a8f338..5cf5116ab6 100644 --- a/include/vlc_es_out.h +++ b/include/vlc_es_out.h @@ -23,6 +23,8 @@ #ifndef VLC_ES_OUT_H #define VLC_ES_OUT_H 1 +#include <assert.h> + /** * \defgroup es_out ES output * \ingroup input @@ -128,6 +130,10 @@ struct es_out_callbacks void (*del)(es_out_t *, es_out_id_t *); int (*control)(es_out_t *, int query, va_list); void (*destroy)(es_out_t *); + /** + * Private control callback, must be NULL for es_out created from modules. + */ + int (*priv_control)(es_out_t *, int query, va_list); }; struct es_out_t diff --git a/modules/demux/timestamps_filter.h b/modules/demux/timestamps_filter.h index f56c4e7137..4d2b2e0883 100644 --- a/modules/demux/timestamps_filter.h +++ b/modules/demux/timestamps_filter.h @@ -353,6 +353,7 @@ static const struct es_out_callbacks timestamps_filter_es_out_cbs = timestamps_filter_es_out_Del, timestamps_filter_es_out_Control, timestamps_filter_es_out_Delete, + NULL, }; static es_out_t * timestamps_filter_es_out_New(es_out_t *orig) diff --git a/src/input/es_out.c b/src/input/es_out.c index 6955192dc0..9f3666965b 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -244,6 +244,7 @@ static void EsOutGlobalMeta( es_out_t *p_out, const vlc_meta_t *p_meta ); static void EsOutMeta( es_out_t *p_out, const vlc_meta_t *p_meta, const vlc_meta_t *p_progmeta ); static int EsOutEsUpdateFmt(es_out_t *out, es_out_id_t *es, const es_format_t *fmt); static int EsOutControlLocked( es_out_t *out, int i_query, ... ); +static int EsOutPrivControlLocked( es_out_t *out, int i_query, ... ); static char *LanguageGetName( const char *psz_code ); static char *LanguageGetCode( const char *psz_lang ); @@ -727,8 +728,8 @@ static void EsOutSetEsDelay(es_out_t *out, es_out_id_t *es, vlc_tick_t delay) EsOutDecoderChangeDelay(out, es); /* Update the clock pts delay only if the extra tracks delay changed */ - EsOutControlLocked(out, ES_OUT_SET_JITTER, p_sys->i_pts_delay, - p_sys->i_pts_jitter, p_sys->i_cr_average); + EsOutPrivControlLocked(out, ES_OUT_PRIV_SET_JITTER, p_sys->i_pts_delay, + p_sys->i_pts_jitter, p_sys->i_cr_average); } static void EsOutSetDelay( es_out_t *out, int i_cat, vlc_tick_t i_delay ) @@ -745,8 +746,8 @@ static void EsOutSetDelay( es_out_t *out, int i_cat, vlc_tick_t i_delay ) EsOutDecoderChangeDelay(out, es); /* Update the clock pts delay only if the extra tracks delay changed */ - EsOutControlLocked(out, ES_OUT_SET_JITTER, p_sys->i_pts_delay, - p_sys->i_pts_jitter, p_sys->i_cr_average); + EsOutPrivControlLocked(out, ES_OUT_PRIV_SET_JITTER, p_sys->i_pts_delay, + p_sys->i_pts_jitter, p_sys->i_cr_average); } static int EsOutSetRecord( es_out_t *out, bool b_record ) @@ -2784,59 +2785,6 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_SUCCESS; } - case ES_OUT_GET_GROUP_FORCED: - { - int *pi_group = va_arg( args, int * ); - *pi_group = p_sys->i_group_id; - return VLC_SUCCESS; - } - - case ES_OUT_SET_MODE: - { - const int i_mode = va_arg( args, int ); - assert( i_mode == ES_OUT_MODE_NONE || i_mode == ES_OUT_MODE_ALL || - i_mode == ES_OUT_MODE_AUTO || i_mode == ES_OUT_MODE_PARTIAL || - i_mode == ES_OUT_MODE_END ); - - if (i_mode != ES_OUT_MODE_NONE && !p_sys->b_active && !vlc_list_is_empty(&p_sys->es)) - { - /* XXX Terminate vout if there are tracks but no video one. - * This one is not mandatory but is he earliest place where it - * can be done */ - es_out_id_t *p_es; - bool found = false; - - foreach_es_then_es_slaves(p_es) - if( p_es->fmt.i_cat == VIDEO_ES && !found /* nested loop */ ) - { - found = true; - break; - } - - if (!found) - EsOutStopFreeVout( out ); - } - p_sys->b_active = i_mode != ES_OUT_MODE_NONE; - p_sys->i_mode = i_mode; - - /* Reapply policy mode */ - es_out_id_t *es; - - foreach_es_then_es_slaves(es) - { - if (EsIsSelected(es)) - EsOutUnselectEs(out, es, es->p_pgrm == p_sys->p_pgrm); - } - foreach_es_then_es_slaves(es) - { - EsOutSelect(out, es, false); - } - - if( i_mode == ES_OUT_MODE_END ) - EsOutTerminate( out ); - return VLC_SUCCESS; - } - case ES_OUT_SET_ES: case ES_OUT_RESTART_ES: { @@ -2898,13 +2846,6 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) EsOutStopFreeVout( out ); return VLC_SUCCESS; } - case ES_OUT_SET_ES_LIST: - { - enum es_format_category_e cat = va_arg( args, enum es_format_category_e ); - vlc_es_id_t *const*es_id_list = va_arg( args, vlc_es_id_t ** ); - EsOutSelectList( out, cat, es_id_list ); - return VLC_SUCCESS; - } case ES_OUT_UNSET_ES: { es_out_id_t *es = va_arg( args, es_out_id_t * ), *other; @@ -2925,50 +2866,6 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) } return VLC_EGENERIC; } - case ES_OUT_STOP_ALL_ES: - { - es_out_id_t *es; - int count = 0; - - foreach_es_then_es_slaves(es) - count++; - - int *selected_es = vlc_alloc(count + 1, sizeof(int)); - if (!selected_es) - return VLC_ENOMEM; - - *va_arg(args, void **) = selected_es; - *selected_es = count; - - foreach_es_then_es_slaves(es) - { - if (EsIsSelected(es)) - { - EsOutDestroyDecoder(out, es); - *++selected_es = es->fmt.i_id; - } - else - *++selected_es = -1; - } - return VLC_SUCCESS; - } - case ES_OUT_START_ALL_ES: - { - int *selected_es = va_arg( args, void * ); - int count = selected_es[0]; - for( int i = 0; i < count; ++i ) - { - int i_id = selected_es[i + 1]; - if( i_id != -1 ) - { - es_out_id_t *p_es = EsOutGetFromID( out, i_id ); - EsOutCreateDecoder( out, p_es ); - } - } - free(selected_es); - EsOutStopFreeVout( out ); - return VLC_SUCCESS; - } case ES_OUT_SET_ES_DEFAULT: { @@ -3107,10 +3004,9 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) /* Force a rebufferization when we are too late */ EsOutControlLocked( out, ES_OUT_RESET_PCR ); - EsOutControlLocked( out, ES_OUT_SET_JITTER, - p_sys->i_pts_delay, - i_new_jitter, - p_sys->i_cr_average ); + EsOutPrivControlLocked( out, ES_OUT_PRIV_SET_JITTER, + p_sys->i_pts_delay, i_new_jitter, + p_sys->i_cr_average ); } } return VLC_SUCCESS; @@ -3238,28 +3134,206 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_SUCCESS; } - case ES_OUT_GET_WAKE_UP: + case ES_OUT_GET_EMPTY: + { + bool *pb = va_arg( args, bool* ); + *pb = EsOutDecodersIsEmpty( out ); + return VLC_SUCCESS; + } + + case ES_OUT_GET_PCR_SYSTEM: + { + if( p_sys->b_buffering ) + return VLC_EGENERIC; + + es_out_pgrm_t *p_pgrm = p_sys->p_pgrm; + if( !p_pgrm ) + return VLC_EGENERIC; + + vlc_tick_t *pi_system = va_arg( args, vlc_tick_t *); + vlc_tick_t *pi_delay = va_arg( args, vlc_tick_t *); + input_clock_GetSystemOrigin( p_pgrm->p_input_clock, pi_system, pi_delay ); + return VLC_SUCCESS; + } + + case ES_OUT_MODIFY_PCR_SYSTEM: + { + if( p_sys->b_buffering ) + return VLC_EGENERIC; + + es_out_pgrm_t *p_pgrm = p_sys->p_pgrm; + if( !p_pgrm ) + return VLC_EGENERIC; + + const bool b_absolute = va_arg( args, int ); + const vlc_tick_t i_system = va_arg( args, vlc_tick_t ); + input_clock_ChangeSystemOrigin( p_pgrm->p_input_clock, b_absolute, i_system ); + return VLC_SUCCESS; + } + + case ES_OUT_POST_SUBNODE: + { + input_thread_t *input = p_sys->p_input; + input_item_node_t *node = va_arg(args, input_item_node_t *); + input_SendEventParsing(input, node); + input_item_node_Delete(node); + + return VLC_SUCCESS; + } + + case ES_OUT_VOUT_SET_MOUSE_EVENT: + { + es_out_id_t *p_es = va_arg( args, es_out_id_t * ); + + if( !p_es || p_es->fmt.i_cat != VIDEO_ES ) + return VLC_EGENERIC; + + p_es->mouse_event_cb = va_arg( args, vlc_mouse_event ); + p_es->mouse_event_userdata = va_arg( args, void * ); + + if( p_es->p_dec ) + input_DecoderSetVoutMouseEvent( p_es->p_dec, + p_es->mouse_event_cb, p_es->mouse_event_userdata ); + + return VLC_SUCCESS; + } + case ES_OUT_VOUT_ADD_OVERLAY: + { + es_out_id_t *p_es = va_arg( args, es_out_id_t * ); + subpicture_t *sub = va_arg( args, subpicture_t * ); + 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_DEL_OVERLAY: + { + es_out_id_t *p_es = va_arg( args, es_out_id_t * ); + size_t channel = va_arg( args, size_t ); + if( p_es && p_es->fmt.i_cat == VIDEO_ES && p_es->p_dec ) + return input_DecoderDelVoutOverlay( p_es->p_dec, channel ); + return VLC_EGENERIC; + } + case ES_OUT_SPU_SET_HIGHLIGHT: + { + es_out_id_t *p_es = va_arg( args, es_out_id_t * ); + const vlc_spu_highlight_t *spu_hl = + va_arg( args, const vlc_spu_highlight_t * ); + if( p_es && p_es->fmt.i_cat == SPU_ES && p_es->p_dec ) + return input_DecoderSetSpuHighlight( p_es->p_dec, spu_hl ); + return VLC_EGENERIC; + } + default: + msg_Err( p_sys->p_input, "unknown query 0x%x in %s", i_query, + __func__ ); + return VLC_EGENERIC; + } +} + +static int EsOutVaPrivControlLocked( es_out_t *out, int query, va_list args ) +{ + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out); + + switch (query) + { + case ES_OUT_PRIV_SET_MODE: + { + const int i_mode = va_arg( args, int ); + assert( i_mode == ES_OUT_MODE_NONE || i_mode == ES_OUT_MODE_ALL || + i_mode == ES_OUT_MODE_AUTO || i_mode == ES_OUT_MODE_PARTIAL || + i_mode == ES_OUT_MODE_END ); + + if (i_mode != ES_OUT_MODE_NONE && !p_sys->b_active && !vlc_list_is_empty(&p_sys->es)) + { + /* XXX Terminate vout if there are tracks but no video one. + * This one is not mandatory but is he earliest place where it + * can be done */ + es_out_id_t *p_es; + bool found = false; + + foreach_es_then_es_slaves(p_es) + if( p_es->fmt.i_cat == VIDEO_ES && !found /* nested loop */ ) + { + found = true; + break; + } + + if (!found) + EsOutStopFreeVout( out ); + } + p_sys->b_active = i_mode != ES_OUT_MODE_NONE; + p_sys->i_mode = i_mode; + + /* Reapply policy mode */ + es_out_id_t *es; + + foreach_es_then_es_slaves(es) + { + if (EsIsSelected(es)) + EsOutUnselectEs(out, es, es->p_pgrm == p_sys->p_pgrm); + } + foreach_es_then_es_slaves(es) + { + EsOutSelect(out, es, false); + } + + if( i_mode == ES_OUT_MODE_END ) + EsOutTerminate( out ); + return VLC_SUCCESS; + } + case ES_OUT_PRIV_GET_WAKE_UP: { vlc_tick_t *pi_wakeup = va_arg( args, vlc_tick_t* ); *pi_wakeup = EsOutGetWakeup( out ); return VLC_SUCCESS; } - - case ES_OUT_SET_ES_BY_ID: - case ES_OUT_RESTART_ES_BY_ID: - case ES_OUT_SET_ES_DEFAULT_BY_ID: + case ES_OUT_PRIV_SET_ES_LIST: + { + enum es_format_category_e cat = va_arg( args, enum es_format_category_e ); + vlc_es_id_t *const*es_id_list = va_arg( args, vlc_es_id_t ** ); + EsOutSelectList( out, cat, es_id_list ); + return VLC_SUCCESS; + } + case ES_OUT_PRIV_SET_AUTOSELECT: + { + int i_cat = va_arg( args, int ); + bool b_enabled = va_arg( args, int ); + switch ( i_cat ) + { + case VIDEO_ES: + p_sys->video.b_autoselect = b_enabled; + break; + case AUDIO_ES: + p_sys->audio.b_autoselect = b_enabled; + break; + case SPU_ES: + p_sys->sub.b_autoselect = b_enabled; + break; + default: + return VLC_EGENERIC; + } + return VLC_SUCCESS; + } + case ES_OUT_PRIV_SET_ES_BY_ID: + case ES_OUT_PRIV_RESTART_ES_BY_ID: + case ES_OUT_PRIV_SET_ES_DEFAULT_BY_ID: { const int i_id = va_arg( args, int ); es_out_id_t *p_es = EsOutGetFromID( out, i_id ); int i_new_query = 0; - switch( i_query ) + switch( query ) { - case ES_OUT_SET_ES_BY_ID: i_new_query = ES_OUT_SET_ES; + case ES_OUT_PRIV_SET_ES_BY_ID: + i_new_query = ES_OUT_SET_ES; p_es->b_forced = va_arg( args, int ); break; - case ES_OUT_RESTART_ES_BY_ID: i_new_query = ES_OUT_RESTART_ES; break; - case ES_OUT_SET_ES_DEFAULT_BY_ID: i_new_query = ES_OUT_SET_ES_DEFAULT; break; + case ES_OUT_PRIV_RESTART_ES_BY_ID: + i_new_query = ES_OUT_RESTART_ES; + break; + case ES_OUT_PRIV_SET_ES_DEFAULT_BY_ID: + i_new_query = ES_OUT_SET_ES_DEFAULT; + break; default: vlc_assert_unreachable(); } @@ -3267,44 +3341,76 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) return i_ret; } + case ES_OUT_PRIV_STOP_ALL_ES: + { + es_out_id_t *es; + int count = 0; + + foreach_es_then_es_slaves(es) + count++; + + int *selected_es = vlc_alloc(count + 1, sizeof(int)); + if (!selected_es) + return VLC_ENOMEM; - case ES_OUT_GET_BUFFERING: + *va_arg(args, void **) = selected_es; + *selected_es = count; + + foreach_es_then_es_slaves(es) + { + if (EsIsSelected(es)) + { + EsOutDestroyDecoder(out, es); + *++selected_es = es->fmt.i_id; + } + else + *++selected_es = -1; + } + return VLC_SUCCESS; + } + case ES_OUT_PRIV_START_ALL_ES: { - bool *pb = va_arg( args, bool* ); - *pb = p_sys->b_buffering; + int *selected_es = va_arg( args, void * ); + int count = selected_es[0]; + for( int i = 0; i < count; ++i ) + { + int i_id = selected_es[i + 1]; + if( i_id != -1 ) + { + es_out_id_t *p_es = EsOutGetFromID( out, i_id ); + EsOutCreateDecoder( out, p_es ); + } + } + free(selected_es); + EsOutStopFreeVout( out ); return VLC_SUCCESS; } - - case ES_OUT_GET_EMPTY: + case ES_OUT_PRIV_GET_BUFFERING: { bool *pb = va_arg( args, bool* ); - *pb = EsOutDecodersIsEmpty( out ); + *pb = p_sys->b_buffering; return VLC_SUCCESS; } - - case ES_OUT_SET_ES_DELAY: + case ES_OUT_PRIV_SET_ES_DELAY: { es_out_id_t *es = va_arg(args, es_out_id_t *); const vlc_tick_t delay = va_arg(args, vlc_tick_t); EsOutSetEsDelay(out, es, delay); return VLC_SUCCESS; } - - case ES_OUT_SET_DELAY: + case ES_OUT_PRIV_SET_DELAY: { const int i_cat = va_arg( args, int ); const vlc_tick_t i_delay = va_arg( args, vlc_tick_t ); EsOutSetDelay( out, i_cat, i_delay ); return VLC_SUCCESS; } - - case ES_OUT_SET_RECORD_STATE: + case ES_OUT_PRIV_SET_RECORD_STATE: { bool b = va_arg( args, int ); return EsOutSetRecord( out, b ); } - - case ES_OUT_SET_PAUSE_STATE: + case ES_OUT_PRIV_SET_PAUSE_STATE: { const bool b_source_paused = (bool)va_arg( args, int ); const bool b_paused = (bool)va_arg( args, int ); @@ -3315,8 +3421,7 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_SUCCESS; } - - case ES_OUT_SET_RATE: + case ES_OUT_PRIV_SET_RATE: { const float src_rate = va_arg( args, double ); const float rate = va_arg( args, double ); @@ -3326,12 +3431,10 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_SUCCESS; } - - case ES_OUT_SET_FRAME_NEXT: + case ES_OUT_PRIV_SET_FRAME_NEXT: EsOutFrameNext( out ); return VLC_SUCCESS; - - case ES_OUT_SET_TIMES: + case ES_OUT_PRIV_SET_TIMES: { double f_position = va_arg( args, double ); vlc_tick_t i_time = va_arg( args, vlc_tick_t ); @@ -3371,7 +3474,7 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) i_normal_time, i_length ); return VLC_SUCCESS; } - case ES_OUT_SET_JITTER: + case ES_OUT_PRIV_SET_JITTER: { vlc_tick_t i_pts_delay = va_arg( args, vlc_tick_t ); vlc_tick_t i_pts_jitter = va_arg( args, vlc_tick_t ); @@ -3404,37 +3507,13 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) } return VLC_SUCCESS; } - - case ES_OUT_GET_PCR_SYSTEM: + case ES_OUT_PRIV_GET_GROUP_FORCED: { - if( p_sys->b_buffering ) - return VLC_EGENERIC; - - es_out_pgrm_t *p_pgrm = p_sys->p_pgrm; - if( !p_pgrm ) - return VLC_EGENERIC; - - vlc_tick_t *pi_system = va_arg( args, vlc_tick_t *); - vlc_tick_t *pi_delay = va_arg( args, vlc_tick_t *); - input_clock_GetSystemOrigin( p_pgrm->p_input_clock, pi_system, pi_delay ); - return VLC_SUCCESS; - } - - case ES_OUT_MODIFY_PCR_SYSTEM: - { - if( p_sys->b_buffering ) - return VLC_EGENERIC; - - es_out_pgrm_t *p_pgrm = p_sys->p_pgrm; - if( !p_pgrm ) - return VLC_EGENERIC; - - const bool b_absolute = va_arg( args, int ); - const vlc_tick_t i_system = va_arg( args, vlc_tick_t ); - input_clock_ChangeSystemOrigin( p_pgrm->p_input_clock, b_absolute, i_system ); + int *pi_group = va_arg( args, int * ); + *pi_group = p_sys->i_group_id; return VLC_SUCCESS; } - case ES_OUT_SET_EOS: + case ES_OUT_PRIV_SET_EOS: { es_out_id_t *id; foreach_es_then_es_slaves(id) @@ -3442,61 +3521,8 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) input_DecoderDrain(id->p_dec); return VLC_SUCCESS; } - - case ES_OUT_POST_SUBNODE: - { - input_thread_t *input = p_sys->p_input; - input_item_node_t *node = va_arg(args, input_item_node_t *); - input_SendEventParsing(input, node); - input_item_node_Delete(node); - - return VLC_SUCCESS; - } - - case ES_OUT_VOUT_SET_MOUSE_EVENT: - { - es_out_id_t *p_es = va_arg( args, es_out_id_t * ); - - if( !p_es || p_es->fmt.i_cat != VIDEO_ES ) - return VLC_EGENERIC; - - p_es->mouse_event_cb = va_arg( args, vlc_mouse_event ); - p_es->mouse_event_userdata = va_arg( args, void * ); - - if( p_es->p_dec ) - input_DecoderSetVoutMouseEvent( p_es->p_dec, - p_es->mouse_event_cb, p_es->mouse_event_userdata ); - - return VLC_SUCCESS; - } - case ES_OUT_VOUT_ADD_OVERLAY: - { - es_out_id_t *p_es = va_arg( args, es_out_id_t * ); - subpicture_t *sub = va_arg( args, subpicture_t * ); - 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_DEL_OVERLAY: - { - es_out_id_t *p_es = va_arg( args, es_out_id_t * ); - size_t channel = va_arg( args, size_t ); - if( p_es && p_es->fmt.i_cat == VIDEO_ES && p_es->p_dec ) - return input_DecoderDelVoutOverlay( p_es->p_dec, channel ); - return VLC_EGENERIC; - } - case ES_OUT_SPU_SET_HIGHLIGHT: - { - es_out_id_t *p_es = va_arg( args, es_out_id_t * ); - const vlc_spu_highlight_t *spu_hl = - va_arg( args, const vlc_spu_highlight_t * ); - if( p_es && p_es->fmt.i_cat == SPU_ES && p_es->p_dec ) - return input_DecoderSetSpuHighlight( p_es->p_dec, spu_hl ); - return VLC_EGENERIC; - } - case ES_OUT_SET_VBI_PAGE: - case ES_OUT_SET_VBI_TRANSPARENCY: + case ES_OUT_PRIV_SET_VBI_PAGE: + case ES_OUT_PRIV_SET_VBI_TRANSPARENCY: { es_out_id_t *es = va_arg( args, es_out_id_t * ); assert(es); @@ -3505,7 +3531,7 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) return VLC_EGENERIC; int ret; - if( i_query == ES_OUT_SET_VBI_PAGE ) + if( query == ES_OUT_PRIV_SET_VBI_PAGE ) { unsigned page = va_arg( args, unsigned ); ret = var_SetInteger( es->p_dec, "vbi-page", page ); @@ -3521,32 +3547,11 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args ) } return ret; } - case ES_OUT_SET_AUTOSELECT: - { - int i_cat = va_arg( args, int ); - bool b_enabled = va_arg( args, int ); - switch ( i_cat ) - { - case VIDEO_ES: - p_sys->video.b_autoselect = b_enabled; - break; - case AUDIO_ES: - p_sys->audio.b_autoselect = b_enabled; - break; - case SPU_ES: - p_sys->sub.b_autoselect = b_enabled; - break; - default: - return VLC_EGENERIC; - } - return VLC_SUCCESS; - } - default: - msg_Err( p_sys->p_input, "unknown query 0x%x in %s", i_query, - __func__ ); - return VLC_EGENERIC; + default: vlc_assert_unreachable(); } + } + static int EsOutControl( es_out_t *out, int i_query, va_list args ) { es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out); @@ -3559,6 +3564,27 @@ static int EsOutControl( es_out_t *out, int i_query, va_list args ) return i_ret; } +static int EsOutPrivControlLocked( es_out_t *out, int i_query, ... ) +{ + va_list args; + + va_start( args, i_query ); + int ret = EsOutVaPrivControlLocked( out, i_query, args ); + va_end( args ); + return ret; +} + +static int EsOutPrivControl( es_out_t *out, int query, va_list args ) +{ + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out); + + vlc_mutex_lock( &p_sys->lock ); + int ret = EsOutVaPrivControlLocked( out, query, args ); + vlc_mutex_unlock( &p_sys->lock ); + + return ret; +} + static const struct es_out_callbacks es_out_cbs = { .add = EsOutAdd, @@ -3566,6 +3592,7 @@ static const struct es_out_callbacks es_out_cbs = .del = EsOutDel, .control = EsOutControl, .destroy = EsOutDelete, + .priv_control = EsOutPrivControl, }; /**************************************************************************** diff --git a/src/input/es_out.h b/src/input/es_out.h index 780dd12bd4..69c9130092 100644 --- a/src/input/es_out.h +++ b/src/input/es_out.h @@ -38,78 +38,93 @@ enum es_out_mode_e enum es_out_query_private_e { /* set/get mode */ - ES_OUT_SET_MODE = ES_OUT_PRIVATE_START, /* arg1= int */ + ES_OUT_PRIV_SET_MODE, /* arg1= int */ /* Get date to wait before demuxing more data */ - ES_OUT_GET_WAKE_UP, /* arg1=vlc_tick_t* res=cannot fail */ + ES_OUT_PRIV_GET_WAKE_UP, /* arg1=vlc_tick_t* res=cannot fail */ /* Select a list of ES */ - ES_OUT_SET_ES_LIST, /* arg1= es_out_id_t *const* (null terminated array) */ + ES_OUT_PRIV_SET_ES_LIST, /* arg1= es_out_id_t *const* (null terminated array) */ /* Disable autoselection of tracks from a given category */ - ES_OUT_SET_AUTOSELECT, /* arg1= int (es category), - arg2= int (enabled/disabled), res=can fail */ + ES_OUT_PRIV_SET_AUTOSELECT, /* arg1= int (es category), + arg2= int (enabled/disabled), res=can fail */ /* Wrapper for some ES command to work with id */ - ES_OUT_SET_ES_BY_ID, /* arg1= int, arg2= bool (forced) */ - ES_OUT_RESTART_ES_BY_ID, - ES_OUT_SET_ES_DEFAULT_BY_ID, + ES_OUT_PRIV_SET_ES_BY_ID, /* arg1= int, arg2= bool (forced) */ + ES_OUT_PRIV_RESTART_ES_BY_ID, + ES_OUT_PRIV_SET_ES_DEFAULT_BY_ID, /* 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 ** */ - /* Start all ES from the context returned by ES_OUT_STOP_ALL_ES */ - ES_OUT_START_ALL_ES, /* arg1=void * */ + * context or call ES_OUT_PRIV_STOP_ALL_ES */ + ES_OUT_PRIV_STOP_ALL_ES, /* arg1=void ** */ + /* Start all ES from the context returned by ES_OUT_PRIV_STOP_ALL_ES */ + ES_OUT_PRIV_START_ALL_ES, /* arg1=void * */ /* Get buffering state */ - ES_OUT_GET_BUFFERING, /* arg1=bool* res=cannot fail */ + ES_OUT_PRIV_GET_BUFFERING, /* arg1=bool* res=cannot fail */ /* Set delay for an ES identifier */ - ES_OUT_SET_ES_DELAY, /* arg1=es_out_id_t *, res=cannot fail */ + ES_OUT_PRIV_SET_ES_DELAY, /* arg1=es_out_id_t *, res=cannot fail */ /* Set delay for a ES category */ - ES_OUT_SET_DELAY, /* arg1=es_category_e, res=cannot fail */ + ES_OUT_PRIV_SET_DELAY, /* arg1=es_category_e, res=cannot fail */ /* Set record state */ - ES_OUT_SET_RECORD_STATE, /* arg1=bool res=can fail */ + ES_OUT_PRIV_SET_RECORD_STATE, /* arg1=bool res=can fail */ /* Set pause state */ - ES_OUT_SET_PAUSE_STATE, /* arg1=bool b_source_paused, bool b_paused arg2=vlc_tick_t res=can fail */ + ES_OUT_PRIV_SET_PAUSE_STATE, /* arg1=bool b_source_paused, bool b_paused arg2=vlc_tick_t res=can fail */ /* Set rate */ - ES_OUT_SET_RATE, /* arg1=double source_rate arg2=double rate res=can fail */ + ES_OUT_PRIV_SET_RATE, /* arg1=double source_rate arg2=double rate res=can fail */ /* Set next frame */ - ES_OUT_SET_FRAME_NEXT, /* res=can fail */ + ES_OUT_PRIV_SET_FRAME_NEXT, /* res=can fail */ /* Set position/time/length */ - ES_OUT_SET_TIMES, /* arg1=double f_position arg2=vlc_tick_t i_time arg3=vlc_tick_t i_normal_time arg4=vlc_tick_t i_length res=cannot fail */ + ES_OUT_PRIV_SET_TIMES, /* arg1=double f_position arg2=vlc_tick_t i_time arg3=vlc_tick_t i_normal_time arg4=vlc_tick_t i_length res=cannot fail */ /* Set jitter */ - ES_OUT_SET_JITTER, /* arg1=vlc_tick_t i_pts_delay arg2= vlc_tick_t i_pts_jitter, arg2=int i_cr_average res=cannot fail */ + ES_OUT_PRIV_SET_JITTER, /* arg1=vlc_tick_t i_pts_delay arg2= vlc_tick_t i_pts_jitter, arg2=int i_cr_average res=cannot fail */ /* Get forced group */ - ES_OUT_GET_GROUP_FORCED, /* arg1=int * res=cannot fail */ + ES_OUT_PRIV_GET_GROUP_FORCED, /* arg1=int * res=cannot fail */ /* Set End Of Stream */ - ES_OUT_SET_EOS, /* res=cannot fail */ + ES_OUT_PRIV_SET_EOS, /* res=cannot fail */ /* Set a VBI/Teletext page */ - ES_OUT_SET_VBI_PAGE, /* arg1=unsigned res=can fail */ + ES_OUT_PRIV_SET_VBI_PAGE, /* arg1=unsigned res=can fail */ /* Set VBI/Teletext menu transparent */ - ES_OUT_SET_VBI_TRANSPARENCY /* arg1=bool res=can fail */ + ES_OUT_PRIV_SET_VBI_TRANSPARENCY /* arg1=bool res=can fail */ }; +static inline int es_out_vaPrivControl( es_out_t *out, int query, va_list args ) +{ + vlc_assert( out->cbs->priv_control ); + return out->cbs->priv_control( out, query, args ); +} + +static inline int es_out_PrivControl( es_out_t *out, int query, ... ) +{ + va_list args; + va_start( args, query ); + int result = es_out_vaPrivControl( out, query, args ); + va_end( args ); + return result; +} + static inline void es_out_SetMode( es_out_t *p_out, int i_mode ) { - int i_ret = es_out_Control( p_out, ES_OUT_SET_MODE, i_mode ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_MODE, i_mode ); assert( !i_ret ); } static inline vlc_tick_t es_out_GetWakeup( es_out_t *p_out ) { vlc_tick_t i_wu; - int i_ret = es_out_Control( p_out, ES_OUT_GET_WAKE_UP, &i_wu ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_GET_WAKE_UP, &i_wu ); assert( !i_ret ); return i_wu; @@ -117,7 +132,7 @@ static inline vlc_tick_t es_out_GetWakeup( es_out_t *p_out ) static inline bool es_out_GetBuffering( es_out_t *p_out ) { bool b; - int i_ret = es_out_Control( p_out, ES_OUT_GET_BUFFERING, &b ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_GET_BUFFERING, &b ); assert( !i_ret ); return b; @@ -132,55 +147,55 @@ static inline bool es_out_GetEmpty( es_out_t *p_out ) } static inline void es_out_SetEsDelay( es_out_t *p_out, es_out_id_t *es, vlc_tick_t i_delay ) { - int i_ret = es_out_Control( p_out, ES_OUT_SET_ES_DELAY, es, i_delay ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_ES_DELAY, es, i_delay ); assert( !i_ret ); } static inline void es_out_SetDelay( es_out_t *p_out, int i_cat, vlc_tick_t i_delay ) { - int i_ret = es_out_Control( p_out, ES_OUT_SET_DELAY, i_cat, i_delay ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_DELAY, i_cat, i_delay ); assert( !i_ret ); } static inline int es_out_SetRecordState( es_out_t *p_out, bool b_record ) { - return es_out_Control( p_out, ES_OUT_SET_RECORD_STATE, b_record ); + return es_out_PrivControl( p_out, ES_OUT_PRIV_SET_RECORD_STATE, b_record ); } static inline int es_out_SetPauseState( es_out_t *p_out, bool b_source_paused, bool b_paused, vlc_tick_t i_date ) { - return es_out_Control( p_out, ES_OUT_SET_PAUSE_STATE, b_source_paused, b_paused, i_date ); + return es_out_PrivControl( p_out, ES_OUT_PRIV_SET_PAUSE_STATE, b_source_paused, b_paused, i_date ); } static inline int es_out_SetRate( es_out_t *p_out, float source_rate, float rate ) { - return es_out_Control( p_out, ES_OUT_SET_RATE, source_rate, rate ); + return es_out_PrivControl( p_out, ES_OUT_PRIV_SET_RATE, source_rate, rate ); } static inline int es_out_SetFrameNext( es_out_t *p_out ) { - return es_out_Control( p_out, ES_OUT_SET_FRAME_NEXT ); + return es_out_PrivControl( p_out, ES_OUT_PRIV_SET_FRAME_NEXT ); } static inline void es_out_SetTimes( es_out_t *p_out, double f_position, vlc_tick_t i_time, vlc_tick_t i_normal_time, vlc_tick_t i_length ) { - int i_ret = es_out_Control( p_out, ES_OUT_SET_TIMES, f_position, i_time, - i_normal_time, i_length ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_TIMES, f_position, i_time, + i_normal_time, i_length ); assert( !i_ret ); } static inline void es_out_SetJitter( es_out_t *p_out, vlc_tick_t i_pts_delay, vlc_tick_t i_pts_jitter, int i_cr_average ) { - int i_ret = es_out_Control( p_out, ES_OUT_SET_JITTER, - i_pts_delay, i_pts_jitter, i_cr_average ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_JITTER, + i_pts_delay, i_pts_jitter, i_cr_average ); assert( !i_ret ); } static inline int es_out_GetGroupForced( es_out_t *p_out ) { int i_group; - int i_ret = es_out_Control( p_out, ES_OUT_GET_GROUP_FORCED, &i_group ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_GET_GROUP_FORCED, &i_group ); assert( !i_ret ); return i_group; } static inline void es_out_Eos( es_out_t *p_out ) { - int i_ret = es_out_Control( p_out, ES_OUT_SET_EOS ); + int i_ret = es_out_PrivControl( p_out, ES_OUT_PRIV_SET_EOS ); assert( !i_ret ); } diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c index ff43fe1581..ff8de86b82 100644 --- a/src/input/es_out_timeshift.c +++ b/src/input/es_out_timeshift.c @@ -130,22 +130,31 @@ typedef struct attribute_packed int i_cat; int i_policy; } es_policy; + } u; +} ts_cmd_control_t; + +typedef struct attribute_packed +{ + int i_query; + + union + { + int i_int; + struct + { + vlc_tick_t i_pts_delay; + vlc_tick_t i_pts_jitter; + int i_cr_average; + } jitter; struct { - /* FIXME Really too big (double make the whole thing too big) */ double f_position; vlc_tick_t i_time; vlc_tick_t i_normal_time; vlc_tick_t i_length; } times; - struct - { - vlc_tick_t i_pts_delay; - vlc_tick_t i_pts_jitter; - int i_cr_average; - } jitter; } u; -} ts_cmd_control_t; +} ts_cmd_privcontrol_t; typedef struct attribute_packed { @@ -157,6 +166,7 @@ typedef struct attribute_packed ts_cmd_del_t del; ts_cmd_send_t send; ts_cmd_control_t control; + ts_cmd_privcontrol_t privcontrol; } u; } ts_cmd_t; @@ -278,6 +288,7 @@ static int CmdInitAdd ( ts_cmd_t *, es_out_id_t *, const es_format_t *, bool static void CmdInitSend ( ts_cmd_t *, es_out_id_t *, block_t * ); static int CmdInitDel ( ts_cmd_t *, es_out_id_t * ); static int CmdInitControl( ts_cmd_t *, int i_query, va_list, bool b_copy ); +static int CmdInitPrivControl( ts_cmd_t *, int i_query, va_list, bool b_copy ); /* */ static void CmdCleanAdd ( ts_cmd_t * ); @@ -289,6 +300,7 @@ static void CmdExecuteAdd ( es_out_t *, ts_cmd_t * ); static int CmdExecuteSend ( es_out_t *, ts_cmd_t * ); static void CmdExecuteDel ( es_out_t *, ts_cmd_t * ); static int CmdExecuteControl( es_out_t *, ts_cmd_t * ); +static int CmdExecutePrivControl( es_out_t *, ts_cmd_t * ); /* File helpers */ static int GetTmpFile( char **ppsz_file, const char *psz_path ); @@ -602,7 +614,6 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args ) switch( i_query ) { /* Pass-through control */ - case ES_OUT_SET_MODE: case ES_OUT_SET_GROUP: case ES_OUT_SET_PCR: case ES_OUT_SET_GROUP_PCR: @@ -622,9 +633,6 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args ) case ES_OUT_SET_ES_STATE: case ES_OUT_SET_ES_CAT_POLICY: case ES_OUT_SET_ES_FMT: - case ES_OUT_SET_TIMES: - case ES_OUT_SET_JITTER: - case ES_OUT_SET_EOS: { ts_cmd_t cmd; if( CmdInitControl( &cmd, i_query, args, p_sys->b_delayed ) ) @@ -686,17 +694,80 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args ) bool *pb_empty = va_arg( args, bool* ); return ControlLockedGetEmpty( p_out, pb_empty ); } - case ES_OUT_GET_WAKE_UP: /* TODO ? */ + + case ES_OUT_GET_PCR_SYSTEM: + if( p_sys->b_delayed ) + return VLC_EGENERIC; + /* fall through */ + case ES_OUT_POST_SUBNODE: + return es_out_vaControl( p_sys->p_out, i_query, args ); + + case ES_OUT_MODIFY_PCR_SYSTEM: + { + const bool b_absolute = va_arg( args, int ); + const vlc_tick_t i_system = va_arg( args, vlc_tick_t ); + + if( b_absolute && p_sys->b_delayed ) + return VLC_EGENERIC; + + return es_out_ControlModifyPcrSystem( p_sys->p_out, b_absolute, i_system ); + } + + default: + vlc_assert_unreachable(); + return VLC_EGENERIC; + } +} + +static int Control( es_out_t *p_out, int i_query, va_list args ) +{ + es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out); + int i_ret; + + vlc_mutex_lock( &p_sys->lock ); + + TsAutoStop( p_out ); + + i_ret = ControlLocked( p_out, i_query, args ); + + vlc_mutex_unlock( &p_sys->lock ); + + return i_ret; +} + +static int PrivControlLocked( es_out_t *p_out, int i_query, va_list args ) +{ + es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out); + + switch( i_query ) + { + /* Pass-through control */ + case ES_OUT_PRIV_SET_MODE: + case ES_OUT_PRIV_SET_TIMES: + case ES_OUT_PRIV_SET_JITTER: + case ES_OUT_PRIV_SET_EOS: + { + ts_cmd_t cmd; + if( CmdInitPrivControl( &cmd, i_query, args, p_sys->b_delayed ) ) + return VLC_EGENERIC; + if( p_sys->b_delayed ) + { + TsPushCmd( p_sys->p_ts, &cmd ); + return VLC_SUCCESS; + } + return CmdExecutePrivControl( p_sys->p_out, &cmd ); + } + case ES_OUT_PRIV_GET_WAKE_UP: /* TODO ? */ { vlc_tick_t *pi_wakeup = va_arg( args, vlc_tick_t* ); return ControlLockedGetWakeup( p_out, pi_wakeup ); } - case ES_OUT_GET_BUFFERING: + case ES_OUT_PRIV_GET_BUFFERING: { bool *pb_buffering = va_arg( args, bool* ); return ControlLockedGetBuffering( p_out, pb_buffering ); } - case ES_OUT_SET_PAUSE_STATE: + case ES_OUT_PRIV_SET_PAUSE_STATE: { const bool b_source_paused = (bool)va_arg( args, int ); const bool b_paused = (bool)va_arg( args, int ); @@ -704,55 +775,36 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args ) return ControlLockedSetPauseState( p_out, b_source_paused, b_paused, i_date ); } - case ES_OUT_SET_RATE: + case ES_OUT_PRIV_SET_RATE: { const float src_rate = va_arg( args, double ); const float rate = va_arg( args, double ); return ControlLockedSetRate( p_out, src_rate, rate ); } - case ES_OUT_SET_FRAME_NEXT: + case ES_OUT_PRIV_SET_FRAME_NEXT: { return ControlLockedSetFrameNext( p_out ); } - - case ES_OUT_GET_PCR_SYSTEM: - if( p_sys->b_delayed ) - return VLC_EGENERIC; - /* fall through */ - case ES_OUT_GET_GROUP_FORCED: - case ES_OUT_POST_SUBNODE: - return es_out_vaControl( p_sys->p_out, i_query, args ); - - case ES_OUT_MODIFY_PCR_SYSTEM: - { - const bool b_absolute = va_arg( args, int ); - const vlc_tick_t i_system = va_arg( args, vlc_tick_t ); - - if( b_absolute && p_sys->b_delayed ) - return VLC_EGENERIC; - - return es_out_ControlModifyPcrSystem( p_sys->p_out, b_absolute, i_system ); - } - + case ES_OUT_PRIV_GET_GROUP_FORCED: + return es_out_vaPrivControl( p_sys->p_out, i_query, args ); /* Invalid queries for this es_out level */ - case ES_OUT_SET_ES_BY_ID: - case ES_OUT_SET_ES_LIST: - case ES_OUT_RESTART_ES_BY_ID: - case ES_OUT_SET_ES_DEFAULT_BY_ID: - case ES_OUT_STOP_ALL_ES: - case ES_OUT_START_ALL_ES: - case ES_OUT_SET_ES_DELAY: - case ES_OUT_SET_DELAY: - case ES_OUT_SET_RECORD_STATE: - case ES_OUT_SET_VBI_PAGE: - case ES_OUT_SET_VBI_TRANSPARENCY: - default: - vlc_assert_unreachable(); - return VLC_EGENERIC; + case ES_OUT_PRIV_SET_ES_LIST: + case ES_OUT_PRIV_SET_ES_BY_ID: + case ES_OUT_PRIV_RESTART_ES_BY_ID: + case ES_OUT_PRIV_SET_ES_DEFAULT_BY_ID: + case ES_OUT_PRIV_STOP_ALL_ES: + case ES_OUT_PRIV_START_ALL_ES: + case ES_OUT_PRIV_SET_ES_DELAY: + case ES_OUT_PRIV_SET_DELAY: + case ES_OUT_PRIV_SET_RECORD_STATE: + case ES_OUT_PRIV_SET_VBI_PAGE: + case ES_OUT_PRIV_SET_VBI_TRANSPARENCY: + default: vlc_assert_unreachable(); } } -static int Control( es_out_t *p_out, int i_query, va_list args ) + +static int PrivControl( es_out_t *p_out, int i_query, va_list args ) { es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out); int i_ret; @@ -761,7 +813,7 @@ static int Control( es_out_t *p_out, int i_query, va_list args ) TsAutoStop( p_out ); - i_ret = ControlLocked( p_out, i_query, args ); + i_ret = PrivControlLocked( p_out, i_query, args ); vlc_mutex_unlock( &p_sys->lock ); @@ -775,6 +827,7 @@ static const struct es_out_callbacks es_out_timeshift_cbs = .del = Del, .control = Control, .destroy = Destroy, + .priv_control = PrivControl, }; /***************************************************************************** @@ -1388,7 +1441,6 @@ static int CmdInitControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_co switch( i_query ) { /* Pass-through control */ - case ES_OUT_SET_MODE: /* arg1= int */ case ES_OUT_SET_GROUP: /* arg1= int */ case ES_OUT_DEL_GROUP: /* arg1=int i_group */ p_cmd->u.control.u.i_int = va_arg( args, int ); @@ -1410,7 +1462,6 @@ static int CmdInitControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_co break; case ES_OUT_RESET_PCR: /* no arg */ - case ES_OUT_SET_EOS: break; case ES_OUT_SET_META: /* arg1=const vlc_meta_t* */ @@ -1511,31 +1562,6 @@ static int CmdInitControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_co } break; } - case ES_OUT_SET_TIMES: - { - double f_position = va_arg( args, double ); - vlc_tick_t i_time = va_arg( args, vlc_tick_t ); - vlc_tick_t i_normal_time = va_arg( args, vlc_tick_t ); - vlc_tick_t i_length = va_arg( args, vlc_tick_t ); - - p_cmd->u.control.u.times.f_position = f_position; - p_cmd->u.control.u.times.i_time = i_time; - p_cmd->u.control.u.times.i_normal_time = i_normal_time; - p_cmd->u.control.u.times.i_length = i_length; - break; - } - case ES_OUT_SET_JITTER: - { - vlc_tick_t i_pts_delay = va_arg( args, vlc_tick_t ); - vlc_tick_t i_pts_jitter = va_arg( args, vlc_tick_t ); - int i_cr_average = va_arg( args, int ); - - p_cmd->u.control.u.jitter.i_pts_delay = i_pts_delay; - p_cmd->u.control.u.jitter.i_pts_jitter = i_pts_jitter; - p_cmd->u.control.u.jitter.i_cr_average = i_cr_average; - break; - } - default: vlc_assert_unreachable(); return VLC_EGENERIC; @@ -1550,7 +1576,6 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd ) switch( i_query ) { /* Pass-through control */ - case ES_OUT_SET_MODE: /* arg1= int */ case ES_OUT_SET_GROUP: /* arg1= int */ case ES_OUT_DEL_GROUP: /* arg1=int i_group */ return es_out_Control( p_out, i_query, p_cmd->u.control.u.i_int ); @@ -1564,7 +1589,6 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd ) p_cmd->u.control.u.int_i64.i_i64 ); case ES_OUT_RESET_PCR: /* no arg */ - case ES_OUT_SET_EOS: return es_out_Control( p_out, i_query ); case ES_OUT_SET_GROUP_META: /* arg1=int i_group arg2=const vlc_meta_t* */ @@ -1609,16 +1633,6 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd ) return es_out_Control( p_out, i_query, p_cmd->u.control.u.es_fmt.p_es->p_es, p_cmd->u.control.u.es_fmt.p_fmt ); - case ES_OUT_SET_TIMES: - return es_out_Control( p_out, i_query, p_cmd->u.control.u.times.f_position, - p_cmd->u.control.u.times.i_time, - p_cmd->u.control.u.times.i_normal_time, - p_cmd->u.control.u.times.i_length ); - case ES_OUT_SET_JITTER: - return es_out_Control( p_out, i_query, p_cmd->u.control.u.jitter.i_pts_delay, - p_cmd->u.control.u.jitter.i_pts_jitter, - p_cmd->u.control.u.jitter.i_cr_average ); - default: vlc_assert_unreachable(); return VLC_EGENERIC; @@ -1651,6 +1665,76 @@ static void CmdCleanControl( ts_cmd_t *p_cmd ) } } +static int CmdInitPrivControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_copy ) +{ + VLC_UNUSED( b_copy ); + p_cmd->i_type = C_CONTROL; + p_cmd->i_date = vlc_tick_now(); + p_cmd->u.privcontrol.i_query = i_query; + + switch( i_query ) + { + /* Pass-through control */ + case ES_OUT_PRIV_SET_MODE: /* arg1= int */ + p_cmd->u.privcontrol.u.i_int = va_arg( args, int ); + break; + case ES_OUT_PRIV_SET_JITTER: + { + vlc_tick_t i_pts_delay = va_arg( args, vlc_tick_t ); + vlc_tick_t i_pts_jitter = va_arg( args, vlc_tick_t ); + int i_cr_average = va_arg( args, int ); + + p_cmd->u.privcontrol.u.jitter.i_pts_delay = i_pts_delay; + p_cmd->u.privcontrol.u.jitter.i_pts_jitter = i_pts_jitter; + p_cmd->u.privcontrol.u.jitter.i_cr_average = i_cr_average; + break; + } + case ES_OUT_PRIV_SET_TIMES: + { + double f_position = va_arg( args, double ); + vlc_tick_t i_time = va_arg( args, vlc_tick_t ); + vlc_tick_t i_normal_time = va_arg( args, vlc_tick_t ); + vlc_tick_t i_length = va_arg( args, vlc_tick_t ); + + p_cmd->u.privcontrol.u.times.f_position = f_position; + p_cmd->u.privcontrol.u.times.i_time = i_time; + p_cmd->u.privcontrol.u.times.i_normal_time = i_normal_time; + p_cmd->u.privcontrol.u.times.i_length = i_length; + break; + } + case ES_OUT_PRIV_SET_EOS: /* no arg */ + break; + default: vlc_assert_unreachable(); + } + + return VLC_SUCCESS; +} + +static int CmdExecutePrivControl( es_out_t *p_out, ts_cmd_t *p_cmd ) +{ + const int i_query = p_cmd->u.privcontrol.i_query; + + switch( i_query ) + { + /* Pass-through control */ + case ES_OUT_PRIV_SET_MODE: /* arg1= int */ + return es_out_PrivControl( p_out, i_query, p_cmd->u.privcontrol.u.i_int ); + case ES_OUT_PRIV_SET_JITTER: + return es_out_PrivControl( p_out, i_query, p_cmd->u.privcontrol.u.jitter.i_pts_delay, + p_cmd->u.privcontrol.u.jitter.i_pts_jitter, + p_cmd->u.privcontrol.u.jitter.i_cr_average ); + case ES_OUT_PRIV_SET_TIMES: + return es_out_PrivControl( p_out, i_query, + p_cmd->u.privcontrol.u.times.f_position, + p_cmd->u.privcontrol.u.times.i_time, + p_cmd->u.privcontrol.u.times.i_normal_time, + p_cmd->u.privcontrol.u.times.i_length ); + case ES_OUT_PRIV_SET_EOS: /* no arg */ + return es_out_PrivControl( p_out, i_query ); + default: vlc_assert_unreachable(); + } +} + static int GetTmpFile( char **filename, const char *dirname ) { if( dirname != NULL diff --git a/src/input/input.c b/src/input/input.c index 74e4f87d8b..36b243aa75 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -2014,9 +2014,9 @@ static bool Control( input_thread_t *p_input, break; case INPUT_CONTROL_SET_ES_LIST: { - if( es_out_Control( input_priv(p_input)->p_es_out_display, - ES_OUT_SET_ES_LIST, param.list.cat, - param.list.ids ) == VLC_SUCCESS ) + if( es_out_PrivControl( input_priv(p_input)->p_es_out_display, + ES_OUT_PRIV_SET_ES_LIST, param.list.cat, + param.list.ids ) == VLC_SUCCESS ) { if( param.list.ids[0] != NULL && param.list.ids[1] == NULL ) demux_Control( input_priv(p_input)->master->p_demux, DEMUX_SET_ES, @@ -2238,8 +2238,8 @@ static bool Control( input_thread_t *p_input, break; void *context; - if( es_out_Control( priv->p_es_out_display, - ES_OUT_STOP_ALL_ES, &context ) != VLC_SUCCESS ) + if( es_out_PrivControl( priv->p_es_out_display, + ES_OUT_PRIV_STOP_ALL_ES, &context ) != VLC_SUCCESS ) break; if ( p_priv->p_renderer ) @@ -2261,23 +2261,23 @@ static bool Control( input_thread_t *p_input, vlc_renderer_item_demux_filter( p_item ) ); } } - es_out_Control( priv->p_es_out_display, ES_OUT_START_ALL_ES, - context ); + es_out_PrivControl( priv->p_es_out_display, ES_OUT_PRIV_START_ALL_ES, + context ); #endif break; } case INPUT_CONTROL_SET_VBI_PAGE: - es_out_Control( priv->p_es_out_display, ES_OUT_SET_VBI_PAGE, - param.vbi_page.id, param.vbi_page.page ); + es_out_PrivControl( priv->p_es_out_display, ES_OUT_PRIV_SET_VBI_PAGE, + param.vbi_page.id, param.vbi_page.page ); break; case INPUT_CONTROL_SET_VBI_TRANSPARENCY: - es_out_Control( priv->p_es_out_display, ES_OUT_SET_VBI_TRANSPARENCY, - param.vbi_transparency.id, - param.vbi_transparency.enabled ); + es_out_PrivControl( priv->p_es_out_display, ES_OUT_PRIV_SET_VBI_TRANSPARENCY, + param.vbi_transparency.id, + param.vbi_transparency.enabled ); break; case INPUT_CONTROL_SET_ES_AUTOSELECT: - es_out_Control( priv->p_es_out_display, ES_OUT_SET_AUTOSELECT, - param.es_autoselect.cat, param.es_autoselect.enabled ); + es_out_PrivControl( priv->p_es_out_display, ES_OUT_PRIV_SET_AUTOSELECT, + param.es_autoselect.cat, param.es_autoselect.enabled ); break; case INPUT_CONTROL_NAV_ACTIVATE: @@ -3306,10 +3306,10 @@ static int input_SlaveSourceAdd( input_thread_t *p_input, assert( priv->i_last_es_id != -1 ); - es_out_Control( priv->p_es_out_display, ES_OUT_SET_ES_DEFAULT_BY_ID, - priv->i_last_es_id ); - es_out_Control( priv->p_es_out_display, ES_OUT_SET_ES_BY_ID, - priv->i_last_es_id, false ); + es_out_PrivControl( priv->p_es_out_display, ES_OUT_PRIV_SET_ES_DEFAULT_BY_ID, + priv->i_last_es_id ); + es_out_PrivControl( priv->p_es_out_display, ES_OUT_PRIV_SET_ES_BY_ID, + priv->i_last_es_id, false ); return VLC_SUCCESS; } diff --git a/test/modules/demux/timestamps_filter.c b/test/modules/demux/timestamps_filter.c index e183938aae..f115fc394d 100644 --- a/test/modules/demux/timestamps_filter.c +++ b/test/modules/demux/timestamps_filter.c @@ -76,6 +76,7 @@ static const struct es_out_callbacks trash_es_out_cbs = trash_es_out_Del, trash_es_out_Control, trash_es_out_Delete, + NULL, }; #define TIMELINE_0 (CLOCK_FREQ) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
