[vlc-devel] [RFC PATCHv2 02/18] es_out: also pass ctx from controls

Thomas Guillem thomas at gllm.fr
Tue Feb 18 17:11:15 CET 2020


The es_out ctx will also be needed when searching/creating programs and
progames can be also created from controls.
---
 include/vlc_es_out.h                          |   4 +-
 modules/access/bluray.c                       |   3 +-
 modules/demux/adaptive/plumbing/FakeESOut.cpp |   4 +-
 src/input/es_out.c                            |  36 ++--
 src/input/es_out_ctx.c                        |   6 +-
 src/input/es_out_timeshift.c                  | 170 +++++++++++-------
 6 files changed, 132 insertions(+), 91 deletions(-)

diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h
index 15bcdbc166e..c5424d5438a 100644
--- a/include/vlc_es_out.h
+++ b/include/vlc_es_out.h
@@ -133,7 +133,7 @@ struct es_out_callbacks
     es_out_id_t *(*add)(es_out_t *, es_out_ctx_t *ctx, const es_format_t *);
     int          (*send)(es_out_t *, es_out_id_t *, block_t *);
     void         (*del)(es_out_t *, es_out_id_t *);
-    int          (*control)(es_out_t *, int query, va_list);
+    int          (*control)(es_out_t *, es_out_ctx_t *ctx, int query, va_list);
     void         (*destroy)(es_out_t *);
 };
 
@@ -161,7 +161,7 @@ static inline int es_out_Send( es_out_t *out, es_out_id_t *id,
 
 static inline int es_out_vaControl( es_out_t *out, int i_query, va_list args )
 {
-    return out->cbs->control( out, i_query, args );
+    return out->cbs->control( out, NULL, i_query, args );
 }
 
 static inline int es_out_Control( es_out_t *out, int i_query, ... )
diff --git a/modules/access/bluray.c b/modules/access/bluray.c
index 5e8af77fb90..1b04da2f90a 100644
--- a/modules/access/bluray.c
+++ b/modules/access/bluray.c
@@ -1415,8 +1415,9 @@ static void bluray_esOutDel(es_out_t *p_out, es_out_id_t *p_es)
     vlc_mutex_unlock(&esout_priv->lock);
 }
 
-static int bluray_esOutControl(es_out_t *p_out, int i_query, va_list args)
+static int bluray_esOutControl(es_out_t *p_out, es_out_ctx_t *ctx, int i_query, va_list args)
 {
+    VLC_UNUSED(ctx);
     bluray_esout_priv_t *esout_priv = container_of(p_out, bluray_esout_priv_t, es_out);
     int i_ret;
     vlc_mutex_lock(&esout_priv->lock);
diff --git a/modules/demux/adaptive/plumbing/FakeESOut.cpp b/modules/demux/adaptive/plumbing/FakeESOut.cpp
index 758689989f3..0ba9e10d3d7 100644
--- a/modules/demux/adaptive/plumbing/FakeESOut.cpp
+++ b/modules/demux/adaptive/plumbing/FakeESOut.cpp
@@ -40,7 +40,7 @@ namespace adaptive
             static es_out_id_t *es_out_Add( es_out_t *, es_out_ctx_t *, const es_format_t * );
             static int es_out_Send( es_out_t *, es_out_id_t *, block_t * );
             static void es_out_Del( es_out_t *, es_out_id_t * );
-            static int es_out_Control( es_out_t *, int, va_list );
+            static int es_out_Control( es_out_t *, es_out_ctx_t *ctx, int, va_list );
             static void es_out_Destroy( es_out_t * );
             static const struct es_out_callbacks cbs;
             struct Private
@@ -78,7 +78,7 @@ void EsOutCallbacks::es_out_Del(es_out_t *fakees, es_out_id_t *p_es)
     me->esOutDel(p_es);
 }
 
-int EsOutCallbacks::es_out_Control(es_out_t *fakees, int i_query, va_list args)
+int EsOutCallbacks::es_out_Control(es_out_t *fakees, es_out_ctx_t *, int i_query, va_list args)
 {
     AbstractFakeEsOut *me = container_of(fakees, Private, es_out)->fake;
     return me->esOutControl(i_query, args);
diff --git a/src/input/es_out.c b/src/input/es_out.c
index f9e76b799f7..1c98d85add4 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -243,7 +243,7 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced );
 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 EsOutControlLocked( es_out_t *out, es_out_ctx_t *, int i_query, ... );
 
 static char *LanguageGetName( const char *psz_code );
 static char *LanguageGetCode( const char *psz_lang );
