item.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:24k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * item.c: input_item management
  3.  *****************************************************************************
  4.  * Copyright (C) 1998-2004 the VideoLAN team
  5.  * $Id: 7349d9e05bce853ce87f0046373fc8d078d8f41f $
  6.  *
  7.  * Authors: Clément Stenac <zorglub@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License along
  20.  * with this program; if not, write to the Free Software Foundation, Inc.,
  21.  * 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <assert.h>
  27. #include <vlc_common.h>
  28. #include <vlc_url.h>
  29. #include "vlc_playlist.h"
  30. #include "vlc_interface.h"
  31. #include "item.h"
  32. static void GuessType( input_item_t *p_item );
  33. /** Stuff moved out of vlc_input.h -- FIXME: should probably not be inline
  34.  * anyway. */
  35. static inline void input_item_Init( vlc_object_t *p_o, input_item_t *p_i )
  36. {
  37.     memset( p_i, 0, sizeof(input_item_t) );
  38.     p_i->psz_name = NULL;
  39.     p_i->psz_uri = NULL;
  40.     TAB_INIT( p_i->i_es, p_i->es );
  41.     TAB_INIT( p_i->i_options, p_i->ppsz_options );
  42.     p_i->optflagv = NULL, p_i->optflagc = 0;
  43.     TAB_INIT( p_i->i_categories, p_i->pp_categories );
  44.     p_i->i_type = ITEM_TYPE_UNKNOWN;
  45.     p_i->b_fixed_name = true;
  46.     p_i->p_stats = NULL;
  47.     p_i->p_meta = NULL;
  48.     vlc_mutex_init( &p_i->lock );
  49.     vlc_event_manager_t * p_em = &p_i->event_manager;
  50.     vlc_event_manager_init( p_em, p_i, p_o );
  51.     vlc_event_manager_register_event_type( p_em, vlc_InputItemMetaChanged );
  52.     vlc_event_manager_register_event_type( p_em, vlc_InputItemSubItemAdded );
  53.     vlc_event_manager_register_event_type( p_em, vlc_InputItemDurationChanged );
  54.     vlc_event_manager_register_event_type( p_em, vlc_InputItemPreparsedChanged );
  55.     vlc_event_manager_register_event_type( p_em, vlc_InputItemNameChanged );
  56.     vlc_event_manager_register_event_type( p_em, vlc_InputItemInfoChanged );
  57.     vlc_event_manager_register_event_type( p_em, vlc_InputItemErrorWhenReadingChanged );
  58. }
  59. static inline void input_item_Clean( input_item_t *p_i )
  60. {
  61.     int i;
  62.     vlc_event_manager_fini( &p_i->event_manager );
  63.     free( p_i->psz_name );
  64.     free( p_i->psz_uri );
  65.     if( p_i->p_stats )
  66.     {
  67.         vlc_mutex_destroy( &p_i->p_stats->lock );
  68.         free( p_i->p_stats );
  69.     }
  70.     if( p_i->p_meta )
  71.         vlc_meta_Delete( p_i->p_meta );
  72.     for( i = 0; i < p_i->i_options; i++ )
  73.         free( p_i->ppsz_options[i] );
  74.     TAB_CLEAN( p_i->i_options, p_i->ppsz_options );
  75.     free( p_i->optflagv);
  76.     for( i = 0; i < p_i->i_es; i++ )
  77.     {
  78.         es_format_Clean( p_i->es[i] );
  79.         free( p_i->es[i] );
  80.     }
  81.     TAB_CLEAN( p_i->i_es, p_i->es );
  82.     for( i = 0; i < p_i->i_categories; i++ )
  83.     {
  84.         info_category_t *p_category = p_i->pp_categories[i];
  85.         int j;
  86.         for( j = 0; j < p_category->i_infos; j++ )
  87.         {
  88.             struct info_t *p_info = p_category->pp_infos[j];
  89.             free( p_info->psz_name);
  90.             free( p_info->psz_value );
  91.             free( p_info );
  92.         }
  93.         TAB_CLEAN( p_category->i_infos, p_category->pp_infos );
  94.         free( p_category->psz_name );
  95.         free( p_category );
  96.     }
  97.     TAB_CLEAN( p_i->i_categories, p_i->pp_categories );
  98.     vlc_mutex_destroy( &p_i->lock );
  99. }
  100. void input_item_SetErrorWhenReading( input_item_t *p_i, bool b_error )
  101. {
  102.     bool b_changed;
  103.     vlc_mutex_lock( &p_i->lock );
  104.     b_changed = p_i->b_error_when_reading != b_error;
  105.     p_i->b_error_when_reading = b_error;
  106.     vlc_mutex_unlock( &p_i->lock );
  107.     if( b_changed )
  108.     {
  109.         vlc_event_t event;
  110.         event.type = vlc_InputItemErrorWhenReadingChanged;
  111.         event.u.input_item_error_when_reading_changed.new_value = b_error;
  112.         vlc_event_send( &p_i->event_manager, &event );
  113.     }
  114. }
  115. void input_item_SetPreparsed( input_item_t *p_i, bool b_preparsed )
  116. {
  117.     bool b_send_event = false;
  118.     vlc_mutex_lock( &p_i->lock );
  119.     if( !p_i->p_meta )
  120.         p_i->p_meta = vlc_meta_New();
  121.     int i_new_status;
  122.     if( b_preparsed )
  123.         i_new_status = p_i->p_meta->i_status | ITEM_PREPARSED;
  124.     else
  125.         i_new_status = p_i->p_meta->i_status & ~ITEM_PREPARSED;
  126.     if( p_i->p_meta->i_status != i_new_status )
  127.     {
  128.         p_i->p_meta->i_status = i_new_status;
  129.         b_send_event = true;
  130.     }
  131.     vlc_mutex_unlock( &p_i->lock );
  132.     if( b_send_event )
  133.     {
  134.         vlc_event_t event;
  135.         event.type = vlc_InputItemPreparsedChanged;
  136.         event.u.input_item_preparsed_changed.new_status = i_new_status;
  137.         vlc_event_send( &p_i->event_manager, &event );
  138.     }
  139. }
  140. void input_item_SetArtNotFound( input_item_t *p_i, bool b_not_found )
  141. {
  142.     vlc_mutex_lock( &p_i->lock );
  143.     if( !p_i->p_meta )
  144.         p_i->p_meta = vlc_meta_New();
  145.     if( b_not_found )
  146.         p_i->p_meta->i_status |= ITEM_ART_NOTFOUND;
  147.     else
  148.         p_i->p_meta->i_status &= ~ITEM_ART_NOTFOUND;
  149.     vlc_mutex_unlock( &p_i->lock );
  150. }
  151. void input_item_SetArtFetched( input_item_t *p_i, bool b_art_fetched )
  152. {
  153.     vlc_mutex_lock( &p_i->lock );
  154.     if( !p_i->p_meta )
  155.         p_i->p_meta = vlc_meta_New();
  156.     if( b_art_fetched )
  157.         p_i->p_meta->i_status |= ITEM_ART_FETCHED;
  158.     else
  159.         p_i->p_meta->i_status &= ~ITEM_ART_FETCHED;
  160.     vlc_mutex_unlock( &p_i->lock );
  161. }
  162. void input_item_SetMeta( input_item_t *p_i, vlc_meta_type_t meta_type, const char *psz_val )
  163. {
  164.     vlc_event_t event;
  165.     vlc_mutex_lock( &p_i->lock );
  166.     if( !p_i->p_meta )
  167.         p_i->p_meta = vlc_meta_New();
  168.     vlc_meta_Set( p_i->p_meta, meta_type, psz_val );
  169.     vlc_mutex_unlock( &p_i->lock );
  170.     /* Notify interested third parties */
  171.     event.type = vlc_InputItemMetaChanged;
  172.     event.u.input_item_meta_changed.meta_type = meta_type;
  173.     vlc_event_send( &p_i->event_manager, &event );
  174. }
  175. /* FIXME GRRRRRRRRRR args should be in the reverse order to be 
  176.  * consistant with (nearly?) all or copy funcs */
  177. void input_item_CopyOptions( input_item_t *p_parent,
  178.                              input_item_t *p_child )
  179. {
  180.     vlc_mutex_lock( &p_parent->lock );
  181.     for( int i = 0 ; i< p_parent->i_options; i++ )
  182.     {
  183.         if( !strcmp( p_parent->ppsz_options[i], "meta-file" ) )
  184.             continue;
  185.         input_item_AddOption( p_child,
  186.                               p_parent->ppsz_options[i],
  187.                               p_parent->optflagv[i] );
  188.     }
  189.     vlc_mutex_unlock( &p_parent->lock );
  190. }
  191. /* This won't hold the item, but can tell to interested third parties
  192.  * Like the playlist, that there is a new sub item. With this design
  193.  * It is not the input item's responsability to keep all the ref of
  194.  * the input item children. */
  195. void input_item_AddSubItem( input_item_t *p_parent, input_item_t *p_child )
  196. {
  197.     vlc_mutex_lock( &p_parent->lock );
  198.     p_parent->i_type = ITEM_TYPE_PLAYLIST;
  199.     vlc_mutex_unlock( &p_parent->lock );
  200.     /* Notify interested third parties */
  201.     vlc_event_t event;
  202.     event.type = vlc_InputItemSubItemAdded;
  203.     event.u.input_item_subitem_added.p_new_child = p_child;
  204.     vlc_event_send( &p_parent->event_manager, &event );
  205. }
  206. bool input_item_HasErrorWhenReading( input_item_t *p_item )
  207. {
  208.     vlc_mutex_lock( &p_item->lock );
  209.     bool b_error = p_item->b_error_when_reading;
  210.     vlc_mutex_unlock( &p_item->lock );
  211.     return b_error;
  212. }
  213. bool input_item_MetaMatch( input_item_t *p_i,
  214.                            vlc_meta_type_t meta_type, const char *psz )
  215. {
  216.     vlc_mutex_lock( &p_i->lock );
  217.     if( !p_i->p_meta )
  218.     {
  219.         vlc_mutex_unlock( &p_i->lock );
  220.         return false;
  221.     }
  222.     const char *psz_meta = vlc_meta_Get( p_i->p_meta, meta_type );
  223.     bool b_ret = psz_meta && strcasestr( psz_meta, psz );
  224.     vlc_mutex_unlock( &p_i->lock );
  225.     return b_ret;
  226. }
  227. char *input_item_GetMeta( input_item_t *p_i, vlc_meta_type_t meta_type )
  228. {
  229.     vlc_mutex_lock( &p_i->lock );
  230.     if( !p_i->p_meta )
  231.     {
  232.         vlc_mutex_unlock( &p_i->lock );
  233.         return NULL;
  234.     }
  235.     char *psz = NULL;
  236.     if( vlc_meta_Get( p_i->p_meta, meta_type ) )
  237.         psz = strdup( vlc_meta_Get( p_i->p_meta, meta_type ) );
  238.     vlc_mutex_unlock( &p_i->lock );
  239.     return psz;
  240. }
  241. /* Get the title of a given item or fallback to the name if the title is empty */
  242. char *input_item_GetTitleFbName( input_item_t *p_item )
  243. {
  244.     char *psz_ret;
  245.     vlc_mutex_lock( &p_item->lock );
  246.     if( !p_item->p_meta )
  247.     {
  248.         psz_ret = p_item->psz_name ? strdup( p_item->psz_name ) : NULL;
  249.         vlc_mutex_unlock( &p_item->lock );
  250.         return psz_ret;
  251.     }
  252.     const char *psz_title = vlc_meta_Get( p_item->p_meta, vlc_meta_Title );
  253.     if( !EMPTY_STR( psz_title ) )
  254.         psz_ret = strdup( psz_title );
  255.     else
  256.         psz_ret = p_item->psz_name ? strdup( p_item->psz_name ) : NULL;
  257.     vlc_mutex_unlock( &p_item->lock );
  258.     return psz_ret;
  259. }
  260. char *input_item_GetName( input_item_t *p_item )
  261. {
  262.     vlc_mutex_lock( &p_item->lock );
  263.     char *psz_name = p_item->psz_name ? strdup( p_item->psz_name ) : NULL;
  264.     vlc_mutex_unlock( &p_item->lock );
  265.     return psz_name;
  266. }
  267. void input_item_SetName( input_item_t *p_item, const char *psz_name )
  268. {
  269.     vlc_mutex_lock( &p_item->lock );
  270.     free( p_item->psz_name );
  271.     p_item->psz_name = strdup( psz_name );
  272.     vlc_mutex_unlock( &p_item->lock );
  273. }
  274. char *input_item_GetURI( input_item_t *p_i )
  275. {
  276.     vlc_mutex_lock( &p_i->lock );
  277.     char *psz_s = p_i->psz_uri ? strdup( p_i->psz_uri ) : NULL;
  278.     vlc_mutex_unlock( &p_i->lock );
  279.     return psz_s;
  280. }
  281. void input_item_SetURI( input_item_t *p_i, const char *psz_uri )
  282. {
  283.     vlc_mutex_lock( &p_i->lock );
  284.     free( p_i->psz_uri );
  285.     p_i->psz_uri = strdup( psz_uri );
  286.     GuessType( p_i );
  287.     if( !p_i->psz_name && p_i->i_type == ITEM_TYPE_FILE )
  288.     {
  289.         const char *psz_filename;
  290.         bool b_path = !strstr( p_i->psz_uri, "://" );
  291.         psz_filename = strrchr( p_i->psz_uri, b_path ? DIR_SEP_CHAR : '/' );
  292.         if( psz_filename && ( *psz_filename == (b_path ? DIR_SEP_CHAR : '/') ) )
  293.             psz_filename++;
  294.         if( psz_filename && *psz_filename )
  295.             p_i->psz_name = strdup( psz_filename );
  296.         /* Make the name more readable */
  297.         if( !b_path && p_i->psz_name )
  298.             decode_URI( p_i->psz_name );
  299.     }
  300.     /* The name is NULL: fill it with everything except login and password */
  301.     if( !p_i->psz_name )
  302.     {
  303.         int r;
  304.         vlc_url_t url;
  305.         vlc_UrlParse( &url, psz_uri, 0 );
  306.         if( url.psz_protocol )
  307.         {
  308.             if( url.i_port > 0 )
  309.                 r=asprintf( &p_i->psz_name, "%s://%s:%d%s", url.psz_protocol,
  310.                           url.psz_host, url.i_port,
  311.                           url.psz_path ? url.psz_path : "" );
  312.             else
  313.                 r=asprintf( &p_i->psz_name, "%s://%s%s", url.psz_protocol,
  314.                           url.psz_host ? url.psz_host : "",
  315.                           url.psz_path ? url.psz_path : "" );
  316.         }
  317.         else
  318.         {
  319.             if( url.i_port > 0 )
  320.                 r=asprintf( &p_i->psz_name, "%s:%d%s", url.psz_host, url.i_port,
  321.                           url.psz_path ? url.psz_path : "" );
  322.             else
  323.                 r=asprintf( &p_i->psz_name, "%s%s", url.psz_host,
  324.                           url.psz_path ? url.psz_path : "" );
  325.         }
  326.         vlc_UrlClean( &url );
  327.         if( -1==r )
  328.             p_i->psz_name=NULL; /* recover from undefined value */
  329.     }
  330.     vlc_mutex_unlock( &p_i->lock );
  331. }
  332. mtime_t input_item_GetDuration( input_item_t *p_i )
  333. {
  334.     vlc_mutex_lock( &p_i->lock );
  335.     mtime_t i_duration = p_i->i_duration;
  336.     vlc_mutex_unlock( &p_i->lock );
  337.     return i_duration;
  338. }
  339. void input_item_SetDuration( input_item_t *p_i, mtime_t i_duration )
  340. {
  341.     bool b_send_event = false;
  342.     vlc_mutex_lock( &p_i->lock );
  343.     if( p_i->i_duration != i_duration )
  344.     {
  345.         p_i->i_duration = i_duration;
  346.         b_send_event = true;
  347.     }
  348.     vlc_mutex_unlock( &p_i->lock );
  349.     if( b_send_event )
  350.     {
  351.         vlc_event_t event;
  352.         event.type = vlc_InputItemDurationChanged;
  353.         event.u.input_item_duration_changed.new_duration = i_duration;
  354.         vlc_event_send( &p_i->event_manager, &event );
  355.     }
  356. }
  357. bool input_item_IsPreparsed( input_item_t *p_item )
  358. {
  359.     vlc_mutex_lock( &p_item->lock );
  360.     bool b_preparsed = p_item->p_meta ? ( p_item->p_meta->i_status & ITEM_PREPARSED ) != 0 : false;
  361.     vlc_mutex_unlock( &p_item->lock );
  362.     return b_preparsed;
  363. }
  364. bool input_item_IsArtFetched( input_item_t *p_item )
  365. {
  366.     vlc_mutex_lock( &p_item->lock );
  367.     bool b_fetched = p_item->p_meta ? ( p_item->p_meta->i_status & ITEM_ART_FETCHED ) != 0 : false;
  368.     vlc_mutex_unlock( &p_item->lock );
  369.     return b_fetched;
  370. }
  371. static void input_item_Destroy ( gc_object_t *p_gc )
  372. {
  373.     input_item_t *p_item = vlc_priv( p_gc, input_item_t );
  374.     input_item_Clean( p_item );
  375.     free( p_item );
  376. }
  377. int input_item_AddOption( input_item_t *p_input, const char *psz_option,
  378.                           unsigned flags )
  379. {
  380.     int err = VLC_SUCCESS;
  381.     if( psz_option == NULL )
  382.         return VLC_EGENERIC;
  383.     vlc_mutex_lock( &p_input->lock );
  384.     if (flags & VLC_INPUT_OPTION_UNIQUE)
  385.     {
  386.         for (int i = 0 ; i < p_input->i_options; i++)
  387.             if( !strcmp( p_input->ppsz_options[i], psz_option ) )
  388.                 goto out;
  389.     }
  390.     uint8_t *flagv = realloc (p_input->optflagv, p_input->optflagc + 1);
  391.     if (flagv == NULL)
  392.     {
  393.         err = VLC_ENOMEM;
  394.         goto out;
  395.     }
  396.     p_input->optflagv = flagv;
  397.     flagv[p_input->optflagc++] = flags;
  398.     INSERT_ELEM( p_input->ppsz_options, p_input->i_options,
  399.                  p_input->i_options, strdup( psz_option ) );
  400. out:
  401.     vlc_mutex_unlock( &p_input->lock );
  402.     return err;
  403. }
  404. /**
  405.  * Get a info item from a given category in a given input item.
  406.  *
  407.  * param p_i The input item to get info from
  408.  * param psz_cat String representing the category for the info
  409.  * param psz_name String representing the name of the desired info
  410.  * return A pointer to the string with the given info if found, or an
  411.  *         empty string otherwise. The caller should free the returned
  412.  *         pointer.
  413.  */
  414. char *input_item_GetInfo( input_item_t *p_i,
  415.                           const char *psz_cat,
  416.                           const char *psz_name )
  417. {
  418.     vlc_mutex_lock( &p_i->lock );
  419.     for( int i = 0; i< p_i->i_categories; i++ )
  420.     {
  421.         const info_category_t *p_cat = p_i->pp_categories[i];
  422.         if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
  423.             continue;
  424.         for( int j = 0; j < p_cat->i_infos; j++ )
  425.         {
  426.             if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
  427.             {
  428.                 char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
  429.                 vlc_mutex_unlock( &p_i->lock );
  430.                 return psz_ret;
  431.             }
  432.         }
  433.     }
  434.     vlc_mutex_unlock( &p_i->lock );
  435.     return strdup( "" );
  436. }
  437. static int InputItemVaAddInfo( input_item_t *p_i,
  438.                                const char *psz_cat,
  439.                                const char *psz_name,
  440.                                const char *psz_format, va_list args )
  441. {
  442.     int i;
  443.     info_t *p_info = NULL;
  444.     info_category_t *p_cat = NULL ;
  445.     vlc_assert_locked( &p_i->lock );
  446.     for( i = 0 ; i < p_i->i_categories ; i ++ )
  447.     {
  448.         if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) )
  449.         {
  450.             p_cat = p_i->pp_categories[i];
  451.             break;
  452.         }
  453.     }
  454.     if( !p_cat )
  455.     {
  456.         if( !(p_cat = malloc( sizeof(*p_cat) )) )
  457.             return VLC_ENOMEM;
  458.         p_cat->psz_name = strdup( psz_cat );
  459.         p_cat->i_infos = 0;
  460.         p_cat->pp_infos = 0;
  461.         INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories,
  462.                      p_cat );
  463.     }
  464.     for( i = 0; i< p_cat->i_infos; i++ )
  465.     {
  466.         if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
  467.         {
  468.             p_info = p_cat->pp_infos[i];
  469.             break;
  470.         }
  471.     }
  472.     if( !p_info )
  473.     {
  474.         if( ( p_info = malloc( sizeof( *p_info ) ) ) == NULL )
  475.             return VLC_ENOMEM;
  476.         INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
  477.         p_info->psz_name = strdup( psz_name );
  478.     }
  479.     else
  480.     {
  481.         free( p_info->psz_value );
  482.     }
  483.     if( vasprintf( &p_info->psz_value, psz_format, args ) == -1 )
  484.         p_info->psz_value = NULL;
  485.     return p_info->psz_value ? VLC_SUCCESS : VLC_ENOMEM;
  486. }
  487. static int InputItemAddInfo( input_item_t *p_i,
  488.                              const char *psz_cat,
  489.                              const char *psz_name,
  490.                              const char *psz_format, ... )
  491. {
  492.     va_list args;
  493.     va_start( args, psz_format );
  494.     const int i_ret = InputItemVaAddInfo( p_i, psz_cat, psz_name, psz_format, args );
  495.     va_end( args );
  496.     return i_ret;
  497. }
  498. int input_item_AddInfo( input_item_t *p_i,
  499.                         const char *psz_cat,
  500.                         const char *psz_name,
  501.                         const char *psz_format, ... )
  502. {
  503.     va_list args;
  504.     vlc_mutex_lock( &p_i->lock );
  505.     va_start( args, psz_format );
  506.     const int i_ret = InputItemVaAddInfo( p_i, psz_cat, psz_name, psz_format, args );
  507.     va_end( args );
  508.     vlc_mutex_unlock( &p_i->lock );
  509.     if( !i_ret )
  510.     {
  511.         vlc_event_t event;
  512.         event.type = vlc_InputItemInfoChanged;
  513.         vlc_event_send( &p_i->event_manager, &event );
  514.     }
  515.     return i_ret;
  516. }
  517. int input_item_DelInfo( input_item_t *p_i,
  518.                         const char *psz_cat,
  519.                         const char *psz_name )
  520. {
  521.     info_category_t *p_cat = NULL;
  522.     int i_cat;
  523.     int i;
  524.     vlc_mutex_lock( &p_i->lock );
  525.     for( i_cat = 0; i_cat < p_i->i_categories; i_cat++ )
  526.     {
  527.         if( !strcmp( p_i->pp_categories[i_cat]->psz_name,
  528.                      psz_cat ) )
  529.         {
  530.             p_cat = p_i->pp_categories[i_cat];
  531.             break;
  532.         }
  533.     }
  534.     if( p_cat == NULL )
  535.     {
  536.         vlc_mutex_unlock( &p_i->lock );
  537.         return VLC_EGENERIC;
  538.     }
  539.     if( psz_name )
  540.     {
  541.         /* Remove a specific info */
  542.         for( i = 0; i < p_cat->i_infos; i++ )
  543.         {
  544.             if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
  545.             {
  546.                 free( p_cat->pp_infos[i]->psz_name );
  547.                 free( p_cat->pp_infos[i]->psz_value );
  548.                 free( p_cat->pp_infos[i] );
  549.                 REMOVE_ELEM( p_cat->pp_infos, p_cat->i_infos, i );
  550.                 break;
  551.             }
  552.         }
  553.         if( i >= p_cat->i_infos )
  554.         {
  555.             vlc_mutex_unlock( &p_i->lock );
  556.             return VLC_EGENERIC;
  557.         }
  558.     }
  559.     else
  560.     {
  561.         /* Remove the complete categorie */
  562.         for( i = 0; i < p_cat->i_infos; i++ )
  563.         {
  564.             free( p_cat->pp_infos[i]->psz_name );
  565.             free( p_cat->pp_infos[i]->psz_value );
  566.             free( p_cat->pp_infos[i] );
  567.         }
  568.         free( p_cat->pp_infos );
  569.         REMOVE_ELEM( p_i->pp_categories, p_i->i_categories, i_cat );
  570.     }
  571.     // Free the category
  572.     free( p_cat->psz_name );
  573.     free( p_cat );
  574.     vlc_mutex_unlock( &p_i->lock );
  575.     vlc_event_t event;
  576.     event.type = vlc_InputItemInfoChanged;
  577.     vlc_event_send( &p_i->event_manager, &event );
  578.     return VLC_SUCCESS;
  579. }
  580. void input_item_SetEpg( input_item_t *p_item,
  581.                         const char *psz_epg, const vlc_epg_t *p_epg )
  582. {
  583.     input_item_DelInfo( p_item, psz_epg, NULL );
  584.     vlc_mutex_lock( &p_item->lock );
  585.     for( int i = 0; i < p_epg->i_event; i++ )
  586.     {
  587.         const vlc_epg_event_t *p_evt = p_epg->pp_event[i];
  588.         time_t t_start = (time_t)p_evt->i_start;
  589.         struct tm tm_start;
  590.         char psz_start[128];
  591.         localtime_r( &t_start, &tm_start );
  592.         snprintf( psz_start, sizeof(psz_start), "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
  593.                   1900 + tm_start.tm_year, 1 + tm_start.tm_mon, tm_start.tm_mday,
  594.                   tm_start.tm_hour, tm_start.tm_min, tm_start.tm_sec );
  595.         if( p_evt->psz_short_description || p_evt->psz_description )
  596.             InputItemAddInfo( p_item, psz_epg, psz_start, "%s (%2.2d:%2.2d) - %s %s",
  597.                               p_evt->psz_name,
  598.                               p_evt->i_duration/60/60, (p_evt->i_duration/60)%60,
  599.                               p_evt->psz_short_description ? p_evt->psz_short_description : "" ,
  600.                               p_evt->psz_description ? p_evt->psz_description : "" );
  601.         else
  602.             InputItemAddInfo( p_item, psz_epg, psz_start, "%s (%2.2d:%2.2d)",
  603.                               p_evt->psz_name,
  604.                               p_evt->i_duration/60/60, (p_evt->i_duration/60)%60 );
  605.     }
  606.     vlc_mutex_unlock( &p_item->lock );
  607.     if( p_epg->i_event > 0 )
  608.     {
  609.         vlc_event_t event;
  610.         event.type = vlc_InputItemInfoChanged;
  611.         vlc_event_send( &p_item->event_manager, &event );
  612.     }
  613. }
  614. input_item_t *__input_item_NewExt( vlc_object_t *p_obj, const char *psz_uri,
  615.                                   const char *psz_name,
  616.                                   int i_options,
  617.                                   const char *const *ppsz_options,
  618.                                   unsigned i_option_flags,
  619.                                   mtime_t i_duration )
  620. {
  621.     return input_item_NewWithType( p_obj, psz_uri, psz_name,
  622.                                   i_options, ppsz_options, i_option_flags,
  623.                                   i_duration, ITEM_TYPE_UNKNOWN );
  624. }
  625. input_item_t *input_item_NewWithType( vlc_object_t *p_obj, const char *psz_uri,
  626.                                 const char *psz_name,
  627.                                 int i_options,
  628.                                 const char *const *ppsz_options,
  629.                                 unsigned i_option_flags,
  630.                                 mtime_t i_duration,
  631.                                 int i_type )
  632. {
  633.     libvlc_priv_t *priv = libvlc_priv (p_obj->p_libvlc);
  634.     static vlc_mutex_t input_id_lock = VLC_STATIC_MUTEX;
  635.     input_item_t* p_input = malloc( sizeof(input_item_t ) );
  636.     if( !p_input )
  637.         return NULL;
  638.     input_item_Init( p_obj, p_input );
  639.     vlc_gc_init( p_input, input_item_Destroy );
  640.     vlc_mutex_lock( &input_id_lock );
  641.     p_input->i_id = ++priv->i_last_input_id;
  642.     vlc_mutex_unlock( &input_id_lock );
  643.     p_input->b_fixed_name = false;
  644.     p_input->i_type = i_type;
  645.     p_input->b_prefers_tree = false;
  646.     if( psz_uri )
  647.         input_item_SetURI( p_input, psz_uri );
  648.     if( i_type != ITEM_TYPE_UNKNOWN )
  649.         p_input->i_type = i_type;
  650.     if( psz_name )
  651.         input_item_SetName( p_input, psz_name );
  652.     p_input->i_duration = i_duration;
  653.     for( int i = 0; i < i_options; i++ )
  654.         input_item_AddOption( p_input, ppsz_options[i], i_option_flags );
  655.     return p_input;
  656. }
  657. /* Guess the type of the item using the beginning of the mrl */
  658. static void GuessType( input_item_t *p_item)
  659. {
  660.     int i;
  661.     static struct { const char *psz_search; int i_type; }  types_array[] =
  662.     {
  663.         { "http", ITEM_TYPE_NET },
  664.         { "dvd", ITEM_TYPE_DISC },
  665.         { "cdda", ITEM_TYPE_CDDA },
  666.         { "mms", ITEM_TYPE_NET },
  667.         { "rtsp", ITEM_TYPE_NET },
  668.         { "udp", ITEM_TYPE_NET },
  669.         { "rtp", ITEM_TYPE_NET },
  670.         { "vcd", ITEM_TYPE_DISC },
  671.         { "v4l", ITEM_TYPE_CARD },
  672.         { "dshow", ITEM_TYPE_CARD },
  673.         { "pvr", ITEM_TYPE_CARD },
  674.         { "dvb", ITEM_TYPE_CARD },
  675.         { "qpsk", ITEM_TYPE_CARD },
  676.         { "sdp", ITEM_TYPE_NET },
  677.         { "ftp", ITEM_TYPE_NET },
  678.         { "smb", ITEM_TYPE_NET },
  679.         { NULL, 0 }
  680.     };
  681.     if( !p_item->psz_uri || !strstr( p_item->psz_uri, "://" ) )
  682.     {
  683.         p_item->i_type = ITEM_TYPE_FILE;
  684.         return;
  685.     }
  686.     for( i = 0; types_array[i].psz_search != NULL; i++ )
  687.     {
  688.         if( !strncmp( p_item->psz_uri, types_array[i].psz_search,
  689.                       strlen( types_array[i].psz_search ) ) )
  690.         {
  691.             p_item->i_type = types_array[i].i_type;
  692.             return;
  693.         }
  694.     }
  695.     p_item->i_type = ITEM_TYPE_FILE;
  696. }