]> git.sesse.net Git - vlc/blobdiff - src/input/item.c
libvlc: Split public headers by object and layers.
[vlc] / src / input / item.c
index d561522ab524b79058b65789417696ff15f4ba91..2397c13c55c4ce397afa406cf9b56a7499a2acaa 100644 (file)
@@ -16,9 +16,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -27,6 +27,7 @@
 #include <assert.h>
 
 #include <vlc_common.h>
+#include <vlc_url.h>
 #include "vlc_playlist.h"
 #include "vlc_interface.h"
 
@@ -298,6 +299,29 @@ char *input_item_GetMeta( input_item_t *p_i, vlc_meta_type_t meta_type )
     return psz;
 }
 
+/* Get the title of a given item or fallback to the name if the title is empty */
+char *input_item_GetTitleFbName( input_item_t *p_item )
+{
+    char *psz_ret;
+    vlc_mutex_lock( &p_item->lock );
+
+    if( !p_item->p_meta )
+    {
+        psz_ret = p_item->psz_name ? strdup( p_item->psz_name ) : NULL;
+        vlc_mutex_unlock( &p_item->lock );
+        return psz_ret;
+    }
+
+    const char *psz_title = vlc_meta_Get( p_item->p_meta, vlc_meta_Title );
+    if( !EMPTY_STR( psz_title ) )
+        psz_ret = strdup( psz_title );
+    else
+        psz_ret = p_item->psz_name ? strdup( p_item->psz_name ) : NULL;
+
+    vlc_mutex_unlock( &p_item->lock );
+    return psz_ret;
+}
+
 char *input_item_GetName( input_item_t *p_item )
 {
     vlc_mutex_lock( &p_item->lock );
@@ -344,8 +368,36 @@ void input_item_SetURI( input_item_t *p_i, const char *psz_uri )
             p_i->psz_name = strdup( psz_filename );
     }
 
+    /* The name is NULL: fill it with everything except login and password */
     if( !p_i->psz_name )
-        p_i->psz_name = strdup( p_i->psz_uri );
+    {
+        int r;
+        vlc_url_t url;
+        vlc_UrlParse( &url, psz_uri, 0 );
+        if( url.psz_protocol )
+        {
+            if( url.i_port > 0 )
+                r=asprintf( &p_i->psz_name, "%s://%s:%d%s", url.psz_protocol,
+                          url.psz_host, url.i_port,
+                          url.psz_path ? url.psz_path : "" );
+            else
+                r=asprintf( &p_i->psz_name, "%s://%s%s", url.psz_protocol,
+                          url.psz_host ? url.psz_host : "",
+                          url.psz_path ? url.psz_path : "" );
+        }
+        else
+        {
+            if( url.i_port > 0 )
+                r=asprintf( &p_i->psz_name, "%s:%d%s", url.psz_host, url.i_port,
+                          url.psz_path ? url.psz_path : "" );
+            else
+                r=asprintf( &p_i->psz_name, "%s%s", url.psz_host,
+                          url.psz_path ? url.psz_path : "" );
+        }
+        vlc_UrlClean( &url );
+        if( -1==r )
+            p_i->psz_name=NULL; /* recover from undefined value */
+    }
 
     vlc_mutex_unlock( &p_i->lock );
 }
@@ -401,43 +453,6 @@ bool input_item_IsArtFetched( input_item_t *p_item )
     return b_fetched;
 }
 
-/**
- * Get a info item from a given category in a given input item.
- *
- * \param p_i The input item to get info from
- * \param psz_cat String representing the category for the info
- * \param psz_name String representing the name of the desired info
- * \return A pointer to the string with the given info if found, or an
- *         empty string otherwise. The caller should free the returned
- *         pointer.
- */
-char *input_item_GetInfo( input_item_t *p_i,
-                          const char *psz_cat,
-                          const char *psz_name )
-{
-    vlc_mutex_lock( &p_i->lock );
-
-    for( int i = 0; i< p_i->i_categories; i++ )
-    {
-        const info_category_t *p_cat = p_i->pp_categories[i];
-
-        if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
-            continue;
-
-        for( int j = 0; j < p_cat->i_infos; j++ )
-        {
-            if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
-            {
-                char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
-                vlc_mutex_unlock( &p_i->lock );
-                return psz_ret;
-            }
-        }
-    }
-    vlc_mutex_unlock( &p_i->lock );
-    return strdup( "" );
-}
-
 static void input_item_Destroy ( gc_object_t *p_gc )
 {
     input_item_t *p_item = vlc_priv( p_gc, input_item_t );
@@ -478,17 +493,53 @@ out:
     return err;
 }
 
