]> git.sesse.net Git - vlc/blobdiff - src/libvlc.c
dejidjei:
[vlc] / src / libvlc.c
index 1e62c1fdf1645a8acc2d0847069bf8c4d1bd2058..496c013c266aa6f0c491039de0371a72bac29413 100644 (file)
@@ -94,6 +94,7 @@
 #include "playlist/playlist_internal.h"
 
 #include <vlc_vlm.h>
+#include <vlc_input.h>
 
 #include <assert.h>
 
@@ -105,6 +106,47 @@ static unsigned          i_instances = 0;
 
 static bool b_daemon = false;
 
+/*****************************************************************************
+ * vlc_gc_*.
+ *****************************************************************************/
+void __vlc_gc_incref( gc_object_t * p_gc )
+{
+    assert( p_gc->i_gc_refcount > 0 );
+
+    char * name = input_item_GetName((input_item_t *)p_gc);
+    printf("--- %s++ (%d)\n", name, p_gc->i_gc_refcount+1);
+    free(name);
+    /* FIXME: atomic version needed! */
+    p_gc->i_gc_refcount ++;
+}
+
+void __vlc_gc_decref( gc_object_t *p_gc )
+{
+    assert( p_gc );
+    assert( p_gc->i_gc_refcount > 0 );
+    char * name = input_item_GetName((input_item_t *)p_gc);
+    printf("--- %s-- (%d)\n", name, p_gc->i_gc_refcount-1);
+    free(name);
+
+    /* FIXME: atomic version needed! */
+    p_gc->i_gc_refcount -- ;
+
+    if( p_gc->i_gc_refcount == 0 )
+    {
+        p_gc->pf_destructor( p_gc );
+        /* Do not use the p_gc pointer from now on ! */
+    }
+}
+
+void
+__vlc_gc_init( gc_object_t * p_gc, void (*pf_destructor)( gc_object_t * ),
+               void * arg)
+{
+    p_gc->i_gc_refcount = 1;
+    p_gc->pf_destructor = pf_destructor;
+    p_gc->p_destructor_arg = arg;
+}
+
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
@@ -433,6 +475,15 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
         b_exit = true;
         i_ret = VLC_EEXITSUCCESS;
     }
