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 *****************************************************************************/
30 #include "vlc_playlist.h"
31 #include "vlc_interface.h"
33 #include "input_internal.h"
35 static void GuessType( input_item_t
*p_item
);
37 void input_item_SetMeta( input_item_t
*p_i
, vlc_meta_type_t meta_type
, const char *psz_val
)
41 vlc_mutex_lock( &p_i
->lock
);
43 p_i
->p_meta
= vlc_meta_New();
44 vlc_meta_Set( p_i
->p_meta
, meta_type
, psz_val
);
45 vlc_mutex_unlock( &p_i
->lock
);
47 /* Notify interested third parties */
48 event
.type
= vlc_InputItemMetaChanged
;
49 event
.u
.input_item_meta_changed
.meta_type
= meta_type
;
50 vlc_event_send( &p_i
->event_manager
, &event
);
54 * Get the item from an input thread
56 input_item_t
*input_GetItem( input_thread_t
*p_input
)
58 assert( p_input
&& p_input
->p
);
59 return p_input
->p
->input
.p_item
;
63 * Get a info item from a given category in a given input item.
65 * \param p_i The input item to get info from
66 * \param psz_cat String representing the category for the info
67 * \param psz_name String representing the name of the desired info
68 * \return A pointer to the string with the given info if found, or an
69 * empty string otherwise. The caller should free the returned
72 char *input_ItemGetInfo( input_item_t
*p_i
,
74 const char *psz_name
)
78 vlc_mutex_lock( &p_i
->lock
);
80 for( i
= 0 ; i
< p_i
->i_categories
; i
++ )
82 info_category_t
*p_cat
= p_i
->pp_categories
[i
];
84 if( !psz_cat
|| strcmp( p_cat
->psz_name
, psz_cat
) )
87 for( j
= 0; j
< p_cat
->i_infos
; j
++ )
89 if( !strcmp( p_cat
->pp_infos
[j
]->psz_name
, psz_name
) )
91 char *psz_ret
= strdup( p_cat
->pp_infos
[j
]->psz_value
);
92 vlc_mutex_unlock( &p_i
->lock
);
97 vlc_mutex_unlock( &p_i
->lock
);
101 static void input_ItemDestroy ( gc_object_t
*p_this
)
103 vlc_object_t
*p_obj
= (vlc_object_t
*)p_this
->p_destructor_arg
;
104 input_item_t
*p_input
= (input_item_t
*) p_this
;
107 input_ItemClean( p_input
);
109 vlc_mutex_lock( &p_obj
->p_libvlc
->object_lock
);
111 ARRAY_BSEARCH( p_obj
->p_libvlc
->input_items
,->i_id
, int, p_input
->i_id
, i
);
113 ARRAY_REMOVE( p_obj
->p_libvlc
->input_items
, i
);
115 vlc_mutex_unlock( &p_obj
->p_libvlc
->object_lock
);
120 int input_ItemAddOpt( input_item_t
*p_input
, const char *psz_option
,
123 int err
= VLC_SUCCESS
;
125 if( psz_option
== NULL
)
128 vlc_mutex_lock( &p_input
->lock
);
129 if (flags
& VLC_INPUT_OPTION_UNIQUE
)
131 for (int i
= 0 ; i
< p_input
->i_options
; i
++)
132 if( !strcmp( p_input
->ppsz_options
[i
], psz_option
) )
136 uint8_t *flagv
= realloc (p_input
->optflagv
, p_input
->optflagc
+ 1);
142 p_input
->optflagv
= flagv
;
143 flagv
[p_input
->optflagc
++] = flags
;
145 INSERT_ELEM( p_input
->ppsz_options
, p_input
->i_options
,
146 p_input
->i_options
, strdup( psz_option
) );
148 vlc_mutex_unlock( &p_input
->lock
);
152 int input_ItemAddInfo( input_item_t
*p_i
,
154 const char *psz_name
,
155 const char *psz_format
, ... )
159 info_t
*p_info
= NULL
;
160 info_category_t
*p_cat
= NULL
;
162 vlc_mutex_lock( &p_i
->lock
);
164 for( i
= 0 ; i
< p_i
->i_categories
; i
++ )
166 if( !strcmp( p_i
->pp_categories
[i
]->psz_name
, psz_cat
) )
168 p_cat
= p_i
->pp_categories
[i
];
174 if( !(p_cat
= (info_category_t
*)malloc( sizeof(info_category_t
) )) )
176 vlc_mutex_unlock( &p_i
->lock
);
179 p_cat
->psz_name
= strdup( psz_cat
);
182 INSERT_ELEM( p_i
->pp_categories
, p_i
->i_categories
, p_i
->i_categories
,
186 for( i
= 0; i
< p_cat
->i_infos
; i
++ )
188 if( !strcmp( p_cat
->pp_infos
[i
]->psz_name
, psz_name
) )
190 p_info
= p_cat
->pp_infos
[i
];
197 if( ( p_info
= (info_t
*)malloc( sizeof( info_t
) ) ) == NULL
)
199 vlc_mutex_unlock( &p_i
->lock
);
202 INSERT_ELEM( p_cat
->pp_infos
, p_cat
->i_infos
, p_cat
->i_infos
, p_info
);
203 p_info
->psz_name
= strdup( psz_name
);
207 free( p_info
->psz_value
);
210 va_start( args
, psz_format
);
211 if( vasprintf( &p_info
->psz_value
, psz_format
, args
) )
212 p_info
->psz_value
= NULL
;
215 vlc_mutex_unlock( &p_i
->lock
);
217 return p_info
->psz_value
? VLC_SUCCESS
: VLC_ENOMEM
;
220 input_item_t
*__input_ItemGetById( vlc_object_t
*p_obj
, int i_id
)
222 input_item_t
* p_ret
= NULL
;
225 vlc_mutex_lock( &p_obj
->p_libvlc
->object_lock
);
227 ARRAY_BSEARCH( p_obj
->p_libvlc
->input_items
, ->i_id
, int, i_id
, i
);
229 p_ret
= ARRAY_VAL( p_obj
->p_libvlc
->input_items
, i
);
231 vlc_mutex_unlock( &p_obj
->p_libvlc
->object_lock
);
236 input_item_t
*__input_ItemNewExt( vlc_object_t
*p_obj
, const char *psz_uri
,
237 const char *psz_name
,
239 const char *const *ppsz_options
,
242 return input_ItemNewWithType( p_obj
, psz_uri
, psz_name
,
243 i_options
, ppsz_options
,
244 i_duration
, ITEM_TYPE_UNKNOWN
);
248 input_item_t
*input_ItemNewWithType( vlc_object_t
*p_obj
, const char *psz_uri
,
249 const char *psz_name
,
251 const char *const *ppsz_options
,
255 DECMALLOC_NULL( p_input
, input_item_t
);
257 input_ItemInit( p_obj
, p_input
);
258 vlc_gc_init( p_input
, input_ItemDestroy
, (void *)p_obj
);
260 vlc_mutex_lock( &p_obj
->p_libvlc
->object_lock
);
261 p_input
->i_id
= ++p_obj
->p_libvlc
->i_last_input_id
;
262 ARRAY_APPEND( p_obj
->p_libvlc
->input_items
, p_input
);
263 vlc_mutex_unlock( &p_obj
->p_libvlc
->object_lock
);
265 p_input
->b_fixed_name
= VLC_FALSE
;
268 p_input
->psz_uri
= strdup( psz_uri
);
270 p_input
->psz_uri
= NULL
;
272 p_input
->i_type
= i_type
;
273 p_input
->b_prefers_tree
= VLC_FALSE
;
275 if( p_input
->i_type
== ITEM_TYPE_UNKNOWN
)
276 GuessType( p_input
);
278 if( psz_name
!= NULL
)
279 p_input
->psz_name
= strdup( psz_name
);
280 else if( p_input
->i_type
== ITEM_TYPE_FILE
&& p_input
->psz_uri
)
282 const char *psz_filename
= strrchr( p_input
->psz_uri
, DIR_SEP_CHAR
);
283 if( psz_filename
&& *psz_filename
== DIR_SEP_CHAR
)
285 p_input
->psz_name
= strdup( psz_filename
&& *psz_filename
286 ? psz_filename
: p_input
->psz_uri
);
289 p_input
->psz_name
= p_input
->psz_uri
? strdup( p_input
->psz_uri
) : NULL
;
291 p_input
->i_duration
= i_duration
;
293 for( int i
= 0; i
< i_options
; i
++ )
294 input_ItemAddOption( p_input
, ppsz_options
[i
] );
298 /* Guess the type of the item using the beginning of the mrl */
299 static void GuessType( input_item_t
*p_item
)
302 static struct { const char *psz_search
; int i_type
; } types_array
[] =
304 { "http", ITEM_TYPE_NET
},
305 { "dvd", ITEM_TYPE_DISC
},
306 { "cdda", ITEM_TYPE_CDDA
},
307 { "mms", ITEM_TYPE_NET
},
308 { "rtsp", ITEM_TYPE_NET
},
309 { "udp", ITEM_TYPE_NET
},
310 { "rtp", ITEM_TYPE_NET
},
311 { "vcd", ITEM_TYPE_DISC
},
312 { "v4l", ITEM_TYPE_CARD
},
313 { "dshow", ITEM_TYPE_CARD
},
314 { "pvr", ITEM_TYPE_CARD
},
315 { "dvb", ITEM_TYPE_CARD
},
316 { "qpsk", ITEM_TYPE_CARD
},
317 { "sdp", ITEM_TYPE_NET
},
321 if( !p_item
->psz_uri
)
323 p_item
->i_type
= ITEM_TYPE_FILE
;
327 for( i
= 0; types_array
[i
].psz_search
!= NULL
; i
++ )
329 if( !strncmp( p_item
->psz_uri
, types_array
[i
].psz_search
,
330 strlen( types_array
[i
].psz_search
) ) )
332 p_item
->i_type
= types_array
[i
].i_type
;
336 p_item
->i_type
= ITEM_TYPE_FILE
;