]> git.sesse.net Git - vlc/blobdiff - src/input/input.c
input: Remove vlc_playlist.h inclusion.
[vlc] / src / input / input.c
index 6121f717d614b61bb321f1c3f3baa8bc598c4940..f397d4d13bb139b301adbd0e29a6b348e25299d2 100644 (file)
@@ -29,7 +29,7 @@
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
+#include <vlc_common.h>
 
 #include <ctype.h>
 #include <limits.h>
@@ -43,7 +43,6 @@
 #include <vlc_interface.h>
 #include <vlc_url.h>
 #include <vlc_charset.h>
-#include <vlc_playlist.h>
 
 #ifdef HAVE_SYS_STAT_H
 #   include <sys/stat.h>
@@ -87,9 +86,6 @@ static void SlaveSeek( input_thread_t *p_input );
 static void InputMetaUser( input_thread_t *p_input, vlc_meta_t *p_meta );
 static void InputUpdateMeta( input_thread_t *p_input, vlc_meta_t *p_meta );
 
-static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, bool * );
-static void SoutKeep( sout_instance_t * );
-
 static void DemuxMeta( input_thread_t *p_input, vlc_meta_t *p_meta, demux_t *p_demux );
 static void AccessMeta( input_thread_t * p_input, vlc_meta_t *p_meta );
 static void AppendAttachment( int *pi_attachment, input_attachment_t ***ppp_attachment,
@@ -153,22 +149,27 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
         STATS_TIMER_INPUT_LAUNCHING );
 
     MALLOC_NULL( p_input->p, input_thread_private_t );
+    memset( p_input->p, 0, sizeof( input_thread_private_t ) );
 
     /* One "randomly" selected input thread is responsible for computing
      * the global stats. Check if there is already someone doing this */
     if( p_input->p_libvlc->p_stats && !b_quick )
     {
+        libvlc_priv_t *priv = libvlc_priv (p_input->p_libvlc);
         vlc_mutex_lock( &p_input->p_libvlc->p_stats->lock );
-        if( p_input->p_libvlc->p_stats_computer == NULL )
-        {
-            p_input->p_libvlc->p_stats_computer = p_input;
-        }
+        if( priv->p_stats_computer == NULL )
+            priv->p_stats_computer = p_input;
         vlc_mutex_unlock( &p_input->p_libvlc->p_stats->lock );
     }
 
     p_input->b_preparsing = b_quick;
     p_input->psz_header = psz_header ? strdup( psz_header ) : NULL;
 
+    /* Init events */
+    vlc_event_manager_t * p_em = &p_input->p->event_manager;
+    vlc_event_manager_init_with_vlc_object( p_em, p_input );
+    vlc_event_manager_register_event_type( p_em, vlc_InputStateChanged );
+
     /* Init Common fields */
     p_input->b_eof = false;
     p_input->b_can_pace_control = true;
@@ -185,8 +186,6 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     TAB_INIT( p_input->p->i_attachment, p_input->p->attachment );
     p_input->p->p_es_out = NULL;
     p_input->p->p_sout  = NULL;
-    p_input->p->b_owns_its_sout = true;
-    p_input->p->b_sout_keep  = false;
     p_input->p->b_out_pace_control = false;
     p_input->i_pts_delay = 0;
 
@@ -217,7 +216,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     p_input->p->slave   = NULL;
 
     /* Init control buffer */
-    vlc_mutex_init( p_input, &p_input->p->lock_control );
+    vlc_mutex_init( &p_input->p->lock_control );
     p_input->p->i_control = 0;
 
     /* Parse input options */
@@ -273,7 +272,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
                      }
                      psz_start = psz_end + 1;
                 }