+    /* Check for full help option */
+    else if( config_GetInt( p_libvlc, "full-help" ) > 0 )
+    {
+        config_PutInt( p_libvlc, "advanced", 1);
+        config_PutInt( p_libvlc, "help-verbose", 1);
+        Help( p_libvlc, "full-help" );
+        b_exit = true;
+        i_ret = VLC_EEXITSUCCESS;
+    }
     /* Check for long help option */
     else if( config_GetInt( p_libvlc, "longhelp" ) > 0 )
     {
@@ -933,7 +984,6 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
 int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
 {
     intf_thread_t      * p_intf = NULL;
-    vout_thread_t      * p_vout = NULL;
     libvlc_priv_t      *priv = libvlc_priv (p_libvlc);
 
     /* Ask the interfaces to stop and destroy them */
@@ -954,26 +1004,29 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
     }
 #endif
 
+    playlist_t *p_playlist = priv->p_playlist;
     /* Remove all services discovery */
     msg_Dbg( p_libvlc, "removing all services discovery tasks" );
-    playlist_ServicesDiscoveryKillAll( priv->p_playlist );
+    playlist_ServicesDiscoveryKillAll( p_playlist );
 
     /* Free playlist */
+    /* Any thread still running must not assume pl_Yield() succeeds. */
     msg_Dbg( p_libvlc, "removing playlist" );
-    vlc_object_release( priv->p_playlist );
+    priv->p_playlist = NULL;
+    vlc_object_kill( p_playlist ); /* <-- memory barrier for pl_Yield() */
+    vlc_thread_join( p_playlist );
+    vlc_object_release( p_playlist );
 
     /* Free interaction */
     msg_Dbg( p_libvlc, "removing interaction" );
-    vlc_object_release( priv->p_interaction );
+    interaction_Destroy( priv->p_interaction );
 
     /* Free video outputs */
     msg_Dbg( p_libvlc, "removing all video outputs" );
-    while( (p_vout = vlc_object_find( p_libvlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
-    {
-        vlc_object_detach( p_vout );
-        vlc_object_release( p_vout );
-        vlc_object_release( p_vout );
-    }
+    vlc_list_t *list = vlc_list_find (p_libvlc, VLC_OBJECT_VOUT, FIND_CHILD);
+    for (int i = 0; i < list->i_count; i++)
+        vlc_object_release (list->p_values[i].p_object);
+    vlc_list_release (list);
 
     stats_TimersDumpAll( p_libvlc );
     stats_TimersCleanAll( p_libvlc );
@@ -1007,7 +1060,7 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
     FOREACH_ARRAY( input_item_t *p_del, priv->input_items )
         msg_Err( p_libvlc, "input item %p has not been deleted properly: refcount %d, name %s",
             p_del, p_del->i_gc_refcount, p_del->psz_name ? p_del->psz_name : "(null)" );
-        b_clean = false;
+        //b_clean = false;
     FOREACH_END();
     assert( b_clean );
     ARRAY_RESET( priv->input_items );
@@ -1261,6 +1314,12 @@ static int GetFilenames( libvlc_int_t *p_vlc, int i_argc, const char *ppsz_argv[
  *****************************************************************************
  * Print a short inline help. Message interface is initialized at this stage.
  *****************************************************************************/
+static inline void print_help_on_full_help( void )
+{
+    utf8_fprintf( stdout, "\n" );
+    utf8_fprintf( stdout, "%s\n", _("To get exhaustive help, use '-H'.") );
+}
+
 static void Help( libvlc_int_t *p_this, char const *psz_help_name )
 {
 #ifdef WIN32
@@ -1272,8 +1331,15 @@ static void Help( libvlc_int_t *p_this, char const *psz_help_name )
         utf8_fprintf( stdout, vlc_usage, p_this->psz_object_name );
         Usage( p_this, "help" );
         Usage( p_this, "main" );
+        print_help_on_full_help();
     }
     else if( psz_help_name && !strcmp( psz_help_name, "longhelp" ) )
+    {
+        utf8_fprintf( stdout, vlc_usage, p_this->psz_object_name );
+        Usage( p_this, NULL );
+        print_help_on_full_help();
+    }
+    else if( psz_help_name && !strcmp( psz_help_name, "full-help" ) )
     {
         utf8_fprintf( stdout, vlc_usage, p_this->psz_object_name );
         Usage( p_this, NULL );
@@ -1293,6 +1359,34 @@ static void Help( libvlc_int_t *p_this, char const *psz_help_name )
  *****************************************************************************
  * Print a short inline help. Message interface is initialized at this stage.
  *****************************************************************************/
+#   define COL(x)  "\033[" #x ";1m"
+#   define RED     COL(31)
+#   define GREEN   COL(32)
+#   define YELLOW  COL(33)
+#   define BLUE    COL(34)
+#   define MAGENTA COL(35)
+#   define CYAN    COL(36)
+#   define WHITE   COL(0)
+#   define GRAY    "\033[0m"
+static void print_help_section( module_config_t *p_item, bool b_color, bool b_description )
+{
+    if( !p_item ) return;
+    if( b_color )
+    {
+        utf8_fprintf( stdout, RED"   %s:\n"GRAY,
+                      p_item->psz_text );
+        if( b_description && p_item->psz_longtext )
+            utf8_fprintf( stdout, MAGENTA"   %s\n"GRAY,
+                          p_item->psz_longtext );
+    }
+    else
+    {
+        utf8_fprintf( stdout, "   %s:\n", p_item->psz_text );
+        if( b_description && p_item->psz_longtext )
+            utf8_fprintf( stdout, "   %s\n", p_item->psz_longtext );
+    }
+}
+
 static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
 {
 #define FORMAT_STRING "  %s --%s%s%s%s%s%s%s "
@@ -1308,15 +1402,6 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
      * The purpose of having bra and ket is that we might i18n them as well.
      */
 
-#   define COL(x)  "\033[" #x ";1m"
-#   define RED     COL(31)
-#   define GREEN   COL(32)
-#   define YELLOW  COL(33)
-#   define BLUE    COL(34)
-#   define MAGENTA COL(35)
-#   define CYAN    COL(36)
-#   define WHITE   COL(0)
-#   define GRAY    "\033[0m"
 #define COLOR_FORMAT_STRING (WHITE"  %s --%s"YELLOW"%s%s%s%s%s%s "GRAY)
 #define COLOR_FORMAT_STRING_BOOL (WHITE"  %s --%s%s%s%s%s%s%s "GRAY)
 
@@ -1377,12 +1462,13 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
         bool b_help_module;
         module_t *p_parser = (module_t *)p_list->p_values[i_index].p_object;
         module_config_t *p_item = NULL;
+        module_config_t *p_section = NULL;
         module_config_t *p_end = p_parser->p_config + p_parser->confsize;
 
         if( psz_module_name && strcmp( psz_module_name,
                                        p_parser->psz_object_name ) )
         {
-            const char *const *pp_shortcut = p_parser->pp_shortcuts;
+            char *const *pp_shortcut = p_parser->pp_shortcuts;
             while( *pp_shortcut )
             {
                 if( !strcmp( psz_module_name, *pp_shortcut ) )
@@ -1481,22 +1567,9 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
 
             case CONFIG_HINT_SUBCATEGORY:
                 if( strcmp( "main", p_parser->psz_object_name ) )
-                break;
+                    break;
             case CONFIG_SECTION:
-                if( b_color )
-                {
-                    utf8_fprintf( stdout, RED"   %s:\n"GRAY,
-                                  p_item->psz_text );
-                    if( b_description && p_item->psz_longtext )
-                        utf8_fprintf( stdout, MAGENTA"   %s\n"GRAY,
-                                      p_item->psz_longtext );
-                }
-                else
-                {
-                    utf8_fprintf( stdout, "   %s:\n", p_item->psz_text );
-                    if( b_description && p_item->psz_longtext )
-                        utf8_fprintf( stdout, "   %s\n", p_item->psz_longtext );
-                }
+                p_section = p_item;
                 break;
 
             case CONFIG_ITEM_STRING:
@@ -1508,6 +1581,8 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
             case CONFIG_ITEM_MODULE_LIST_CAT:
             case CONFIG_ITEM_FONT:
             case CONFIG_ITEM_PASSWORD:
+                print_help_section( p_section, b_color, b_description );
+                p_section = NULL;
                 psz_bra = OPTION_VALUE_SEP "<";
                 psz_type = _("string");
                 psz_ket = ">";
@@ -1527,6 +1602,8 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
                 break;
             case CONFIG_ITEM_INTEGER:
             case CONFIG_ITEM_KEY: /* FIXME: do something a bit more clever */
+                print_help_section( p_section, b_color, b_description );
+                p_section = NULL;
                 psz_bra = OPTION_VALUE_SEP "<";
                 psz_type = _("integer");
                 psz_ket = ">";
@@ -1554,6 +1631,8 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
                 }
                 break;
             case CONFIG_ITEM_FLOAT:
+                print_help_section( p_section, b_color, b_description );
+                p_section = NULL;
                 psz_bra = OPTION_VALUE_SEP "<";
                 psz_type = _("float");
                 psz_ket = ">";
@@ -1565,6 +1644,8 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
                 }
                 break;
             case CONFIG_ITEM_BOOL:
+                print_help_section( p_section, b_color, b_description );
+                p_section = NULL;
                 psz_bra = ""; psz_type = ""; psz_ket = "";
                 if( !b_help_module )
                 {
@@ -1788,7 +1869,7 @@ static void ListModules( libvlc_int_t *p_this, bool b_verbose )
 
         if( b_verbose )
         {
-            const char *const *pp_shortcut = p_parser->pp_shortcuts;
+            char *const *pp_shortcut = p_parser->pp_shortcuts;
             while( *pp_shortcut )
             {
                 if( strcmp( *pp_shortcut, p_parser->psz_object_name ) )