[vlc-devel] [PATCH 4/5] input: es_out_timeshift: fix asynchronous accounting of ES

Francois Cartegnie fcvlcdev at free.fr
Thu Apr 23 13:00:13 CEST 2020


You can't keep track of scheduled ES as they don't exist
and they expire with the command list.
---
 src/input/es_out_timeshift.c | 120 ++++++++++++++++++-----------------
 1 file changed, 62 insertions(+), 58 deletions(-)

diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 7704b4f4b3..b1468b3e95 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -208,6 +208,7 @@ typedef struct
 {
     vlc_thread_t   thread;
     input_thread_t *p_input;
+    es_out_t       *p_tsout;
     es_out_t       *p_out;
     int64_t        i_tmp_size_max;
     const char     *psz_tmp_path;
@@ -308,7 +309,7 @@ static void CmdCleanAdd    ( ts_cmd_add_t * );
 static void CmdCleanSend   ( ts_cmd_send_t * );
 static void CmdCleanControl( ts_cmd_control_t * );
 
-/* XXX these functions will take the destination es_out_t */
+/* */
 static void CmdExecuteAdd    ( es_out_t *, ts_cmd_add_t * );
 static int  CmdExecuteSend   ( es_out_t *, ts_cmd_send_t * );
 static void CmdExecuteDel    ( es_out_t *, ts_cmd_del_t * );
@@ -454,12 +455,10 @@ static es_out_id_t *Add( es_out_t *p_out, input_source_t *in, const es_format_t
         return NULL;
     }
 
-    TAB_APPEND( p_sys->i_es, p_sys->pp_es, p_es );
-
     if( p_sys->b_delayed )
         TsPushCmd( p_sys->p_ts, (ts_cmd_t *) &cmd );
     else
-        CmdExecuteAdd( p_sys->p_out, &cmd );
+        CmdExecuteAdd( p_out, &cmd );
 
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -479,7 +478,7 @@ static int Send( es_out_t *p_out, es_out_id_t *p_es, block_t *p_block )
     if( p_sys->b_delayed )
         TsPushCmd( p_sys->p_ts, (ts_cmd_t *)&cmd );
     else
-        i_ret = CmdExecuteSend( p_sys->p_out, &cmd) ;
+        i_ret = CmdExecuteSend( p_out, &cmd) ;
 
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -498,9 +497,7 @@ static void Del( es_out_t *p_out, es_out_id_t *p_es )
     if( p_sys->b_delayed )
         TsPushCmd( p_sys->p_ts, (ts_cmd_t *)&cmd );
     else
-        CmdExecuteDel( p_sys->p_out, &cmd );
-
-    TAB_REMOVE( p_sys->i_es, p_sys->pp_es, p_es );
+        CmdExecuteDel( p_out, &cmd );
 
     vlc_mutex_unlock( &p_sys->lock );
 }
@@ -679,7 +676,7 @@ static int ControlLocked( es_out_t *p_out, input_source_t *in, int i_query,
             TsPushCmd( p_sys->p_ts, (ts_cmd_t *) &cmd );
             return VLC_SUCCESS;
         }
-        return CmdExecuteControl( p_sys->p_out, &cmd );
+        return CmdExecuteControl( p_out, &cmd );
     }
 
     /* Special control when delayed */
@@ -758,25 +755,25 @@ static int ControlLocked( es_out_t *p_out, input_source_t *in, int i_query,
     }
 }
 
