1 /*****************************************************************************
2 * item.c: input_item management
3 *****************************************************************************
4 * Copyright (C) 1998-2004 the VideoLAN team
7 * Authors: Clément Stenac <zorglub@videolan.org>
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.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
25 #include "vlc_playlist.h"
26 #include "vlc_interface.h"
28 #include "input_internal.h"
30 static void GuessType( input_item_t *p_item );
33 * Get the item from an input thread
35 input_item_t *input_GetItem( input_thread_t *p_input )
37 assert( p_input && p_input->p );
38 return p_input->p->input.p_item;
42 * Get a info item from a given category in a given input item.
44 * \param p_i The input item to get info from
45 * \param psz_cat String representing the category for the info
46 * \param psz_name String representing the name of the desired info
47 * \return A pointer to the string with the given info if found, or an
48 * empty string otherwise. The caller should free the returned
51 char *input_ItemGetInfo( input_item_t *p_i,
53 const char *psz_name )
57 vlc_mutex_lock( &p_i->lock );
59 for( i = 0 ; i< p_i->i_categories ; i++ )
61 info_category_t *p_cat = p_i->pp_categories[i];
63 if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
66 for( j = 0; j < p_cat->i_infos ; j++ )
68 if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
70 char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
71 vlc_mutex_unlock( &p_i->lock );
76 vlc_mutex_unlock( &p_i->lock );
80 static void input_ItemDestroy ( gc_object_t *p_this )
82 vlc_object_t *p_obj = (vlc_object_t *)p_this->p_destructor_arg;
83 input_item_t *p_input = (input_item_t *) p_this;
86 playlist_t *p_playlist = pl_Yield( p_obj );
87 input_ItemClean( p_input );
89 ARRAY_BSEARCH( p_playlist->input_items,->i_id, int, p_input->i_id, i);
91 ARRAY_REMOVE( p_playlist->input_items, i);
97 void input_ItemAddOption( input_item_t *p_input,
98 const char *psz_option )
100 if( !psz_option ) return;
101 vlc_mutex_lock( &p_input->lock );
102 INSERT_ELEM( p_input->ppsz_options, p_input->i_options,
103 p_input->i_options, strdup( psz_option ) );
104 vlc_mutex_unlock( &p_input->lock );
107 void input_ItemAddOptionNoDup( input_item_t *p_input,
108 const char *psz_option )
111 if( !psz_option ) return ;
112 vlc_mutex_lock( &p_input->lock );
113 for( i = 0 ; i< p_input->i_options; i++ )
115 if( !strcmp( p_input->ppsz_options[i], psz_option ) )
117 vlc_mutex_unlock(& p_input->lock );
121 TAB_APPEND( p_input->i_options, p_input->ppsz_options, strdup( psz_option)); vlc_mutex_unlock( &p_input->lock );
125 int input_ItemAddInfo( input_item_t *p_i,
127 const char *psz_name,
128 const char *psz_format, ... )
132 info_t *p_info = NULL;
133 info_category_t *p_cat = NULL ;
135 vlc_mutex_lock( &p_i->lock );
137 for( i = 0 ; i < p_i->i_categories ; i ++ )
139 if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) )
141 p_cat = p_i->pp_categories[i];
147 if( !(p_cat = (info_category_t *)malloc( sizeof(info_category_t) )) )
149 vlc_mutex_unlock( &p_i->lock );
152 p_cat->psz_name = strdup( psz_cat );
155 INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories,
159 for( i = 0; i< p_cat->i_infos; i++ )
161 if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
163 p_info = p_cat->pp_infos[i];
170 if( ( p_info = (info_t *)malloc( sizeof( info_t ) ) ) == NULL )
172 vlc_mutex_unlock( &p_i->lock );
175 INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
176 p_info->psz_name = strdup( psz_name );
180 if( p_info->psz_value ) free( p_info->psz_value );
183 va_start( args, psz_format );
184 vasprintf( &p_info->psz_value, psz_format, args);
187 vlc_mutex_unlock( &p_i->lock );
192 input_item_t *input_ItemGetById( playlist_t *p_playlist, int i_id )
195 ARRAY_BSEARCH( p_playlist->input_items, ->i_id, int, i_id, i);
197 return ARRAY_VAL( p_playlist->input_items, i);
201 input_item_t *__input_ItemNewExt( vlc_object_t *p_obj, const char *psz_uri,
202 const char *psz_name, int i_options,
203 const char *const *ppsz_options, int i_duration )
205 return input_ItemNewWithType( p_obj, psz_uri, psz_name,
206 i_options, ppsz_options,
207 i_duration, ITEM_TYPE_UNKNOWN );
211 input_item_t *input_ItemNewWithType( vlc_object_t *p_obj, const char *psz_uri,
212 const char *psz_name, int i_options,
213 const char *const *ppsz_options, int i_duration,
216 playlist_t *p_playlist = pl_Yield( p_obj );
217 DECMALLOC_NULL( p_input, input_item_t );
219 input_ItemInit( p_obj, p_input );
220 vlc_gc_init( p_input, input_ItemDestroy, (void *)p_obj );
223 p_input->i_id = ++p_playlist->i_last_input_id;
224 ARRAY_APPEND( p_playlist->input_items, p_input );
228 p_input->b_fixed_name = VLC_FALSE;
231 p_input->psz_uri = strdup( psz_uri );
233 p_input->psz_uri = NULL;
235 p_input->i_type = i_type;
236 p_input->b_prefers_tree = VLC_FALSE;
238 if( p_input->i_type == ITEM_TYPE_UNKNOWN )
239 GuessType( p_input );
241 if( psz_name != NULL )
242 p_input->psz_name = strdup( psz_name );
243 else if( p_input->i_type == ITEM_TYPE_AFILE
244 || p_input->i_type == ITEM_TYPE_VFILE )
246 const char *psz_filename = strrchr( p_input->psz_uri, DIR_SEP_CHAR );
247 if( psz_filename && *psz_filename == DIR_SEP_CHAR )
249 p_input->psz_name = strdup( psz_filename && *psz_filename
250 ? psz_filename : p_input->psz_uri );
253 p_input->psz_name = strdup( p_input->psz_uri );
255 p_input->i_duration = i_duration;
256 p_input->ppsz_options = NULL;
258 for( p_input->i_options = 0; p_input->i_options < i_options;
259 p_input->i_options++ )
261 if( !p_input->i_options )
263 p_input->ppsz_options = malloc( i_options * sizeof(char *) );
264 if( !p_input->ppsz_options ) break;
266 p_input->ppsz_options[p_input->i_options] =
267 strdup( ppsz_options[p_input->i_options] );
272 /* Guess the type of the item using the beginning of the mrl */
273 static void GuessType( input_item_t *p_item)
276 static struct { const char *psz_search; int i_type; } types_array[] =
278 { "http", ITEM_TYPE_NET },
279 { "dvd", ITEM_TYPE_DISC },
280 { "cdda", ITEM_TYPE_CDDA },
281 { "mms", ITEM_TYPE_NET },
282 { "rtsp", ITEM_TYPE_NET },
283 { "udp", ITEM_TYPE_NET },
284 { "rtp", ITEM_TYPE_NET },
285 { "vcd", ITEM_TYPE_DISC },
286 { "v4l", ITEM_TYPE_CARD },
287 { "dshow", ITEM_TYPE_CARD },
288 { "pvr", ITEM_TYPE_CARD },
289 { "dvb", ITEM_TYPE_CARD },
290 { "qpsk", ITEM_TYPE_CARD },
291 { "sdp", ITEM_TYPE_NET },
296 static struct { char *psz_search; int i_type; } exts_array[] =
298 { "mp3", ITEM_TYPE_AFILE },
303 for( i = 0; types_array[i].psz_search != NULL; i++ )
305 if( !strncmp( p_item->psz_uri, types_array[i].psz_search,
306 strlen( types_array[i].psz_search ) ) )
308 p_item->i_type = types_array[i].i_type;
312 p_item->i_type = ITEM_TYPE_VFILE;