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

Francois Cartegnie fcvlcdev at free.fr
Mon Apr 20 20:27:29 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 | 89 +++++++++++++++++++-----------------
 1 file changed, 47 insertions(+), 42 deletions(-)

diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 73ac3e2183..63562d358a 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -201,6 +201,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;
@@ -301,7 +302,7 @@ static void CmdCleanAdd    ( ts_cmd_t * );
 static void CmdCleanSend   ( ts_cmd_t * );
 static void CmdCleanControl( ts_cmd_t *p_cmd );
 
-/* XXX these functions will take the destination es_out_t */
+/* */
 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 * );
@@ -446,12 +447,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, &cmd );
     else
-        CmdExecuteAdd( p_sys->p_out, &cmd );
+        CmdExecuteAdd( p_out, &cmd );
 
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -471,7 +470,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, &cmd );
     else
-        i_ret = CmdExecuteSend( p_sys->p_out, &cmd) ;
+        i_ret = CmdExecuteSend( p_out, &cmd) ;
 
     vlc_mutex_unlock( &p_sys->lock );
 
@@ -490,9 +489,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, &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 );
 }
@@ -671,7 +668,7 @@ static int ControlLocked( es_out_t *p_out, input_source_t *in, int i_query,
             TsPushCmd( p_sys->p_ts, &cmd );
             return VLC_SUCCESS;
         }
-        return CmdExecuteControl( p_sys->p_out, &cmd );
+        return CmdExecuteControl( p_out, &cmd );
     }
 
     /* Special control when delayed */
@@ -786,7 +783,7 @@ 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 );
+        return CmdExecutePrivControl( p_out, &cmd );
     }
     case ES_OUT_PRIV_GET_WAKE_UP: /* TODO ? */
     {
@@ -884,6 +881,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 );
@@ -1156,19 +1154,19 @@ static void *TsRun( void *p_data )
         switch( cmd.i_type )
         {
         case C_ADD:
-            CmdExecuteAdd( p_ts->p_out, &cmd );
+            CmdExecuteAdd( p_ts->p_tsout, &cmd );
             CmdCleanAdd( &cmd );
             break;
         case C_SEND:
-            CmdExecuteSend( p_ts->p_out, &cmd );
+            CmdExecuteSend( p_ts->p_tsout, &cmd );
             CmdCleanSend( &cmd );
             break;
         case C_CONTROL:
-            CmdExecuteControl( p_ts->p_out, &cmd );
+            CmdExecuteControl( p_ts->p_tsout, &cmd );
             CmdCleanControl( &cmd );
             break;
         case C_DEL:
-            CmdExecuteDel( p_ts->p_out, &cmd );
+            CmdExecuteDel( p_ts->p_tsout, &cmd );
             break;
         default:
             vlc_assert_unreachable();
@@ -1405,10 +1403,12 @@ static int CmdInitAdd( ts_cmd_t *p_cmd, input_source_t *in,  es_out_id_t *p_es,
     }
     return VLC_SUCCESS;
 }
-static void CmdExecuteAdd( es_out_t *p_out, ts_cmd_t *p_cmd )
+static void CmdExecuteAdd( es_out_t *p_tsout, ts_cmd_t *p_cmd )
 {
-    p_cmd->u.add.p_es->p_es = p_out->cbs->add( p_out, p_cmd->u.add.in,
-                                               p_cmd->u.add.p_fmt );
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
+    p_cmd->u.add.p_es->p_es = p_sys->p_out->cbs->add( p_sys->p_out, p_cmd->u.add.in,
+                                                      p_cmd->u.add.p_fmt );
+    TAB_APPEND( p_sys->i_es, p_sys->pp_es, p_cmd->u.add.p_es );
 }
 static void CmdCleanAdd( ts_cmd_t *p_cmd )
 {
@@ -1425,8 +1425,9 @@ static void CmdInitSend( ts_cmd_t *p_cmd, es_out_id_t *p_es, block_t *p_block )
     p_cmd->u.send.p_es = p_es;
     p_cmd->u.send.p_block = p_block;
 }