-                msg_Dbg( p_input, "adding bookmark: %s, bytes="I64Fd", time="I64Fd,
+                msg_Dbg( p_input, "adding bookmark: %s, bytes=%"PRId64", time=%"PRId64,
                                   p_seekpoint->psz_name, p_seekpoint->i_byte_offset,
                                   p_seekpoint->i_time_offset );
                 input_Control( p_input, INPUT_ADD_BOOKMARK, p_seekpoint );
@@ -293,13 +292,10 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
 
     /* */
     if( p_sout )
-    {
         p_input->p->p_sout = p_sout;
-        p_input->p->b_owns_its_sout = false;
-    }
 
     memset( &p_input->p->counters, 0, sizeof( p_input->p->counters ) );
-    vlc_mutex_init( p_input, &p_input->p->counters.counters_lock );
+    vlc_mutex_init( &p_input->p->counters.counters_lock );
 
     /* Attach only once we are ready */
     vlc_object_attach( p_input, p_parent );
@@ -317,19 +313,13 @@ static void Destructor( input_thread_t * p_input )
 {
     input_thread_private_t *priv = p_input->p;
 
+    vlc_event_manager_fini( &p_input->p->event_manager );
+
     stats_TimerDump( p_input, STATS_TIMER_INPUT_LAUNCHING );
     stats_TimerClean( p_input, STATS_TIMER_INPUT_LAUNCHING );
 #ifdef ENABLE_SOUT
-    if( priv->b_owns_its_sout && priv->p_sout )
-    {
-        if( priv->b_sout_keep )
-            SoutKeep( priv->p_sout );
-        else
-        {
-            sout_DeleteInstance( priv->p_sout );
-            priv->p_sout = NULL;
-        }
-    }
+    if( priv->p_sout )
+        sout_DeleteInstance( priv->p_sout );
 #endif
     vlc_gc_decref( p_input->p->input.p_item );
 
@@ -350,15 +340,7 @@ static void Destructor( input_thread_t * p_input )
 input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
                                       input_item_t *p_item )
 {
-    bool b_sout_keep;
-    sout_instance_t *p_sout = SoutFind( p_parent, p_item, &b_sout_keep );
-    input_thread_t *p_input =  __input_CreateThreadExtended( p_parent, p_item, NULL, p_sout );
-
-    if( !p_input && p_sout )
-        SoutKeep( p_sout );
-
-    p_input->p->b_sout_keep = b_sout_keep;
-    return p_input;
+    return __input_CreateThreadExtended( p_parent, p_item, NULL, NULL );
 }
 
 /* */
@@ -387,7 +369,7 @@ input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent,
 }
 
 /**
- * Initialize an input thread and run it. This thread will clean after himself,
+ * Initialize an input thread and run it. This thread will clean after itself,
  * you can forget about it. It can work either in blocking or non-blocking mode
  *
  * \param p_parent a vlc_object
@@ -398,17 +380,11 @@ input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent,
 int __input_Read( vlc_object_t *p_parent, input_item_t *p_item,
                    bool b_block )
 {
-    bool b_sout_keep;
-    sout_instance_t *p_sout = SoutFind( p_parent, p_item, &b_sout_keep );
     input_thread_t *p_input;
 
-    p_input = Create( p_parent, p_item, NULL, false, p_sout );
-    if( !p_input && p_sout )
-    {
-        SoutKeep( p_sout );
+    p_input = Create( p_parent, p_item, NULL, false, NULL );
+    if( !p_input )
         return VLC_EGENERIC;
-    }
-    p_input->p->b_sout_keep = b_sout_keep;
 
     if( b_block )
     {
@@ -501,8 +477,10 @@ void input_StopThread( input_thread_t *p_input )
 
 sout_instance_t * input_DetachSout( input_thread_t *p_input )
 {
-    p_input->p->b_owns_its_sout = false;
-    return p_input->p->p_sout;
+    sout_instance_t *p_sout = p_input->p->p_sout;
+    vlc_object_detach( p_sout );
+    p_input->p->p_sout = NULL;
+    return p_sout;
 }
 
 /*****************************************************************************
@@ -520,15 +498,6 @@ static int Run( input_thread_t *p_input )
         /* If we failed, wait before we are killed, and exit */
         p_input->b_error = true;
 
-        /* FIXME: we don't want to depend on the playlist */
-        playlist_t * p_playlist = vlc_object_find( p_input,
-            VLC_OBJECT_PLAYLIST, FIND_PARENT );
-        if( p_playlist )
-        {
-            playlist_Signal( p_playlist );
-            vlc_object_release( p_playlist );
-        }
-
         Error( p_input );
 
         /* Tell we're dead */
@@ -554,7 +523,7 @@ static int Run( input_thread_t *p_input )
 
         /* We have finished */
         p_input->b_eof = true;
-        playlist_Signal( pl_Get( p_input ) );
+        input_ChangeState( p_input, END_S );
     }
 
     /* Wait until we are asked to die */
@@ -665,7 +634,6 @@ static void MainLoop( input_thread_t *p_input )
                 {
                     /* End of file - we do not set b_die because only the
                      * playlist is allowed to do so. */
-                    input_ChangeState( p_input, END_S );
                     msg_Dbg( p_input, "EOF reached" );
                     p_input->p->input.b_eof = true;
                 }
@@ -772,17 +740,17 @@ static void MainLoop( input_thread_t *p_input )
             }
 
             var_SetBool( p_input, "intf-change", true );
-            i_intf_update = mdate() + I64C(150000);
+            i_intf_update = mdate() + INT64_C(150000);
         }
         /* 150ms * 8 = ~ 1 second */
         if( ++i_updates % 8 == 0 )
         {
             stats_ComputeInputStats( p_input, p_input->p->input.p_item->p_stats );
             /* Are we the thread responsible for computing global stats ? */
-            if( p_input->p_libvlc->p_stats_computer == p_input )
+            if( libvlc_priv (p_input->p_libvlc)->p_stats_computer == p_input )
             {
                 stats_ComputeGlobalStats( p_input->p_libvlc,
-                                     p_input->p_libvlc->p_stats );
+                                          p_input->p_libvlc->p_stats );
             }
         }
     }
