Line | Count | Source (jump to first uncovered line) |
1 | | /***************************************************************************** |
2 | | * core.c: Core libvlc new API functions : initialization |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2005 VLC authors and VideoLAN |
5 | | * |
6 | | * Authors: Clément Stenac <zorglub@videolan.org> |
7 | | * |
8 | | * This program is free software; you can redistribute it and/or modify it |
9 | | * under the terms of the GNU Lesser General Public License as published by |
10 | | * the Free Software Foundation; either version 2.1 of the License, or |
11 | | * (at your option) any later version. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program; if not, write to the Free Software Foundation, |
20 | | * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. |
21 | | *****************************************************************************/ |
22 | | |
23 | | #ifdef HAVE_CONFIG_H |
24 | | # include "config.h" |
25 | | #endif |
26 | | |
27 | | #include "libvlc_internal.h" |
28 | | #include <vlc_modules.h> |
29 | | #include <vlc/vlc.h> |
30 | | |
31 | | #include <vlc_preparser.h> |
32 | | #include <vlc_interface.h> |
33 | | |
34 | | #include <stdarg.h> |
35 | | #include <limits.h> |
36 | | #include <assert.h> |
37 | | |
38 | | static_assert(LIBVLC_VERSION_MAJOR == PACKAGE_VERSION_MAJOR, "Major VLC version mismatch"); |
39 | | static_assert(LIBVLC_VERSION_MINOR == PACKAGE_VERSION_MINOR, "Minor VLC version mismatch"); |
40 | | static_assert(LIBVLC_VERSION_REVISION == PACKAGE_VERSION_REVISION, "VLC Revision version mismatch"); |
41 | | static_assert(LIBVLC_VERSION_EXTRA == PACKAGE_VERSION_EXTRA, "VLC Extra version mismatch"); |
42 | | static_assert(LIBVLC_ABI_VERSION_MAJOR == LIBVLC_ABI_MAJOR, "Major LibVLC version mismatch"); |
43 | | static_assert(LIBVLC_ABI_VERSION_MINOR == LIBVLC_ABI_MINOR, "Minor LibVLC version mismatch"); |
44 | | static_assert(LIBVLC_ABI_VERSION_MICRO == LIBVLC_ABI_MICRO, "Micro LibVLC version mismatch"); |
45 | | |
46 | | int libvlc_abi_version(void) |
47 | 0 | { |
48 | 0 | return LIBVLC_ABI_VERSION_INT; |
49 | 0 | } |
50 | | |
51 | | libvlc_instance_t * libvlc_new( int argc, const char *const *argv ) |
52 | 52 | { |
53 | 52 | libvlc_threads_init (); |
54 | | |
55 | 52 | libvlc_instance_t *p_new = malloc (sizeof (*p_new)); |
56 | 52 | if (unlikely(p_new == NULL)) |
57 | 0 | return NULL; |
58 | | |
59 | 52 | const char *my_argv[argc + 2]; |
60 | 52 | my_argv[0] = "libvlc"; /* dummy arg0, skipped by getopt() et al */ |
61 | 104 | for( int i = 0; i < argc; i++ ) |
62 | 52 | my_argv[i + 1] = argv[i]; |
63 | 52 | my_argv[argc + 1] = NULL; /* C calling conventions require a NULL */ |
64 | | |
65 | 52 | libvlc_int_t *p_libvlc_int = libvlc_InternalCreate(); |
66 | 52 | if (unlikely (p_libvlc_int == NULL)) |
67 | 0 | goto error; |
68 | | |
69 | 52 | const int ret = libvlc_InternalInit( p_libvlc_int, argc + 1, my_argv ); |
70 | 52 | if (ret != VLC_SUCCESS) |
71 | 0 | { |
72 | 0 | libvlc_InternalDestroy( p_libvlc_int ); |
73 | 0 | const char *error = (ret == VLC_EGENERIC) ? _( "Generic VLC error" ) |
74 | 0 | : vlc_strerror_c( -ret ); |
75 | 0 | libvlc_printerr( "%s", error ); |
76 | 0 | goto error; |
77 | 0 | } |
78 | | |
79 | 52 | p_new->p_libvlc_int = p_libvlc_int; |
80 | 52 | vlc_atomic_rc_init( &p_new->ref_count ); |
81 | 52 | p_new->p_callback_list = NULL; |
82 | | |
83 | 52 | vlc_mutex_init(&p_new->lazy_init_lock); |
84 | 52 | p_new->parser = NULL; |
85 | 52 | p_new->thumbnailer = NULL; |
86 | | |
87 | 52 | return p_new; |
88 | | |
89 | 0 | error: |
90 | 0 | free (p_new); |
91 | 0 | libvlc_threads_deinit (); |
92 | 0 | return NULL; |
93 | 52 | } |
94 | | |
95 | | libvlc_instance_t *libvlc_retain( libvlc_instance_t *p_instance ) |
96 | 0 | { |
97 | 0 | assert( p_instance != NULL ); |
98 | | |
99 | 0 | vlc_atomic_rc_inc( &p_instance->ref_count ); |
100 | 0 | return p_instance; |
101 | 0 | } |
102 | | |
103 | | void libvlc_release( libvlc_instance_t *p_instance ) |
104 | 0 | { |
105 | 0 | if(vlc_atomic_rc_dec( &p_instance->ref_count )) |
106 | 0 | { |
107 | 0 | libvlc_Quit( p_instance->p_libvlc_int ); |
108 | |
|
109 | 0 | if (p_instance->parser != NULL) |
110 | 0 | vlc_preparser_Delete(p_instance->parser); |
111 | 0 | if (p_instance->thumbnailer != NULL) |
112 | 0 | vlc_preparser_Delete(p_instance->thumbnailer); |
113 | |
|
114 | 0 | libvlc_InternalCleanup( p_instance->p_libvlc_int ); |
115 | 0 | libvlc_InternalDestroy( p_instance->p_libvlc_int ); |
116 | 0 | free( p_instance ); |
117 | 0 | libvlc_threads_deinit (); |
118 | 0 | } |
119 | 0 | } |
120 | | |
121 | | void libvlc_set_user_agent (libvlc_instance_t *p_i, |
122 | | const char *name, const char *http) |
123 | 0 | { |
124 | 0 | libvlc_int_t *p_libvlc = p_i->p_libvlc_int; |
125 | 0 | char *str; |
126 | |
|
127 | 0 | var_SetString (p_libvlc, "user-agent", name); |
128 | 0 | if ((http != NULL) |
129 | 0 | && (asprintf (&str, "%s LibVLC/"PACKAGE_VERSION, http) != -1)) |
130 | 0 | { |
131 | 0 | var_SetString (p_libvlc, "http-user-agent", str); |
132 | 0 | free (str); |
133 | 0 | } |
134 | 0 | } |
135 | | |
136 | | void libvlc_set_app_id(libvlc_instance_t *p_i, const char *id, |
137 | | const char *version, const char *icon) |
138 | 0 | { |
139 | 0 | libvlc_int_t *p_libvlc = p_i->p_libvlc_int; |
140 | |
|
141 | 0 | var_SetString(p_libvlc, "app-id", id ? id : ""); |
142 | 0 | var_SetString(p_libvlc, "app-version", version ? version : ""); |
143 | 0 | var_SetString(p_libvlc, "app-icon-name", icon ? icon : ""); |
144 | 0 | } |
145 | | |
146 | | const char * libvlc_get_version(void) |
147 | 0 | { |
148 | 0 | return VERSION_MESSAGE; |
149 | 0 | } |
150 | | |
151 | | const char * libvlc_get_compiler(void) |
152 | 0 | { |
153 | 0 | return VLC_Compiler(); |
154 | 0 | } |
155 | | |
156 | | const char * libvlc_get_changeset(void) |
157 | 0 | { |
158 | 0 | extern const char psz_vlc_changeset[]; |
159 | 0 | return psz_vlc_changeset; |
160 | 0 | } |
161 | | |
162 | | void libvlc_free( void *ptr ) |
163 | 0 | { |
164 | 0 | free( ptr ); |
165 | 0 | } |
166 | | |
167 | | static libvlc_module_description_t *module_description_list_get( |
168 | | libvlc_instance_t *p_instance, const char *capability ) |
169 | 0 | { |
170 | 0 | libvlc_module_description_t *p_list = NULL, |
171 | 0 | *p_actual = NULL, |
172 | 0 | *p_previous = NULL; |
173 | 0 | size_t count; |
174 | 0 | module_t **module_list = module_list_get( &count ); |
175 | |
|
176 | 0 | for (size_t i = 0; i < count; i++) |
177 | 0 | { |
178 | 0 | module_t *p_module = module_list[i]; |
179 | |
|
180 | 0 | if ( !module_provides( p_module, capability ) ) |
181 | 0 | continue; |
182 | | |
183 | 0 | p_actual = ( libvlc_module_description_t * ) malloc( sizeof( libvlc_module_description_t ) ); |
184 | 0 | if ( p_actual == NULL ) |
185 | 0 | { |
186 | 0 | libvlc_printerr( "Not enough memory" ); |
187 | 0 | libvlc_module_description_list_release( p_list ); |
188 | 0 | module_list_free( module_list ); |
189 | 0 | return NULL; |
190 | 0 | } |
191 | | |
192 | 0 | if ( p_list == NULL ) |
193 | 0 | p_list = p_actual; |
194 | |
|
195 | 0 | const char* name = module_get_object( p_module ); |
196 | 0 | const char* shortname = module_GetShortName( p_module ); |
197 | 0 | const char* longname = module_GetLongName( p_module ); |
198 | 0 | const char* help = module_get_help( p_module ); |
199 | 0 | const char* help_html = module_get_help_html( p_module ); |
200 | 0 | p_actual->psz_name = name ? strdup( name ) : NULL; |
201 | 0 | p_actual->psz_shortname = shortname ? strdup( shortname ) : NULL; |
202 | 0 | p_actual->psz_longname = longname ? strdup( longname ) : NULL; |
203 | 0 | p_actual->psz_help = help ? strdup( help ) : NULL; |
204 | 0 | p_actual->psz_help_html = help_html ? strdup( help_html ) : NULL; |
205 | |
|
206 | 0 | p_actual->p_next = NULL; |
207 | 0 | if ( p_previous ) |
208 | 0 | p_previous->p_next = p_actual; |
209 | 0 | p_previous = p_actual; |
210 | 0 | } |
211 | | |
212 | 0 | module_list_free( module_list ); |
213 | 0 | VLC_UNUSED( p_instance ); |
214 | 0 | return p_list; |
215 | 0 | } |
216 | | |
217 | | void libvlc_module_description_list_release( libvlc_module_description_t *p_list ) |
218 | 0 | { |
219 | 0 | libvlc_module_description_t *p_actual, *p_before; |
220 | 0 | p_actual = p_list; |
221 | |
|
222 | 0 | while ( p_actual ) |
223 | 0 | { |
224 | 0 | free( p_actual->psz_name ); |
225 | 0 | free( p_actual->psz_shortname ); |
226 | 0 | free( p_actual->psz_longname ); |
227 | 0 | free( p_actual->psz_help ); |
228 | 0 | free( p_actual->psz_help_html ); |
229 | 0 | p_before = p_actual; |
230 | 0 | p_actual = p_before->p_next; |
231 | 0 | free( p_before ); |
232 | 0 | } |
233 | 0 | } |
234 | | |
235 | | libvlc_module_description_t *libvlc_audio_filter_list_get( libvlc_instance_t *p_instance ) |
236 | 0 | { |
237 | 0 | return module_description_list_get( p_instance, "audio filter" ); |
238 | 0 | } |
239 | | |
240 | | libvlc_module_description_t *libvlc_video_filter_list_get( libvlc_instance_t *p_instance ) |
241 | 0 | { |
242 | 0 | return module_description_list_get( p_instance, "video filter" ); |
243 | 0 | } |
244 | | |
245 | | int64_t libvlc_clock(void) |
246 | 0 | { |
247 | 0 | return US_FROM_VLC_TICK(vlc_tick_now()); |
248 | 0 | } |
249 | | |
250 | | vlc_preparser_t *libvlc_get_preparser(libvlc_instance_t *instance) |
251 | 0 | { |
252 | 0 | vlc_mutex_lock(&instance->lazy_init_lock); |
253 | 0 | vlc_preparser_t *parser = instance->parser; |
254 | |
|
255 | 0 | if (parser == NULL) |
256 | 0 | { |
257 | | /* Temporary: the 2 following variables will be configured directly |
258 | | * with future libvlc_parser API */ |
259 | 0 | int max_threads = var_InheritInteger(instance->p_libvlc_int, "preparse-threads"); |
260 | 0 | if (max_threads < 1) |
261 | 0 | max_threads = 1; |
262 | |
|
263 | 0 | vlc_tick_t default_timeout = |
264 | 0 | VLC_TICK_FROM_MS(var_InheritInteger(instance->p_libvlc_int, "preparse-timeout")); |
265 | 0 | if (default_timeout < 0) |
266 | 0 | default_timeout = 0; |
267 | |
|
268 | 0 | const struct vlc_preparser_cfg cfg = { |
269 | 0 | .types = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_TYPE_FETCHMETA_ALL, |
270 | 0 | .max_parser_threads = max_threads, |
271 | 0 | .timeout = default_timeout, |
272 | 0 | }; |
273 | |
|
274 | 0 | parser = instance->parser = |
275 | 0 | vlc_preparser_New(VLC_OBJECT(instance->p_libvlc_int), &cfg); |
276 | 0 | } |
277 | 0 | vlc_mutex_unlock(&instance->lazy_init_lock); |
278 | |
|
279 | 0 | return parser; |
280 | 0 | } |
281 | | |
282 | | vlc_preparser_t *libvlc_get_thumbnailer(libvlc_instance_t *instance) |
283 | 0 | { |
284 | 0 | vlc_mutex_lock(&instance->lazy_init_lock); |
285 | 0 | vlc_preparser_t *thumb = instance->thumbnailer; |
286 | |
|
287 | 0 | if (thumb == NULL) |
288 | 0 | { |
289 | 0 | const struct vlc_preparser_cfg cfg = { |
290 | 0 | .types = VLC_PREPARSER_TYPE_THUMBNAIL, |
291 | 0 | .timeout = 0, |
292 | 0 | }; |
293 | |
|
294 | 0 | thumb = instance->thumbnailer = |
295 | 0 | vlc_preparser_New(VLC_OBJECT(instance->p_libvlc_int), &cfg); |
296 | 0 | } |
297 | 0 | vlc_mutex_unlock(&instance->lazy_init_lock); |
298 | |
|
299 | 0 | return thumb; |
300 | 0 | } |
301 | | |
302 | | const char vlc_module_name[] = "libvlc"; |