-static int CmdExecuteSend( es_out_t *p_out, ts_cmd_t *p_cmd )
+static int CmdExecuteSend( es_out_t *p_tsout, ts_cmd_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     block_t *p_block = p_cmd->u.send.p_block;
 
     p_cmd->u.send.p_block = NULL;
@@ -1434,7 +1435,7 @@ static int CmdExecuteSend( es_out_t *p_out, ts_cmd_t *p_cmd )
     if( p_block )
     {
         if( p_cmd->u.send.p_es->p_es )
-            return es_out_Send( p_out, p_cmd->u.send.p_es->p_es, p_block );
+            return es_out_Send( p_sys->p_out, p_cmd->u.send.p_es->p_es, p_block );
         block_Release( p_block );
     }
     return VLC_EGENERIC;
@@ -1452,10 +1453,12 @@ static int CmdInitDel( ts_cmd_t *p_cmd, es_out_id_t *p_es )
     p_cmd->u.del.p_es = p_es;
     return VLC_SUCCESS;
 }
-static void CmdExecuteDel( es_out_t *p_out, ts_cmd_t *p_cmd )
+static void CmdExecuteDel( es_out_t *p_tsout, ts_cmd_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     if( p_cmd->u.del.p_es->p_es )
-        es_out_Del( p_out, p_cmd->u.del.p_es->p_es );
+        es_out_Del( p_sys->p_out, p_cmd->u.del.p_es->p_es );
+    TAB_REMOVE( p_sys->i_es, p_sys->pp_es, p_cmd->u.del.p_es );
     free( p_cmd->u.del.p_es );
 }
 
@@ -1602,8 +1605,9 @@ static int CmdInitControl( ts_cmd_t *p_cmd, input_source_t *in,
 
     return VLC_SUCCESS;
 }
-static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd )
+static int CmdExecuteControl( es_out_t *p_tsout, ts_cmd_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     const int i_query = p_cmd->u.control.i_query;
     input_source_t *in = p_cmd->u.control.in;
 
@@ -1612,66 +1616,66 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_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.control.u.i_int );
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.i_i64 );
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.int_i64.i_int,
+        return es_out_in_Control( p_sys->p_out, in, 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 */
-        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.control.u.int_meta.i_int,
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.int_epg.i_int,
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.int_epg_evt.i_int,
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.i_i64 );
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.es_bool.p_es->p_es,
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.int_meta.p_meta );
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, !p_cmd->u.control.u.p_es ? NULL :
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.es_bool.p_es->p_es,
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.es_policy.i_cat,
+        return es_out_in_Control( p_sys->p_out, in, 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_in_Control( p_out, in, i_query, p_cmd->u.control.u.es_fmt.p_es->p_es,
+        return es_out_in_Control( p_sys->p_out, in, i_query, p_cmd->u.control.u.es_fmt.p_es->p_es,
                                   p_cmd->u.control.u.es_fmt.p_fmt );
 
     default:
         if( i_query >= ES_OUT_TIMESHIFT_PRIVATE_START &&
             i_query < ES_OUT_PRIVATE_START )
         {
-            return CmdExecutePrivControl( p_out, p_cmd );
+            return CmdExecutePrivControl( p_tsout, p_cmd );
         }
         vlc_assert_unreachable();
         return VLC_EGENERIC;
@@ -1752,27 +1756,28 @@ static int CmdInitPrivControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool
     return VLC_SUCCESS;
 }
 
-static int CmdExecutePrivControl( es_out_t *p_out, ts_cmd_t *p_cmd )
+static int CmdExecutePrivControl( es_out_t *p_tsout, ts_cmd_t *p_cmd )
 {
+    es_out_sys_t *p_sys = container_of(p_tsout, es_out_sys_t, out);
     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 );
+        return es_out_PrivControl( p_sys->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,
+        return es_out_PrivControl( p_sys->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,
+        return es_out_PrivControl( p_sys->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 );
+        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