-int input_item_AddInfo( input_item_t *p_i,
-                        const char *psz_cat,
-                        const char *psz_name,
-                        const char *psz_format, ... )
+/**
+ * Get a info item from a given category in a given input item.
+ *
+ * \param p_i The input item to get info from
+ * \param psz_cat String representing the category for the info
+ * \param psz_name String representing the name of the desired info
+ * \return A pointer to the string with the given info if found, or an
+ *         empty string otherwise. The caller should free the returned
+ *         pointer.
+ */
+char *input_item_GetInfo( input_item_t *p_i,
+                          const char *psz_cat,
+                          const char *psz_name )
+{
+    vlc_mutex_lock( &p_i->lock );
+
+    for( int i = 0; i< p_i->i_categories; i++ )
+    {
+        const info_category_t *p_cat = p_i->pp_categories[i];
+
+        if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
+            continue;
+
+        for( int j = 0; j < p_cat->i_infos; j++ )
+        {
+            if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
+            {
+                char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
+                vlc_mutex_unlock( &p_i->lock );
+                return psz_ret;
+            }
+        }
+    }
+    vlc_mutex_unlock( &p_i->lock );
+    return strdup( "" );
+}
+
+static int InputItemVaAddInfo( input_item_t *p_i,
+                               const char *psz_cat,
+                               const char *psz_name,
+                               const char *psz_format, va_list args )
 {
-    va_list args;
     int i;
     info_t *p_info = NULL;
     info_category_t *p_cat = NULL ;
 
-    vlc_mutex_lock( &p_i->lock );
+    vlc_assert_locked( &p_i->lock );
 
     for( i = 0 ; i < p_i->i_categories ; i ++ )
     {
@@ -500,11 +551,9 @@ int input_item_AddInfo( input_item_t *p_i,
     }
     if( !p_cat )
     {
-        if( !(p_cat = (info_category_t *)malloc( sizeof(info_category_t) )) )
-        {
-            vlc_mutex_unlock( &p_i->lock );
+        if( !(p_cat = malloc( sizeof(*p_cat) )) )
             return VLC_ENOMEM;
-        }
+
         p_cat->psz_name = strdup( psz_cat );
         p_cat->i_infos = 0;
         p_cat->pp_infos = 0;
@@ -523,11 +572,9 @@ int input_item_AddInfo( input_item_t *p_i,
 
     if( !p_info )
     {
-        if( ( p_info = (info_t *)malloc( sizeof( info_t ) ) ) == NULL )
-        {
-            vlc_mutex_unlock( &p_i->lock );
+        if( ( p_info = malloc( sizeof( *p_info ) ) ) == NULL )
             return VLC_ENOMEM;
-        }
+
         INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
         p_info->psz_name = strdup( psz_name );
     }
@@ -536,22 +583,52 @@ int input_item_AddInfo( input_item_t *p_i,
         free( p_info->psz_value );
     }
 
-    va_start( args, psz_format );
-    if( vasprintf( &p_info->psz_value, psz_format, args) == -1 )
+    if( vasprintf( &p_info->psz_value, psz_format, args ) == -1 )
         p_info->psz_value = NULL;
+
+    return p_info->psz_value ? VLC_SUCCESS : VLC_ENOMEM;
+}
+
+static int InputItemAddInfo( input_item_t *p_i,
+                             const char *psz_cat,
+                             const char *psz_name,
+                             const char *psz_format, ... )
+{
+    va_list args;
+
+    va_start( args, psz_format );
+    const int i_ret = InputItemVaAddInfo( p_i, psz_cat, psz_name, psz_format, args );
+    va_end( args );
+
+    return i_ret;
+}
+
+int input_item_AddInfo( input_item_t *p_i,
+                        const char *psz_cat,
+                        const char *psz_name,
+                        const char *psz_format, ... )
+{
+    va_list args;
+
+    vlc_mutex_lock( &p_i->lock );
+
+    va_start( args, psz_format );
+    const int i_ret = InputItemVaAddInfo( p_i, psz_cat, psz_name, psz_format, args );
     va_end( args );
 
     vlc_mutex_unlock( &p_i->lock );
 
-    if( p_info->psz_value )
+
+    if( !i_ret )
     {
         vlc_event_t event;
 
         event.type = vlc_InputItemInfoChanged;
         vlc_event_send( &p_i->event_manager, &event );
     }
-    return p_info->psz_value ? VLC_SUCCESS : VLC_ENOMEM;
+    return i_ret;
 }
+
 int input_item_DelInfo( input_item_t *p_i,
                         const char *psz_cat,
                         const char *psz_name )
@@ -622,15 +699,57 @@ int input_item_DelInfo( input_item_t *p_i,
     return VLC_SUCCESS;
 }
 
+void input_item_SetEpg( input_item_t *p_item,
+                        const char *psz_epg, const vlc_epg_t *p_epg )
+{
+    input_item_DelInfo( p_item, psz_epg, NULL );
+
+#ifdef HAVE_LOCALTIME_R
+    vlc_mutex_lock( &p_item->lock );
+    for( int i = 0; i < p_epg->i_event; i++ )
+    {
+        const vlc_epg_event_t *p_evt = p_epg->pp_event[i];
+        time_t t_start = (time_t)p_evt->i_start;
+        struct tm tm_start;
+        char psz_start[128];
+
+        localtime_r( &t_start, &tm_start );
+
+        snprintf( psz_start, sizeof(psz_start), "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
+                  1900 + tm_start.tm_year, 1 + tm_start.tm_mon, tm_start.tm_mday,
+                  tm_start.tm_hour, tm_start.tm_min, tm_start.tm_sec );
+        if( p_evt->psz_short_description || p_evt->psz_description )
+            InputItemAddInfo( p_item, psz_epg, psz_start, "%s (%2.2d:%2.2d) - %s",
+                              p_evt->psz_name,
+                              p_evt->i_duration/60/60, (p_evt->i_duration/60)%60,
+                              p_evt->psz_short_description ? p_evt->psz_short_description : p_evt->psz_description );
+        else
+            InputItemAddInfo( p_item, psz_epg, psz_start, "%s (%2.2d:%2.2d)",
+                              p_evt->psz_name,
+                              p_evt->i_duration/60/60, (p_evt->i_duration/60)%60 );
+    }
+    vlc_mutex_unlock( &p_item->lock );
+
+    if( p_epg->i_event > 0 )
+    {
+        vlc_event_t event;
+
+        event.type = vlc_InputItemInfoChanged;
+        vlc_event_send( &p_item->event_manager, &event );
+    }
+#endif
+}
+
 
 input_item_t *__input_item_NewExt( vlc_object_t *p_obj, const char *psz_uri,
                                   const char *psz_name,
                                   int i_options,
                                   const char *const *ppsz_options,
+                                  unsigned i_option_flags,
                                   mtime_t i_duration )
 {
     return input_item_NewWithType( p_obj, psz_uri, psz_name,
-                                  i_options, ppsz_options,
+                                  i_options, ppsz_options, i_option_flags,
                                   i_duration, ITEM_TYPE_UNKNOWN );
 }
 
@@ -639,10 +758,12 @@ input_item_t *input_item_NewWithType( vlc_object_t *p_obj, const char *psz_uri,
                                 const char *psz_name,
                                 int i_options,
                                 const char *const *ppsz_options,
+                                unsigned i_option_flags,
                                 mtime_t i_duration,
                                 int i_type )
 {
     libvlc_priv_t *priv = libvlc_priv (p_obj->p_libvlc);
+    static vlc_mutex_t input_id_lock = VLC_STATIC_MUTEX;
 
     input_item_t* p_input = malloc( sizeof(input_item_t ) );
     if( !p_input )
@@ -651,9 +772,9 @@ input_item_t *input_item_NewWithType( vlc_object_t *p_obj, const char *psz_uri,
     input_item_Init( p_obj, p_input );
     vlc_gc_init( p_input, input_item_Destroy );
 
-    vlc_object_lock( p_obj->p_libvlc );
+    vlc_mutex_lock( &input_id_lock );
     p_input->i_id = ++priv->i_last_input_id;
-    vlc_object_unlock( p_obj->p_libvlc );
+    vlc_mutex_unlock( &input_id_lock );
 
     p_input->b_fixed_name = false;
 
@@ -672,7 +793,7 @@ input_item_t *input_item_NewWithType( vlc_object_t *p_obj, const char *psz_uri,
     p_input->i_duration = i_duration;
 
     for( int i = 0; i < i_options; i++ )
-        input_item_AddOption( p_input, ppsz_options[i], VLC_INPUT_OPTION_TRUSTED );
+        input_item_AddOption( p_input, ppsz_options[i], i_option_flags );
     return p_input;
 }
 
@@ -696,10 +817,12 @@ static void GuessType( input_item_t *p_item)
         { "dvb", ITEM_TYPE_CARD },
         { "qpsk", ITEM_TYPE_CARD },
         { "sdp", ITEM_TYPE_NET },
+        { "ftp", ITEM_TYPE_NET },
+        { "smb", ITEM_TYPE_NET },
         { NULL, 0 }
     };
 
-    if( !p_item->psz_uri )
+    if( !p_item->psz_uri || !strstr( p_item->psz_uri, "://" ) )
     {
         p_item->i_type = ITEM_TYPE_FILE;
         return;