@@ -718,7 +718,8 @@ static bool EsOutDecodersIsEmpty( es_out_t *out )
     return true;
 }
 
-static void EsOutSetEsDelay(es_out_t *out, es_out_id_t *es, vlc_tick_t delay)
+static void EsOutSetEsDelay(es_out_t *out, es_out_ctx_t *ctx,
+                            es_out_id_t *es, vlc_tick_t delay)
 {
     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
 
@@ -729,11 +730,12 @@ 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, ctx, ES_OUT_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 )
+static void EsOutSetDelay( es_out_t *out, es_out_ctx_t *ctx,
+                           int i_cat, vlc_tick_t i_delay )
 {
     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
     es_out_id_t *es;
@@ -747,7 +749,7 @@ 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,
+    EsOutControlLocked(out, ctx, ES_OUT_SET_JITTER, p_sys->i_pts_delay,
                        p_sys->i_pts_jitter, p_sys->i_cr_average);
 }
 
@@ -2695,13 +2697,13 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
     vlc_mutex_unlock( &p_sys->lock );
 }
 
-static int EsOutVaControlLocked( es_out_t *, int, va_list );
-static int EsOutControlLocked( es_out_t *out, int i_query, ... )
+static int EsOutVaControlLocked( es_out_t *, es_out_ctx_t *, int, va_list );
+static int EsOutControlLocked( es_out_t *out, es_out_ctx_t *ctx, int i_query, ... )
 {
     va_list args;
 
     va_start( args, i_query );
-    int ret = EsOutVaControlLocked( out, i_query, args );
+    int ret = EsOutVaControlLocked( out, ctx, i_query, args );
     va_end( args );
     return ret;
 }
@@ -2744,7 +2746,8 @@ static vlc_tick_t EsOutGetTracksDelay(es_out_t *out)
  * \param args a variable list of arguments for the query
  * \return VLC_SUCCESS or an error code
  */
-static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
+static int EsOutVaControlLocked( es_out_t *out, es_out_ctx_t *ctx,
+                                 int i_query, va_list args )
 {
     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
 
@@ -3108,9 +3111,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, ctx, ES_OUT_RESET_PCR );
 
-                EsOutControlLocked( out, ES_OUT_SET_JITTER,
+                EsOutControlLocked( out, ctx, ES_OUT_SET_JITTER,
                                     p_sys->i_pts_delay,
                                     i_new_jitter,
                                     p_sys->i_cr_average );
@@ -3266,7 +3269,7 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
         default:
           vlc_assert_unreachable();
         }
-        int i_ret = EsOutControlLocked( out, i_new_query, p_es );
+        int i_ret = EsOutControlLocked( out, ctx, i_new_query, p_es );
 
         return i_ret;
     }
@@ -3289,7 +3292,7 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
     {
         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);
+        EsOutSetEsDelay(out, ctx, es, delay);
         return VLC_SUCCESS;
     }
 
@@ -3297,7 +3300,7 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
     {
         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 );
+        EsOutSetDelay( out, ctx, i_cat, i_delay );
         return VLC_SUCCESS;
     }
 
@@ -3550,13 +3553,14 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
         return VLC_EGENERIC;
     }
 }
-static int EsOutControl( es_out_t *out, int i_query, va_list args )
+static int EsOutControl( es_out_t *out, es_out_ctx_t *ctx,
+                         int i_query, va_list args )
 {
     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
     int i_ret;
 
     vlc_mutex_lock( &p_sys->lock );
-    i_ret = EsOutVaControlLocked( out, i_query, args );
+    i_ret = EsOutVaControlLocked( out, ctx, i_query, args );
     vlc_mutex_unlock( &p_sys->lock );
 
     return i_ret;
diff --git a/src/input/es_out_ctx.c b/src/input/es_out_ctx.c
index 3adbe46a011..3ef508f35d4 100644
--- a/src/input/es_out_ctx.c
+++ b/src/input/es_out_ctx.c
@@ -120,10 +120,12 @@ static void EsOutContextDel(es_out_t *out, es_out_id_t *es)
     es_out_Del(sys->parent_out, es);
 }
 
