[vlc-devel] [PATCHv2 04/10] es_out: split public and private controls
Thomas Guillem
thomas at gllm.fr
Thu Feb 27 16:19:11 CET 2020
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.
---
include/vlc_es_out.h | 6 +
src/input/es_out.c | 525 ++++++++++++++++++-----------------
src/input/es_out.h | 93 ++++---
src/input/es_out_timeshift.c | 268 ++++++++++++------
src/input/input.c | 36 +--
5 files changed, 530 insertions(+), 398 deletions(-)
diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h
index 06b6a8f338d..5cf5116ab6a 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/src/input/es_out.c b/src/input/es_out.c
index 6955192dc0a..efe0eea13d0 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,7 +728,7 @@ 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,
+ EsOutControlLocked(out, ES_OUT_PRIV_SET_JITTER, p_sys->i_pts_delay,
p_sys->i_pts_jitter, p_sys->i_cr_average);
}
@@ -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 780dd12bd45..421f0d3f40e 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,
+ 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 ff43fe1581d..c78b35160e4 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.control.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 74e4f87d8b6..36b243aa75f 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;
}
--
2.20.1
More information about the vlc-devel
mailing list