-static int Control( es_out_t *p_out, input_source_t *in, int i_query, va_list args )
+static int Control( es_out_t *p_tsout, input_source_t *in, int i_query, va_list args )
 {
-    es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     int i_ret;
 
     vlc_mutex_lock( &p_sys->lock );
 
-    TsAutoStop( p_out );
+    TsAutoStop( p_tsout );
 
-    i_ret = ControlLocked( p_out, in, i_query, args );
+    i_ret = ControlLocked( p_tsout, in, 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 )
+static int PrivControlLocked( es_out_t *p_tsout, int i_query, va_list args )
 {
-    es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
 
     switch( i_query )
     {
@@ -794,17 +791,17 @@ static int PrivControlLocked( es_out_t *p_out, int i_query, va_list args )
             TsPushCmd( p_sys->p_ts, &cmd );
             return VLC_SUCCESS;
         }
-        return CmdExecutePrivControl( p_sys->p_out, &cmd.privcontrol );
+        return CmdExecutePrivControl( p_tsout, &cmd.privcontrol );
     }
     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 );
+        return ControlLockedGetWakeup( p_tsout, pi_wakeup );
     }
     case ES_OUT_PRIV_GET_BUFFERING:
     {
         bool *pb_buffering = va_arg( args, bool* );
-        return ControlLockedGetBuffering( p_out, pb_buffering );
+        return ControlLockedGetBuffering( p_tsout, pb_buffering );
     }
     case ES_OUT_PRIV_SET_PAUSE_STATE:
     {
@@ -812,18 +809,18 @@ static int PrivControlLocked( 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_tsout, b_source_paused, b_paused, i_date );
     }
     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 );
+        return ControlLockedSetRate( p_tsout, src_rate, rate );
     }
     case ES_OUT_PRIV_SET_FRAME_NEXT:
     {
-        return ControlLockedSetFrameNext( p_out );
+        return ControlLockedSetFrameNext( p_tsout );
     }
     case ES_OUT_PRIV_GET_GROUP_FORCED:
         return es_out_vaPrivControl( p_sys->p_out, i_query, args );