-static int EsOutContextControl(es_out_t *out, int query, va_list args)
+static int EsOutContextControl(es_out_t *out, es_out_ctx_t *ctx, int query,
+                               va_list args)
 {
+    assert(ctx == NULL);
     es_out_sys_t *sys = container_of(out, es_out_sys_t, out);
-    return es_out_vaControl(sys->parent_out, query, args);
+    return sys->parent_out->cbs->control(sys->parent_out, sys->ctx, query, args);
 }
 
 static void EsOutContextDestroy(es_out_t *out)
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 9f59e1fb968..a3fd11eb680 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -88,6 +88,7 @@ typedef struct attribute_packed
 
 typedef struct attribute_packed
 {
+    es_out_ctx_t *p_ctx;
     int  i_query;
 
     union
@@ -278,7 +279,7 @@ static void cmd_cleanup_routine( void *p ) { CmdClean( p ); }
 static int  CmdInitAdd    ( ts_cmd_t *, es_out_ctx_t *, es_out_id_t *, const es_format_t *, bool b_copy );
 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  CmdInitControl( ts_cmd_t *, es_out_ctx_t *, int i_query, va_list, bool b_copy );
 
 /* */
 static void CmdCleanAdd    ( ts_cmd_t * );
@@ -481,18 +482,38 @@ static void Del( es_out_t *p_out, es_out_id_t *p_es )
     vlc_mutex_unlock( &p_sys->lock );
 }
 
-static int ControlLockedGetEmpty( es_out_t *p_out, bool *pb_empty )
+static inline int ctx_vaControl( es_out_t *p_out, es_out_ctx_t *p_ctx,
+                                 int i_query, va_list args)
+{
+    return p_out->cbs->control( p_out, p_ctx, i_query, args );
+}
+
+static inline int ctx_Control( es_out_t *p_out, es_out_ctx_t *p_ctx,
+                               int i_query, ... )
+{
+    va_list args;
+    int     i_result;
+
+    va_start( args, i_query );
+    i_result = ctx_vaControl( p_out, p_ctx, i_query, args );
+    va_end( args );
+    return i_result;
+}
+
+static int ControlLockedGetEmpty( es_out_t *p_out, es_out_ctx_t *p_ctx,
+                                  bool *pb_empty )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
 
     if( p_sys->b_delayed && TsHasCmd( p_sys->p_ts ) )
         *pb_empty = false;
     else
-        *pb_empty = es_out_GetEmpty( p_sys->p_out );
+        ctx_Control( p_sys->p_out, p_ctx, ES_OUT_GET_EMPTY, pb_empty );
 
     return VLC_SUCCESS;
 }
-static int ControlLockedGetWakeup( es_out_t *p_out, vlc_tick_t *pi_wakeup )
+static int ControlLockedGetWakeup( es_out_t *p_out, es_out_ctx_t *p_ctx,
+                                   vlc_tick_t *pi_wakeup )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
 
@@ -502,31 +523,32 @@ static int ControlLockedGetWakeup( es_out_t *p_out, vlc_tick_t *pi_wakeup )
         *pi_wakeup = 0;
     }
     else
-    {
-        *pi_wakeup = es_out_GetWakeup( p_sys->p_out );
-    }
+        ctx_Control( p_sys->p_out, p_ctx, ES_OUT_GET_WAKE_UP, pi_wakeup );
 
     return VLC_SUCCESS;
 }
-static int ControlLockedGetBuffering( es_out_t *p_out, bool *pb_buffering )
+static int ControlLockedGetBuffering( es_out_t *p_out, es_out_ctx_t *p_ctx,
+                                      bool *pb_buffering )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
 
     if( p_sys->b_delayed )
         *pb_buffering = true;
     else
-        *pb_buffering = es_out_GetBuffering( p_sys->p_out );
+        ctx_Control( p_sys->p_out, p_ctx, ES_OUT_GET_BUFFERING, pb_buffering );
 
     return VLC_SUCCESS;
 }
-static int ControlLockedSetPauseState( es_out_t *p_out, bool b_source_paused, bool b_paused, vlc_tick_t i_date )
+static int ControlLockedSetPauseState( es_out_t *p_out, es_out_ctx_t *p_ctx,
+                                       bool b_source_paused, bool b_paused, vlc_tick_t i_date )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
     int i_ret;
 
     if( !p_sys->b_delayed && !b_source_paused == !b_paused )
     {
-        i_ret = es_out_SetPauseState( p_sys->p_out, b_source_paused, b_paused, i_date );
+        i_ret = ctx_Control( p_sys->p_out, p_ctx, ES_OUT_SET_PAUSE_STATE,
+                             b_source_paused, b_paused, i_date );
     }
     else
     {
@@ -554,14 +576,15 @@ static int ControlLockedSetPauseState( es_out_t *p_out, bool b_source_paused, bo
     }
     return i_ret;
 }