@@ -795,7 +763,7 @@ static void InitStatistics( input_thread_t * p_input )
     /* Prepare statistics */
 #define INIT_COUNTER( c, type, compute ) p_input->p->counters.p_##c = \
  stats_CounterCreate( p_input, VLC_VAR_##type, STATS_##compute);
-    if( p_input->p_libvlc->b_stats )
+    if( libvlc_stats (p_input) )
     {
         INIT_COUNTER( read_bytes, INTEGER, COUNTER );
         INIT_COUNTER( read_packets, INTEGER, COUNTER );
@@ -863,7 +831,7 @@ static int InitSout( input_thread_t * p_input )
                 return VLC_EGENERIC;
             }
         }
-        if( p_input->p_libvlc->b_stats )
+        if( libvlc_stats (p_input) )
         {
             INIT_COUNTER( sout_sent_packets, INTEGER, COUNTER );
             INIT_COUNTER (sout_sent_bytes, INTEGER, COUNTER );
@@ -952,9 +920,9 @@ static void StartTitle( input_thread_t * p_input )
 
     /* Start time*/
     /* Set start time */
-    p_input->p->i_start = I64C(1000000) * var_GetInteger( p_input, "start-time" );
-    p_input->p->i_stop  = I64C(1000000) * var_GetInteger( p_input, "stop-time" );
-    p_input->p->i_run   = I64C(1000000) * var_GetInteger( p_input, "run-time" );
+    p_input->p->i_start = INT64_C(1000000) * var_GetInteger( p_input, "start-time" );
+    p_input->p->i_stop  = INT64_C(1000000) * var_GetInteger( p_input, "stop-time" );
+    p_input->p->i_run   = INT64_C(1000000) * var_GetInteger( p_input, "run-time" );
     i_length = var_GetTime( p_input, "length" );
     if( p_input->p->i_run < 0 )
     {
@@ -973,7 +941,7 @@ static void StartTitle( input_thread_t * p_input )
             vlc_value_t s;
 
             msg_Dbg( p_input, "starting at time: %ds",
-                              (int)( p_input->p->i_start / I64C(1000000) ) );
+                              (int)( p_input->p->i_start / INT64_C(1000000) ) );
 
             s.i_time = p_input->p->i_start;
             input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &s );
@@ -1260,7 +1228,7 @@ error:
     }
 #endif
 