@@ -844,16 +841,16 @@ static int PrivControlLocked( 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 )
+static int PrivControl( es_out_t *p_tsout, int i_query, va_list args )
 {
-    es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     int i_ret;
 
     vlc_mutex_lock( &p_sys->lock );
 
-    TsAutoStop( p_out );
+    TsAutoStop( p_tsout );
 
-    i_ret = PrivControlLocked( p_out, i_query, args );
+    i_ret = PrivControlLocked( p_tsout, i_query, args );
 
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -892,6 +889,7 @@ static int TsStart( es_out_t *p_out )
     p_ts->psz_tmp_path = p_sys->psz_tmp_path;
     p_ts->p_input = p_sys->p_input;
     p_ts->p_out = p_sys->p_out;
+    p_ts->p_tsout = p_out;
     vlc_mutex_init( &p_ts->lock );
     vlc_cond_init( &p_ts->wait );
     vlc_sem_init( &p_ts->done, 0 );
@@ -1164,22 +1162,22 @@ static void *TsRun( void *p_data )
         switch( cmd.header.i_type )
         {
         case C_ADD:
-            CmdExecuteAdd( p_ts->p_out, &cmd.add );
+            CmdExecuteAdd( p_ts->p_tsout, &cmd.add );
             CmdCleanAdd( &cmd.add );
             break;
         case C_SEND:
-            CmdExecuteSend( p_ts->p_out, &cmd.send );
+            CmdExecuteSend( p_ts->p_tsout, &cmd.send );
             CmdCleanSend( &cmd.send );
             break;
         case C_CONTROL:
-            CmdExecuteControl( p_ts->p_out, &cmd.control );
+            CmdExecuteControl( p_ts->p_tsout, &cmd.control );
             CmdCleanControl( &cmd.control );
             break;
         case C_PRIVCONTROL:
-            CmdExecutePrivControl( p_ts->p_out, &cmd.privcontrol );
+            CmdExecutePrivControl( p_ts->p_tsout, &cmd.privcontrol );
             break;
         case C_DEL:
-            CmdExecuteDel( p_ts->p_out, &cmd.del );
+            CmdExecuteDel( p_ts->p_tsout, &cmd.del );
             break;
         default:
             vlc_assert_unreachable();
@@ -1443,11 +1441,12 @@ static int CmdInitAdd( ts_cmd_add_t *p_cmd, input_source_t *in,  es_out_id_t *p_
     }
     return VLC_SUCCESS;
 }
-
-static void CmdExecuteAdd( es_out_t *p_out, ts_cmd_add_t *p_cmd )
+static void CmdExecuteAdd( es_out_t *p_tsout, ts_cmd_add_t *p_cmd )
 {
-    p_cmd->p_es->p_es = p_out->cbs->add( p_out, p_cmd->in,
-                                         p_cmd->p_fmt );
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
+    p_cmd->p_es->p_es = p_sys->p_out->cbs->add( p_sys->p_out, p_cmd->in,
+                                                p_cmd->p_fmt );
+    TAB_APPEND( p_sys->i_es, p_sys->pp_es, p_cmd->p_es );
 }
 static void CmdCleanAdd( ts_cmd_add_t *p_cmd )
 {
@@ -1464,8 +1463,9 @@ static void CmdInitSend( ts_cmd_send_t *p_cmd, es_out_id_t *p_es, block_t *p_blo
     p_cmd->p_es = p_es;
     p_cmd->p_block = p_block;
 }
-static int CmdExecuteSend( es_out_t *p_out, ts_cmd_send_t *p_cmd )
+static int CmdExecuteSend( es_out_t *p_tsout, ts_cmd_send_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     block_t *p_block = p_cmd->p_block;
 
     p_cmd->p_block = NULL;
@@ -1473,7 +1473,7 @@ static int CmdExecuteSend( es_out_t *p_out, ts_cmd_send_t *p_cmd )
     if( p_block )
     {
         if( p_cmd->p_es->p_es )
-            return es_out_Send( p_out, p_cmd->p_es->p_es, p_block );
+            return es_out_Send( p_sys->p_out, p_cmd->p_es->p_es, p_block );
         block_Release( p_block );
     }
     return VLC_EGENERIC;
@@ -1491,10 +1491,12 @@ static int CmdInitDel( ts_cmd_del_t *p_cmd, es_out_id_t *p_es )
     p_cmd->p_es = p_es;
     return VLC_SUCCESS;
 }
-static void CmdExecuteDel( es_out_t *p_out, ts_cmd_del_t *p_cmd )
+static void CmdExecuteDel( es_out_t *p_tsout, ts_cmd_del_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     if( p_cmd->p_es->p_es )
-        es_out_Del( p_out, p_cmd->p_es->p_es );
+        es_out_Del( p_sys->p_out, p_cmd->p_es->p_es );
+    TAB_REMOVE( p_sys->i_es, p_sys->pp_es, p_cmd->p_es );
     free( p_cmd->p_es );
 }
 
@@ -1641,8 +1643,9 @@ static int CmdInitControl( ts_cmd_control_t *p_cmd, input_source_t *in,
 
     return VLC_SUCCESS;
 }
-static int CmdExecuteControl( es_out_t *p_out, ts_cmd_control_t *p_cmd )
+static int CmdExecuteControl( es_out_t *p_tsout, ts_cmd_control_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     const int i_query = p_cmd->i_query;
     input_source_t *in = p_cmd->in;
 
@@ -1651,59 +1654,59 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_control_t *p_cmd )
     /* Pass-through control */
     case ES_OUT_SET_GROUP:   /* arg1= int                            */
     case ES_OUT_DEL_GROUP:   /* arg1=int i_group */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.i_int );
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->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_in_Control( p_out, in, i_query, p_cmd->u.i_i64 );
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.i_i64 );
 
     case ES_OUT_SET_GROUP_PCR:          /* arg1= int i_group, arg2=vlc_tick_t i_pcr(microsecond!)*/
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.int_i64.i_int,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.int_i64.i_int,
                                   p_cmd->u.int_i64.i_i64 );
 
     case ES_OUT_RESET_PCR:           /* no arg */