-static int ControlLockedSetRate( es_out_t *p_out, float src_rate, float rate )
+static int ControlLockedSetRate( es_out_t *p_out, es_out_ctx_t *p_ctx,
+                                 float src_rate, float rate )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
     int i_ret;
 
     if( !p_sys->b_delayed && src_rate == rate )
     {
-        i_ret = es_out_SetRate( p_sys->p_out, src_rate, rate );
+        i_ret = ctx_Control( p_sys->p_out, p_ctx, ES_OUT_SET_RATE, src_rate, rate );
     }
     else
     {
@@ -590,14 +613,15 @@ static int ControlLockedSetRate( es_out_t *p_out, float src_rate, float rate )
     }
     return i_ret;
 }
-static int ControlLockedSetFrameNext( es_out_t *p_out )
+static int ControlLockedSetFrameNext( es_out_t *p_out, es_out_ctx_t *p_ctx )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
 
-    return es_out_SetFrameNext( p_sys->p_out );
+    return ctx_Control( p_sys->p_out, p_ctx, ES_OUT_SET_FRAME_NEXT );
 }
 
-static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
+static int ControlLocked( es_out_t *p_out, es_out_ctx_t *p_ctx, int i_query,
+                          va_list args )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
 
@@ -629,7 +653,7 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
     case ES_OUT_SET_EOS:
     {
         ts_cmd_t cmd;
-        if( CmdInitControl( &cmd, i_query, args, p_sys->b_delayed ) )
+        if( CmdInitControl( &cmd, p_ctx, i_query, args, p_sys->b_delayed ) )
             return VLC_EGENERIC;
         if( p_sys->b_delayed )
         {
@@ -650,53 +674,53 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
             *pb_enabled = true;
             return VLC_SUCCESS;
         }
-        return es_out_Control( p_sys->p_out, ES_OUT_GET_ES_STATE, p_es->p_es, pb_enabled );
+        return ctx_Control( p_sys->p_out, p_ctx, ES_OUT_GET_ES_STATE, p_es->p_es, pb_enabled );
     }
     case ES_OUT_VOUT_SET_MOUSE_EVENT:
     {
         es_out_id_t *p_es = va_arg( args, es_out_id_t * );
         vlc_mouse_event cb = va_arg( args, vlc_mouse_event );
         void *user_data = va_arg( args, void * );
-        return es_out_Control( p_sys->p_out, ES_OUT_VOUT_SET_MOUSE_EVENT,
-                               p_es->p_es, cb, user_data );
+        return ctx_Control( p_sys->p_out, p_ctx, ES_OUT_VOUT_SET_MOUSE_EVENT,
+                            p_es->p_es, cb, user_data );
     }
     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 * );
-        return es_out_Control( p_sys->p_out, ES_OUT_VOUT_ADD_OVERLAY,
-                               p_es->p_es, sub, channel );
+        return ctx_Control( p_sys->p_out, p_ctx, ES_OUT_VOUT_ADD_OVERLAY,
+                            p_es->p_es, sub, channel );
     }
     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 );