-    if( !p_input->b_preparsing && p_input->p_libvlc->b_stats )
+    if( !p_input->b_preparsing && libvlc_stats (p_input) )
     {
 #define EXIT_COUNTER( c ) do { if( p_input->p->counters.p_##c ) \
                                    stats_CounterClean( p_input->p->counters.p_##c );\
@@ -1343,15 +1311,17 @@ static void End( input_thread_t * p_input )
     if( !p_input->b_preparsing )
     {
 #define CL_CO( c ) stats_CounterClean( p_input->p->counters.p_##c ); p_input->p->counters.p_##c = NULL;
-        if( p_input->p_libvlc->b_stats )
+        if( libvlc_stats (p_input) )
         {
+            libvlc_priv_t *priv = libvlc_priv (p_input->p_libvlc);
+
             /* make sure we are up to date */
             stats_ComputeInputStats( p_input, p_input->p->input.p_item->p_stats );
-            if( p_input->p_libvlc->p_stats_computer == p_input )
+            if( priv->p_stats_computer == p_input )
             {
                 stats_ComputeGlobalStats( p_input->p_libvlc,
                                           p_input->p_libvlc->p_stats );
-                p_input->p_libvlc->p_stats_computer = NULL;
+                priv->p_stats_computer = NULL;
             }
             CL_CO( read_bytes );
             CL_CO( read_packets );
@@ -1390,63 +1360,6 @@ static void End( input_thread_t * p_input )
     p_input->b_dead = true;
 }
 
-static sout_instance_t *SoutFind( vlc_object_t *p_parent, input_item_t *p_item, bool *pb_sout_keep )
-{
-    bool b_keep_sout = var_CreateGetBool( p_parent, "sout-keep" );
-    sout_instance_t *p_sout = NULL;
-    int i;
-
-    /* Search sout-keep options
-     * XXX it has to be done here, but it is duplicated work :( */
-    vlc_mutex_lock( &p_item->lock );
-    for( i = 0; i < p_item->i_options; i++ )
-    {
-        const char *psz_option = p_item->ppsz_options[i];
-        if( !psz_option )
-            continue;
-        if( *psz_option == ':' )
-            psz_option++;
-
-        if( !strcmp( psz_option, "sout-keep" ) )
-            b_keep_sout = true;
-        else if( !strcmp( psz_option, "no-sout-keep" ) || !strcmp( psz_option, "nosout-keep" ) )
-            b_keep_sout = false;
-    }
-    vlc_mutex_unlock( &p_item->lock );
-
-    /* Find a potential sout to reuse
-     * XXX it might be unusable but this will be checked later */
-    if( b_keep_sout )
-    {
-        p_sout = vlc_object_find( p_parent->p_libvlc, VLC_OBJECT_SOUT,
-                                                      FIND_CHILD );
-        if( p_sout )
-        {
-            if( p_sout->p_parent != VLC_OBJECT( p_sout->p_libvlc ) )
-            {
-                vlc_object_release( p_sout );
-                p_sout = NULL;
-            }
-            else
-            {
-                vlc_object_detach( p_sout );    /* Remove it from the GC */
-                vlc_object_release( p_sout );
-            }
-        }
-    }
-
-    if( pb_sout_keep )
-        *pb_sout_keep = b_keep_sout;
-
-    return p_sout;
-}
-
-static void SoutKeep( sout_instance_t *p_sout )
-{
-    msg_Dbg( p_sout, "sout has been kept" );
-    vlc_object_attach( p_sout, p_sout->p_libvlc );
-}
-
 /*****************************************************************************
  * Control
  *****************************************************************************/
@@ -1617,7 +1530,7 @@ static bool Control( input_thread_t *p_input, int i_type,
             }
             if( i_ret )
             {
-                msg_Warn( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) "I64Fd
+                msg_Warn( p_input, "INPUT_CONTROL_SET_TIME(_OFFSET) %"PRId64
                          " failed or not possible", i_time );
             }
             else
@@ -2109,7 +2022,6 @@ static int UpdateFromAccess( input_thread_t *p_input )
         vlc_meta_t *p_meta = vlc_meta_New();
         access_Control( p_input->p->input.p_access,ACCESS_GET_META, p_meta );
         InputUpdateMeta( p_input, p_meta );
-        var_SetInteger( pl_Get( p_input ), "item-change", p_input->p->input.p_item->i_id );
         p_access->info.i_update &= ~INPUT_UPDATE_META;
     }
 
@@ -2148,14 +2060,6 @@ static int UpdateFromAccess( input_thread_t *p_input )
 static void UpdateItemLength( input_thread_t *p_input, int64_t i_length )
 {
     input_item_SetDuration( p_input->p->input.p_item, (mtime_t) i_length );
-
-    if( !p_input->b_preparsing )
-    {
-        pl_Yield( p_input );
-        var_SetInteger( pl_Get( p_input ), "item-change",
-                        p_input->p->input.p_item->i_id );
-        pl_Release( p_input );
-    }
 }
 
 /*****************************************************************************
@@ -2164,27 +2068,8 @@ static void UpdateItemLength( input_thread_t *p_input, int64_t i_length )
 static input_source_t *InputSourceNew( input_thread_t *p_input )
 {
     input_source_t *in = (input_source_t*) malloc( sizeof( input_source_t ) );
-
-    if( !in )
-    {
-        msg_Err( p_input, "out of memory for new input source" );
-        return NULL;
-    }
-
-    in->p_item   = NULL;
-    in->p_access = NULL;
-    in->p_stream = NULL;
-    in->p_demux  = NULL;
-    in->b_title_demux = false;
-    TAB_INIT( in->i_title, in->title );
-    in->b_can_pause = true;
-    in->b_can_pace_control = true;
-    in->b_can_rate_control = true;
-    in->b_rescale_ts = true;
-    in->b_eof = false;
-    in->f_fps = 0.0;
-    in->i_cr_average = 0;
-
+    if( in )
+        memset( in, 0, sizeof( input_source_t ) );
     return in;
 }
 
@@ -2819,6 +2704,12 @@ void MRLSplit( char *psz_dup, const char **ppsz_access, const char **ppsz_demux,
         psz_demux = strchr( psz_access, '/' );
         if( psz_demux )
             *psz_demux++ = '\0';
+
+        /* We really don't want module name substitution here! */
+        if( psz_access[0] == '$' )
+            psz_access++;
+        if( psz_demux && psz_demux[0] == '$' )
+            psz_demux++;
     }
     else
     {
@@ -2962,3 +2853,12 @@ bool input_AddSubtitles( input_thread_t *p_input, char *psz_subtitle,
 
     return true;
 }
+
+/*****************************************************************************
+ * input_get_event_manager
+ *****************************************************************************/
+vlc_event_manager_t *
+input_get_event_manager( input_thread_t *p_input )
+{
+    return &p_input->p->event_manager;
+}