-        return es_out_in_Control( p_out, in, i_query );
+        return es_out_in_Control( p_sys->p_out, in, i_query );
 
     case ES_OUT_SET_GROUP_META:  /* arg1=int i_group arg2=const vlc_meta_t* */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.int_meta.i_int,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.int_meta.i_int,
                                   p_cmd->u.int_meta.p_meta );
 
     case ES_OUT_SET_GROUP_EPG:   /* arg1=int i_group arg2=const vlc_epg_t* */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.int_epg.i_int,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.int_epg.i_int,
                                   p_cmd->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_in_Control( p_out, in, i_query, p_cmd->u.int_epg_evt.i_int,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.int_epg_evt.i_int,
                                   p_cmd->u.int_epg_evt.p_evt );
 
     case ES_OUT_SET_EPG_TIME: /* arg1=int64_t */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.i_i64 );
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.i_i64 );
 
     case ES_OUT_SET_ES_SCRAMBLED_STATE: /* arg1=int es_out_id_t* arg2=bool */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.es_bool.p_es->p_es,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.es_bool.p_es->p_es,
                                   p_cmd->u.es_bool.b_bool );
 
     case ES_OUT_SET_META:  /* arg1=const vlc_meta_t* */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.int_meta.p_meta );
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->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_in_Control( p_out, in, i_query, !p_cmd->u.p_es ? NULL :
+        return es_out_in_Control( p_sys->p_out, in, i_query, !p_cmd->u.p_es ? NULL :
                                   p_cmd->u.p_es->p_es );
 
     case ES_OUT_SET_ES_STATE:/* arg1= es_out_id_t* arg2=bool   */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.es_bool.p_es->p_es,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.es_bool.p_es->p_es,
                                   p_cmd->u.es_bool.b_bool );
 
     case ES_OUT_SET_ES_CAT_POLICY:
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.es_policy.i_cat,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.es_policy.i_cat,
                                   p_cmd->u.es_policy.i_policy );
 
     case ES_OUT_SET_ES_FMT:     /* arg1= es_out_id_t* arg2=es_format_t* */
-        return es_out_in_Control( p_out, in, i_query, p_cmd->u.es_fmt.p_es->p_es,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.es_fmt.p_es->p_es,
                                   p_cmd->u.es_fmt.p_fmt );
 
     default:
@@ -1786,27 +1789,28 @@ static int CmdInitPrivControl( ts_cmd_privcontrol_t *p_cmd, int i_query, va_list
     return VLC_SUCCESS;
 }
 
-static int CmdExecutePrivControl( es_out_t *p_out, ts_cmd_privcontrol_t *p_cmd )
+static int CmdExecutePrivControl( es_out_t *p_tsout, ts_cmd_privcontrol_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     const int i_query = p_cmd->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.i_int );
+        return es_out_PrivControl( p_sys->p_out, i_query, p_cmd->u.i_int );
     case ES_OUT_PRIV_SET_JITTER:
-        return es_out_PrivControl( p_out, i_query, p_cmd->u.jitter.i_pts_delay,
+        return es_out_PrivControl( p_sys->p_out, i_query, p_cmd->u.jitter.i_pts_delay,
                                    p_cmd->u.jitter.i_pts_jitter,
                                    p_cmd->u.jitter.i_cr_average );
     case ES_OUT_PRIV_SET_TIMES:
-        return es_out_PrivControl( p_out, i_query,
+        return es_out_PrivControl( p_sys->p_out, i_query,
                                    p_cmd->u.times.f_position,
                                    p_cmd->u.times.i_time,
                                    p_cmd->u.times.i_normal_time,
                                    p_cmd->u.times.i_length );
     case ES_OUT_PRIV_SET_EOS: /* no arg */
-        return es_out_PrivControl( p_out, i_query );
+        return es_out_PrivControl( p_sys->p_out, i_query );
     default: vlc_assert_unreachable();
     }
 }
-- 
2.25.3



More information about the vlc-devel mailing list