-        return es_out_Control( p_sys->p_out, ES_OUT_VOUT_DEL_OVERLAY,
-                               p_es->p_es, channel );
+        return ctx_Control( p_sys->p_out, p_ctx, ES_OUT_VOUT_DEL_OVERLAY,
+                            p_es->p_es, channel );
     }
     case ES_OUT_SPU_SET_HIGHLIGHT:
     {
         es_out_id_t *p_es = va_arg( args, es_out_id_t * );
         const vlc_spu_highlight_t *p_hl = va_arg( args, const vlc_spu_highlight_t * );
-        return es_out_Control( p_sys->p_out, ES_OUT_SPU_SET_HIGHLIGHT,
-                               p_es->p_es, p_hl );
+        return ctx_Control( p_sys->p_out, p_ctx, ES_OUT_SPU_SET_HIGHLIGHT,
+                            p_es->p_es, p_hl );
     }
     /* Special internal input control */
     case ES_OUT_GET_EMPTY:
     {
         bool *pb_empty = va_arg( args, bool* );
-        return ControlLockedGetEmpty( p_out, pb_empty );
+        return ControlLockedGetEmpty( p_out, p_ctx, pb_empty );
     }
     case ES_OUT_GET_WAKE_UP: /* TODO ? */
     {
         vlc_tick_t *pi_wakeup = va_arg( args, vlc_tick_t* );
-        return ControlLockedGetWakeup( p_out, pi_wakeup );
+        return ControlLockedGetWakeup( p_out, p_ctx, pi_wakeup );
     }
     case ES_OUT_GET_BUFFERING:
     {
         bool *pb_buffering = va_arg( args, bool* );
-        return ControlLockedGetBuffering( p_out, pb_buffering );
+        return ControlLockedGetBuffering( p_out, p_ctx, pb_buffering );
     }
     case ES_OUT_SET_PAUSE_STATE:
     {
@@ -704,18 +728,18 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
         const bool b_paused = (bool)va_arg( args, int );
         const vlc_tick_t i_date = va_arg( args, vlc_tick_t );
 
-        return ControlLockedSetPauseState( p_out, b_source_paused, b_paused, i_date );
+        return ControlLockedSetPauseState( p_out, p_ctx, b_source_paused, b_paused, i_date );
     }
     case ES_OUT_SET_RATE:
     {
         const float src_rate = va_arg( args, double );
         const float rate = va_arg( args, double );
 
-        return ControlLockedSetRate( p_out, src_rate, rate );
+        return ControlLockedSetRate( p_out, p_ctx, src_rate, rate );
     }
     case ES_OUT_SET_FRAME_NEXT:
     {
-        return ControlLockedSetFrameNext( p_out );
+        return ControlLockedSetFrameNext( p_out, p_ctx );
     }
 
     case ES_OUT_GET_PCR_SYSTEM:
@@ -724,7 +748,7 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
         /* fall through */
     case ES_OUT_GET_GROUP_FORCED:
     case ES_OUT_POST_SUBNODE:
-        return es_out_vaControl( p_sys->p_out, i_query, args );
+        return ctx_vaControl( p_sys->p_out, p_ctx, i_query, args );
 
     case ES_OUT_MODIFY_PCR_SYSTEM:
     {
@@ -734,7 +758,7 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
         if( b_absolute && p_sys->b_delayed )
             return VLC_EGENERIC;
 
-        return es_out_ControlModifyPcrSystem( p_sys->p_out, b_absolute, i_system );
+        return ctx_Control( p_sys->p_out, p_ctx, i_query, b_absolute, i_system );
     }
 
     /* Invalid queries for this es_out level */
@@ -754,7 +778,7 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
         return VLC_EGENERIC;
     }
 }
-static int Control( es_out_t *p_out, int i_query, va_list args )
+static int Control( es_out_t *p_out, es_out_ctx_t *p_ctx, int i_query, va_list args )
 {
     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
     int i_ret;
@@ -763,7 +787,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 = ControlLocked( p_out, p_ctx, i_query, args );
 
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -1343,9 +1367,9 @@ static void CmdExecuteAdd( es_out_t *p_out, ts_cmd_t *p_cmd )
 static void CmdCleanAdd( ts_cmd_t *p_cmd )
 {
     es_format_Clean( p_cmd->u.add.p_fmt );
-    free( p_cmd->u.add.p_fmt );
     if( p_cmd->u.add.p_ctx )
         es_out_ctx_Release( p_cmd->u.add.p_ctx );
+    free( p_cmd->u.add.p_fmt );
 }
 
 static void CmdInitSend( ts_cmd_t *p_cmd, es_out_id_t *p_es, block_t *p_block )
@@ -1389,12 +1413,18 @@ static void CmdExecuteDel( es_out_t *p_out, ts_cmd_t *p_cmd )
     free( p_cmd->u.del.p_es );
 }
 
-static int CmdInitControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_copy )
+static int CmdInitControl( ts_cmd_t *p_cmd, es_out_ctx_t *p_ctx,
+                           int i_query, va_list args, bool b_copy )
 {
     p_cmd->i_type = C_CONTROL;
     p_cmd->i_date = vlc_tick_now();
     p_cmd->u.control.i_query = i_query;
 
+    if( b_copy )
+        p_cmd->u.control.p_ctx = p_ctx ? es_out_ctx_Hold( p_ctx ) : NULL;
+    else
+        p_cmd->u.control.p_ctx = p_ctx;
+
     switch( i_query )
     {
     /* Pass-through control */
@@ -1556,6 +1586,7 @@ static int CmdInitControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_co
 static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd )
 {
     const int i_query = p_cmd->u.control.i_query;
+    es_out_ctx_t *p_ctx = p_cmd->u.control.p_ctx;
 
     switch( i_query )
     {
@@ -1563,71 +1594,71 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd )
     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 );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.i_int );
 
     case ES_OUT_SET_PCR:                /* arg1=vlc_tick_t i_pcr(microsecond!) (using default group 0)*/
     case ES_OUT_SET_NEXT_DISPLAY_TIME:  /* arg1=int64_t i_pts(microsecond) */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.i_i64 );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.i_i64 );
 
     case ES_OUT_SET_GROUP_PCR:          /* arg1= int i_group, arg2=vlc_tick_t i_pcr(microsecond!)*/
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.int_i64.i_int,
-                                               p_cmd->u.control.u.int_i64.i_i64 );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.int_i64.i_int,
+                            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 );
+        return ctx_Control( p_out, p_ctx, i_query );
 
     case ES_OUT_SET_GROUP_META:  /* arg1=int i_group arg2=const vlc_meta_t* */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.int_meta.i_int,
