/** * Stops and destroys all interfaces, then the playlist. * @warning FIXME * @param libvlc the LibVLC instance */ void intf_DestroyAll(libvlc_int_t *libvlc) { playlist_t *playlist; vlc_mutex_lock(&lock); playlist = libvlc_priv(libvlc)->playlist; if (playlist != NULL) { intf_thread_t *intf, **pp = &(pl_priv(playlist)->interface); while ((intf = *pp) != NULL) { *pp = intf->p_next; vlc_mutex_unlock(&lock); module_unneed(intf, intf->p_module); config_ChainDestroy(intf->p_cfg); var_DelCallback(intf, "intf-add", AddIntfCallback, playlist); vlc_object_release(intf); vlc_mutex_lock(&lock); } libvlc_priv(libvlc)->playlist = NULL; } vlc_mutex_unlock(&lock); if (playlist != NULL) playlist_Destroy(playlist); }
/** * Stops and destroys all interfaces * @param p_libvlc the LibVLC instance */ void intf_DestroyAll( libvlc_int_t *p_libvlc ) { intf_thread_t *p_first; vlc_mutex_lock( &lock ); p_first = libvlc_priv( p_libvlc )->p_intf; #ifndef NDEBUG libvlc_priv( p_libvlc )->p_intf = NULL; #endif vlc_mutex_unlock( &lock ); /* Tell the interfaces to die */ for( intf_thread_t *p_intf = p_first; p_intf; p_intf = p_intf->p_next ) vlc_object_kill( p_intf ); /* Cleanup the interfaces */ for( intf_thread_t *p_intf = p_first; p_intf != NULL; ) { intf_thread_t *p_next = p_intf->p_next; if( p_intf->pf_run ) { vlc_cancel( p_intf->thread ); vlc_join( p_intf->thread, NULL ); } module_unneed( p_intf, p_intf->p_module ); config_ChainDestroy( p_intf->p_cfg ); vlc_object_release( p_intf ); p_intf = p_next; } }
/** * Registers a new session with the announce handler, using a pregenerated SDP * * \param obj a VLC object * \param psz_sdp the SDP to register * \param psz_dst session address (needed for SAP address auto detection) * \param p_method an announce method descriptor * \return the new session descriptor structure */ session_descriptor_t * sout_AnnounceRegisterSDP( vlc_object_t *obj, const char *psz_sdp, const char *psz_dst, announce_method_t *p_method ) { assert (p_method == &sap_method); (void) p_method; session_descriptor_t *p_session = calloc( 1, sizeof (*p_session) ); if( !p_session ) return NULL; p_session->psz_sdp = strdup( psz_sdp ); /* GRUIK. We should not convert back-and-forth from string to numbers */ struct addrinfo *res; if (vlc_getaddrinfo (obj, psz_dst, 0, NULL, &res) == 0) { if (res->ai_addrlen <= sizeof (p_session->addr)) memcpy (&p_session->addr, res->ai_addr, p_session->addrlen = res->ai_addrlen); vlc_freeaddrinfo (res); } vlc_mutex_lock (&sap_mutex); sap_handler_t *p_sap = libvlc_priv (obj->p_libvlc)->p_sap; if (p_sap == NULL) { p_sap = SAP_Create (VLC_OBJECT (obj->p_libvlc)); libvlc_priv (obj->p_libvlc)->p_sap = p_sap; vlc_object_set_destructor ((vlc_object_t *)p_sap, sap_destroy); } else vlc_object_hold ((vlc_object_t *)p_sap); vlc_mutex_unlock (&sap_mutex); if (p_sap == NULL) goto error; msg_Dbg (obj, "adding SAP session"); if (SAP_Add (p_sap, p_session)) { vlc_mutex_lock (&sap_mutex); vlc_object_release ((vlc_object_t *)p_sap); vlc_mutex_unlock (&sap_mutex); goto error; } return p_session; error: free (p_session->psz_sdp); free (p_session); return NULL; }
/** * Cleanup a libvlc instance. The instance is not completely deallocated * \param p_libvlc the instance to clean */ void libvlc_InternalCleanup( libvlc_int_t *p_libvlc ) { libvlc_priv_t *priv = libvlc_priv (p_libvlc); /* Ask the interfaces to stop and destroy them */ msg_Dbg( p_libvlc, "removing all interfaces" ); libvlc_Quit( p_libvlc ); intf_DestroyAll( p_libvlc ); #ifdef ENABLE_VLM /* Destroy VLM if created in libvlc_InternalInit */ if( priv->p_vlm ) { vlm_Delete( priv->p_vlm ); } #endif /* Free playlist now, all threads are gone */ playlist_t *p_playlist = libvlc_priv (p_libvlc)->p_playlist; if( p_playlist != NULL ) playlist_Destroy( p_playlist ); #if !defined( _WIN32 ) && !defined( __OS2__ ) char *pidfile = var_InheritString( p_libvlc, "pidfile" ); if( pidfile != NULL ) { msg_Dbg( p_libvlc, "removing PID file %s", pidfile ); if( unlink( pidfile ) ) msg_Warn( p_libvlc, "cannot remove PID file %s: %s", pidfile, vlc_strerror_c(errno) ); free( pidfile ); } #endif if (priv->parser != NULL) playlist_preparser_Delete(priv->parser); vlc_DeinitActions( p_libvlc, priv->actions ); /* Save the configuration */ if( !var_InheritBool( p_libvlc, "ignore-config" ) ) config_AutoSaveConfigFile( VLC_OBJECT(p_libvlc) ); /* Free module bank. It is refcounted, so we call this each time */ module_EndBank (true); vlc_LogDeinit (p_libvlc); #if defined(_WIN32) || defined(__OS2__) system_End( ); #endif }
/** * Creates the playlist if necessary, and return a pointer to it. * @note The playlist is not reference-counted. So the pointer is only valid * until intf_DestroyAll() destroys interfaces. */ static playlist_t *intf_GetPlaylist(libvlc_int_t *libvlc) { playlist_t *playlist; vlc_mutex_lock(&lock); playlist = libvlc_priv(libvlc)->playlist; if (playlist == NULL) { playlist = playlist_Create(VLC_OBJECT(libvlc)); libvlc_priv(libvlc)->playlist = playlist; } vlc_mutex_unlock(&lock); return playlist; }
/** * Sets the message logging callback. * \param cb message callback, or NULL to clear * \param data data pointer for the message callback */ void vlc_LogSet(libvlc_int_t *vlc, vlc_log_cb cb, void *opaque) { vlc_logger_t *logger = libvlc_priv(vlc)->logger; if (unlikely(logger == NULL)) return; module_t *module; void *sys; if (cb == NULL) cb = vlc_vaLogDiscard; vlc_rwlock_wrlock(&logger->lock); sys = logger->sys; module = logger->module; logger->log = cb; logger->sys = opaque; logger->module = NULL; vlc_rwlock_unlock(&logger->lock); if (module != NULL) vlc_module_unload(module, vlc_logger_unload, sys); /* Announce who we are */ msg_Dbg (vlc, "VLC media player - %s", VERSION_MESSAGE); msg_Dbg (vlc, "%s", COPYRIGHT_MESSAGE); msg_Dbg (vlc, "revision %s", psz_vlc_changeset); msg_Dbg (vlc, "configured with %s", CONFIGURE_LINE); }
/** * Flush all message queues */ void msg_Flush (libvlc_int_t *p_libvlc) { libvlc_priv_t *priv = libvlc_priv (p_libvlc); vlc_mutex_lock( &QUEUE.lock ); FlushMsg( &QUEUE ); vlc_mutex_unlock( &QUEUE.lock ); }
void libvlc_InternalDialogClean(libvlc_int_t *p_libvlc) { assert(p_libvlc != NULL); vlc_dialog_provider *p_provider = libvlc_priv(p_libvlc)->p_dialog_provider; if (p_provider == NULL) return; vlc_mutex_lock(&p_provider->lock); dialog_clear_all_locked(p_provider); vlc_mutex_unlock(&p_provider->lock); vlc_mutex_destroy(&p_provider->lock); free(p_provider); libvlc_priv(p_libvlc)->p_dialog_provider = NULL; }
int libvlc_media_save_meta( libvlc_media_t *p_md ) { assert( p_md ); vlc_object_t *p_obj = VLC_OBJECT(libvlc_priv( p_md->p_libvlc_instance->p_libvlc_int)->p_playlist); return input_item_WriteMeta( p_obj, p_md->p_input_item ) == VLC_SUCCESS; }
char *libvlc_media_get_meta( libvlc_media_t *p_md, libvlc_meta_t e_meta ) { char * psz_meta; assert( p_md ); /* XXX: locking */ preparse_if_needed( p_md ); psz_meta = input_item_GetMeta( p_md->p_input_item, libvlc_to_vlc_meta[e_meta] ); if( e_meta == libvlc_meta_ArtworkURL && !psz_meta && !p_md->has_asked_art ) { p_md->has_asked_art = true; playlist_AskForArtEnqueue( libvlc_priv(p_md->p_libvlc_instance->p_libvlc_int)->p_playlist, p_md->p_input_item ); } /* Should be integrated in core */ if( !psz_meta && e_meta == libvlc_meta_Title && p_md->p_input_item->psz_name ) { free( psz_meta ); return strdup( p_md->p_input_item->psz_name ); } return psz_meta; }
/** * Initializes the messages logging subsystem and drain the early messages to * the configured log. * * \return 0 on success, -1 on error. */ int vlc_LogInit(libvlc_int_t *vlc) { vlc_logger_t *logger = libvlc_priv(vlc)->logger; if (unlikely(logger == NULL)) return -1; vlc_log_cb cb; void *sys, *early_sys = NULL; /* TODO: module configuration item */ module_t *module = vlc_module_load(logger, "logger", NULL, false, vlc_logger_load, logger, &cb, &sys); if (module == NULL) cb = vlc_vaLogDiscard; vlc_rwlock_wrlock(&logger->lock); if (logger->log == vlc_vaLogEarly) early_sys = logger->sys; logger->log = cb; logger->sys = sys; assert(logger->module == NULL); /* Only one call to vlc_LogInit()! */ logger->module = module; vlc_rwlock_unlock(&logger->lock); if (early_sys != NULL) vlc_LogEarlyClose(logger, early_sys); return 0; }
/** **************************************************************************** * Destroy a vlc object (Internal) * * This function destroys an object that has been previously allocated with * vlc_object_create. The object's refcount must be zero and it must not be * attached to other objects in any way. * * This function must be called with cancellation disabled (currently). *****************************************************************************/ static void vlc_object_destroy( vlc_object_t *p_this ) { vlc_object_internals_t *p_priv = vlc_internals( p_this ); /* Send a kill to the object's thread if applicable */ vlc_object_kill( p_this ); /* Call the custom "subclass" destructor */ if( p_priv->pf_destructor ) p_priv->pf_destructor( p_this ); /* Any thread must have been cleaned up at this point. */ assert( !p_priv->b_thread ); /* Destroy the associated variables. */ var_DestroyAll( p_this ); vlc_cond_destroy( &p_priv->var_wait ); vlc_mutex_destroy( &p_priv->var_lock ); free( p_this->psz_header ); free( p_priv->psz_name ); vlc_spin_destroy( &p_priv->ref_spin ); if( p_priv->pipes[1] != -1 && p_priv->pipes[1] != p_priv->pipes[0] ) close( p_priv->pipes[1] ); if( p_priv->pipes[0] != -1 ) close( p_priv->pipes[0] ); if( VLC_OBJECT(p_this->p_libvlc) == p_this ) vlc_mutex_destroy (&(libvlc_priv ((libvlc_int_t *)p_this)->structure_lock)); free( p_priv ); }
/** * Allocate a libvlc instance, initialize global data if needed * It also initializes the threading system */ libvlc_int_t * libvlc_InternalCreate( void ) { libvlc_int_t *p_libvlc; libvlc_priv_t *priv; /* Now that the thread system is initialized, we don't have much, but * at least we have variables */ /* Allocate a libvlc instance object */ p_libvlc = vlc_custom_create( (vlc_object_t *)NULL, sizeof (*priv), "libvlc" ); if( p_libvlc == NULL ) return NULL; priv = libvlc_priv (p_libvlc); priv->p_playlist = NULL; priv->p_ml = NULL; priv->p_dialog_provider = NULL; priv->p_vlm = NULL; priv->i_verbose = 3; /* initial value until config is loaded */ #if defined( HAVE_ISATTY ) && !defined( WIN32 ) priv->b_color = isatty( STDERR_FILENO ); /* 2 is for stderr */ #else priv->b_color = false; #endif /* Initialize mutexes */ vlc_mutex_init( &priv->ml_lock ); vlc_ExitInit( &priv->exit ); return p_libvlc; }
/** * Initialize messages queues * This function initializes all message queues */ void msg_Create (libvlc_int_t *p_libvlc) { libvlc_priv_t *priv = libvlc_priv (p_libvlc); msg_bank_t *bank = libvlc_bank (p_libvlc); vlc_mutex_init (&bank->lock); vlc_cond_init (&bank->wait); vlc_dictionary_init( &priv->msg_enabled_objects, 0 ); priv->msg_all_objects_enabled = true; QUEUE.i_sub = 0; QUEUE.pp_sub = NULL; #ifdef UNDER_CE QUEUE.logfile = CreateFile( L"vlc-log.txt", GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL ); SetFilePointer( QUEUE.logfile, 0, NULL, FILE_END ); #endif vlc_mutex_lock( &msg_stack_lock ); if( banks++ == 0 ) vlc_threadvar_create( &msg_context, cleanup_msg_context ); vlc_mutex_unlock( &msg_stack_lock ); }
/** * Sets the message logging callback. * \param cb message callback, or NULL to reset * \param data data pointer for the message callback */ void vlc_LogSet (libvlc_int_t *vlc, vlc_log_cb cb, void *opaque) { libvlc_priv_t *priv = libvlc_priv (vlc); if (cb == NULL) { #if defined (HAVE_ISATTY) && !defined (_WIN32) if (isatty (STDERR_FILENO) && var_InheritBool (vlc, "color")) cb = PrintColorMsg; else #endif cb = PrintMsg; opaque = (void *)(intptr_t)priv->log.verbose; } vlc_rwlock_wrlock (&priv->log.lock); priv->log.cb = cb; priv->log.opaque = opaque; vlc_rwlock_unlock (&priv->log.lock); /* Announce who we are */ msg_Dbg (vlc, "VLC media player - %s", VERSION_MESSAGE); msg_Dbg (vlc, "%s", COPYRIGHT_MESSAGE); msg_Dbg (vlc, "revision %s", psz_vlc_changeset); msg_Dbg (vlc, "configured with %s", CONFIGURE_LINE); }
unsigned libvlc_get_log_verbosity( const libvlc_instance_t *p_instance, libvlc_exception_t *p_e ) { if( p_instance ) { libvlc_priv_t *p_priv = libvlc_priv( p_instance->p_libvlc_int ); return p_priv->i_verbose; } RAISEZERO("Invalid VLC instance!"); }
/** * Cancels extraction of the meta data for an input item. * * This does nothing if the input item is already processed or if it was not * added with libvlc_MetadataRequest() */ void libvlc_MetadataCancel(libvlc_int_t *libvlc, void *id) { libvlc_priv_t *priv = libvlc_priv(libvlc); if (unlikely(priv->parser == NULL)) return; playlist_preparser_Cancel(priv->parser, id); }
playlist_t *pl_Get (vlc_object_t *obj) { static vlc_mutex_t lock = VLC_STATIC_MUTEX; libvlc_int_t *p_libvlc = obj->p_libvlc; playlist_t *pl; vlc_mutex_lock (&lock); pl = libvlc_priv (p_libvlc)->p_playlist; if (unlikely(pl == NULL)) { pl = playlist_Create (VLC_OBJECT(p_libvlc)); if (unlikely(pl == NULL)) abort(); libvlc_priv (p_libvlc)->p_playlist = pl; } vlc_mutex_unlock (&lock); return pl; }
int libvlc_InternalKeystoreInit(libvlc_int_t *p_libvlc) { assert(p_libvlc != NULL); libvlc_priv_t *p_priv = libvlc_priv(p_libvlc); p_priv->p_memory_keystore = keystore_create(VLC_OBJECT(p_libvlc), "memory"); return p_priv->p_memory_keystore != NULL ? VLC_SUCCESS : VLC_EGENERIC; }
/** * Destroy everything. * This function requests the running threads to finish, waits for their * termination, and destroys their structure. * It stops the thread systems: no instance can run after this has run * \param p_libvlc the instance to destroy */ void libvlc_InternalDestroy( libvlc_int_t *p_libvlc ) { libvlc_priv_t *priv = libvlc_priv( p_libvlc ); vlc_ExitDestroy( &priv->exit ); assert( atomic_load(&(vlc_internals(p_libvlc)->refs)) == 1 ); vlc_object_release( p_libvlc ); }
void __msg_DisableObjectPrinting (vlc_object_t *p_this, char * psz_object) { libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); vlc_mutex_lock( &QUEUE.lock ); if( !strcmp(psz_object, "all") ) priv->msg_all_objects_enabled = false; else vlc_dictionary_insert( &priv->msg_enabled_objects, psz_object, (void *)kObjectPrintingDisabled ); vlc_mutex_unlock( &QUEUE.lock ); }
/** * Requests retrieving/downloading art for an input item. * The retrieval is performed asynchronously. */ int libvlc_ArtRequest(libvlc_int_t *libvlc, input_item_t *item) { libvlc_priv_t *priv = libvlc_priv(libvlc); if (unlikely(priv->parser == NULL)) return VLC_ENOMEM; playlist_preparser_fetcher_Push(priv->parser, item); return VLC_SUCCESS; }
static int media_parse(libvlc_media_t *media) { /* TODO: fetcher and parser independent of playlist */ playlist_t *playlist = libvlc_priv (media->p_libvlc_instance->p_libvlc_int)->p_playlist; /* TODO: Fetch art on need basis. But how not to break compatibility? */ playlist_AskForArtEnqueue(playlist, media->p_input_item ); return playlist_PreparseEnqueue(playlist, media->p_input_item); }
void libvlc_set_log_verbosity( libvlc_instance_t *p_instance, unsigned level, libvlc_exception_t *p_e ) { if( p_instance ) { libvlc_priv_t *p_priv = libvlc_priv( p_instance->p_libvlc_int ); p_priv->i_verbose = level; } else RAISEVOID("Invalid VLC instance!"); }
/** * Requests extraction of the meta data for an input item (a.k.a. preparsing). * The actual extraction is asynchronous. */ int libvlc_MetaRequest(libvlc_int_t *libvlc, input_item_t *item, input_item_meta_request_option_t i_options) { libvlc_priv_t *priv = libvlc_priv(libvlc); if (unlikely(priv->parser == NULL)) return VLC_ENOMEM; playlist_preparser_Push(priv->parser, item, i_options); return VLC_SUCCESS; }
static void vlc_vaLogCallback(libvlc_int_t *vlc, int type, const vlc_log_t *item, const char *format, va_list ap) { vlc_logger_t *logger = libvlc_priv(vlc)->logger; assert(logger != NULL); vlc_rwlock_rdlock(&logger->lock); logger->log(logger->sys, type, item, format, ap); vlc_rwlock_unlock(&logger->lock); }
void libvlc_InternalPlay(libvlc_int_t *libvlc) { playlist_t *pl; vlc_mutex_lock(&lock); pl = libvlc_priv(libvlc)->playlist; vlc_mutex_unlock(&lock); if (pl != NULL && var_GetBool(pl, "playlist-autostart")) playlist_Control(pl, PLAYLIST_PLAY, false); }
static vlc_object_t *dialog_GetProvider (vlc_object_t *obj) { libvlc_priv_t *priv = libvlc_priv (obj->p_libvlc); vlc_object_t *provider; vlc_mutex_lock (&provider_lock); if ((provider = priv->p_dialog_provider) != NULL) vlc_object_hold (provider); vlc_mutex_unlock (&provider_lock); return provider; }
static inline vlc_dialog_provider * get_dialog_provider(vlc_object_t *p_obj, bool b_check_interact) { if (b_check_interact && p_obj->obj.flags & OBJECT_FLAGS_NOINTERACT) return NULL; vlc_dialog_provider *p_provider = libvlc_priv(p_obj->obj.libvlc)->p_dialog_provider; assert(p_provider != NULL); return p_provider; }
void libvlc_playlist_play( libvlc_instance_t *p_instance, int i_id, int i_options, char **ppsz_options ) { playlist_t *pl = libvlc_priv (p_instance->p_libvlc_int)->p_playlist; VLC_UNUSED(i_id); VLC_UNUSED(i_options); VLC_UNUSED(ppsz_options); assert( pl ); if( pl->items.i_size == 0 ) return; playlist_Control( pl, PLAYLIST_PLAY, false ); }