Coverage Report

Created: 2025-08-29 07:30

/src/vlc/lib/core.c
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";