-                                               p_cmd->u.control.u.int_meta.p_meta );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.int_meta.i_int,
+                            p_cmd->u.control.u.int_meta.p_meta );
 
     case ES_OUT_SET_GROUP_EPG:   /* arg1=int i_group arg2=const vlc_epg_t* */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.int_epg.i_int,
-                                               p_cmd->u.control.u.int_epg.p_epg );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.int_epg.i_int,
+                            p_cmd->u.control.u.int_epg.p_epg );
 
     case ES_OUT_SET_GROUP_EPG_EVENT: /* arg1=int i_group arg2=const vlc_epg_event_t* */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.int_epg_evt.i_int,
-                                               p_cmd->u.control.u.int_epg_evt.p_evt );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.int_epg_evt.i_int,
+                            p_cmd->u.control.u.int_epg_evt.p_evt );
 
     case ES_OUT_SET_EPG_TIME: /* arg1=int64_t */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.i_i64 );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.i_i64 );
 
     case ES_OUT_SET_ES_SCRAMBLED_STATE: /* arg1=int es_out_id_t* arg2=bool */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.es_bool.p_es->p_es,
-                                               p_cmd->u.control.u.es_bool.b_bool );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.es_bool.p_es->p_es,
+                            p_cmd->u.control.u.es_bool.b_bool );
 
     case ES_OUT_SET_META:  /* arg1=const vlc_meta_t* */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.int_meta.p_meta );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.int_meta.p_meta );
 
     /* Modified control */
     case ES_OUT_SET_ES:      /* arg1= es_out_id_t*                   */
     case ES_OUT_UNSET_ES:    /* arg1= es_out_id_t*                   */
     case ES_OUT_RESTART_ES:  /* arg1= es_out_id_t*                   */
     case ES_OUT_SET_ES_DEFAULT: /* arg1= es_out_id_t*                */
-        return es_out_Control( p_out, i_query, !p_cmd->u.control.u.p_es ? NULL :
-                                               p_cmd->u.control.u.p_es->p_es );
+        return ctx_Control( p_out, p_ctx, i_query, !p_cmd->u.control.u.p_es ? NULL :
+                            p_cmd->u.control.u.p_es->p_es );
 
     case ES_OUT_SET_ES_STATE:/* arg1= es_out_id_t* arg2=bool   */
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.es_bool.p_es->p_es,
-                                               p_cmd->u.control.u.es_bool.b_bool );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.es_bool.p_es->p_es,
+                            p_cmd->u.control.u.es_bool.b_bool );
 
     case ES_OUT_SET_ES_CAT_POLICY:
-        return es_out_Control( p_out, i_query, p_cmd->u.control.u.es_policy.i_cat,
-                                               p_cmd->u.control.u.es_policy.i_policy );
+        return ctx_Control( p_out, p_ctx, i_query, p_cmd->u.control.u.es_policy.i_cat,
+                            p_cmd->u.control.u.es_policy.i_policy );
 
     case ES_OUT_SET_ES_FMT:     /* arg1= es_out_id_t* arg2=es_format_t* */
-        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 );
+        return ctx_Control( p_out, p_ctx, 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 );
+        return ctx_Control( p_out, p_ctx, 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 );
+        return ctx_Control( p_out, p_ctx, 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();
@@ -1636,6 +1667,9 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd )
 }
 static void CmdCleanControl( ts_cmd_t *p_cmd )
 {
+    if( p_cmd->u.control.p_ctx )
+        es_out_ctx_Release( p_cmd->u.control.p_ctx );
+
     switch( p_cmd->u.control.i_query )
     {
     case ES_OUT_SET_GROUP_META:
-- 
2.20.1



More information about the vlc-devel mailing list