void libvlc_video_set_format_callbacks( libvlc_media_player_t *mp, libvlc_video_format_cb setup, libvlc_video_cleanup_cb cleanup ) { var_SetAddress( mp, "vmem-setup", setup ); var_SetAddress( mp, "vmem-cleanup", cleanup ); }
void libvlc_audio_set_format_callbacks( libvlc_media_player_t *mp, libvlc_audio_setup_cb setup, libvlc_audio_cleanup_cb cleanup ) { var_SetAddress( mp, "amem-setup", setup ); var_SetAddress( mp, "amem-cleanup", cleanup ); input_resource_ResetAout(mp->input.p_resource); }
void libvlc_audio_set_callbacks( libvlc_media_player_t *mp, libvlc_audio_play_cb play_cb, libvlc_audio_set_volume_cb set_volume_cb, void *opaque ) { var_SetAddress( mp, "amem-play", play_cb ); var_SetAddress( mp, "amem-set-volume", set_volume_cb ); var_SetAddress( mp, "amem-data", opaque ); var_SetString( mp, "aout", "amem" ); }
void libvlc_video_set_callbacks( libvlc_media_player_t *mp, void *(*lock_cb) (void *, void **), void (*unlock_cb) (void *, void *, void *const *), void (*display_cb) (void *, void *), void *opaque ) { var_SetAddress( mp, "vmem-lock", lock_cb ); var_SetAddress( mp, "vmem-unlock", unlock_cb ); var_SetAddress( mp, "vmem-display", display_cb ); var_SetAddress( mp, "vmem-data", opaque ); var_SetString( mp, "vout", "vmem" ); }
static struct decklink_sys_t *GetDLSys(vlc_object_t *obj) { vlc_object_t *libvlc = VLC_OBJECT(obj->p_libvlc); struct decklink_sys_t *sys; vlc_mutex_lock(&sys_lock); if (var_Type(libvlc, "decklink-sys") == VLC_VAR_ADDRESS) sys = (struct decklink_sys_t*)var_GetAddress(libvlc, "decklink-sys"); else { sys = (struct decklink_sys_t*)malloc(sizeof(*sys)); if (sys) { sys->p_output = NULL; sys->offset = 0; sys->users = 0; sys->i_rate = -1; vlc_mutex_init(&sys->lock); vlc_cond_init(&sys->cond); var_Create(libvlc, "decklink-sys", VLC_VAR_ADDRESS); var_SetAddress(libvlc, "decklink-sys", (void*)sys); } } vlc_mutex_unlock(&sys_lock); return sys; }
/** * Sends an error message through the user interface (if any). * @param obj the VLC object emitting the error * @param modal whether to wait for user to acknowledge the error * before returning control to the caller * @param title title of the error dialog * @param fmt format string for the error message * @param ap parameters list for the formatted error message */ void dialog_VFatal (vlc_object_t *obj, bool modal, const char *title, const char *fmt, va_list ap) { char *text; if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) return; vlc_object_t *provider = dialog_GetProvider (obj); if (provider == NULL) { msg_Err (obj, "%s", title); msg_GenericVa (obj, VLC_MSG_ERR, MODULE_STRING, fmt, ap); return; } if (vasprintf (&text, fmt, ap) != -1) { dialog_fatal_t dialog = { title, text, }; var_SetAddress (provider, modal ? "dialog-critical" : "dialog-error", &dialog); free (text); } vlc_object_release (provider); }
/** * Requests a username and password through the user interface. * @param obj the VLC object requesting credential information * @param username a pointer to the specified username [OUT] * @param password a pointer to the specified password [OUT] * @param title title for the dialog * @param text format string for the message in the dialog * @return Nothing. If a user name resp. a password was specified, * it will be returned as a heap-allocated character array * into the username resp password pointer. Those must be freed with free(). * Otherwise *username resp *password will be NULL. */ void dialog_Login (vlc_object_t *obj, char **username, char **password, const char *title, const char *fmt, ...) { assert ((username != NULL) && (password != NULL)); *username = *password = NULL; if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) return; vlc_object_t *provider = dialog_GetProvider (obj); if (provider == NULL) return; char *text; va_list ap; va_start (ap, fmt); if (vasprintf (&text, fmt, ap) != -1) { dialog_login_t dialog = { title, text, username, password, }; var_SetAddress (provider, "dialog-login", &dialog); free (text); } va_end (ap); vlc_object_release (provider); }
/* Open Interface */ static int Open( vlc_object_t *p_this, bool isDialogProvider ) { intf_thread_t *p_intf = (intf_thread_t *)p_this; #ifdef Q_WS_X11 if( !vlc_xlib_init( p_this ) ) return VLC_EGENERIC; char *display = var_CreateGetNonEmptyString( p_intf, "x11-display" ); Display *p_display = XOpenDisplay( x11_display ); if( !p_display ) { msg_Err( p_intf, "Could not connect to X server" ); free (display); return VLC_EGENERIC; } XCloseDisplay( p_display ); #else char *display = NULL; #endif QMutexLocker locker (&lock); if (busy) { msg_Err (p_this, "cannot start Qt4 multiple times"); free (display); return VLC_EGENERIC; } /* Allocations of p_sys */ intf_sys_t *p_sys = p_intf->p_sys = new intf_sys_t; p_intf->p_sys->b_isDialogProvider = isDialogProvider; p_sys->p_mi = NULL; p_sys->p_playlist = pl_Get( p_intf ); /* */ #ifdef Q_WS_X11 x11_display = display; #endif vlc_sem_init (&ready, 0); if( vlc_clone( &p_sys->thread, Thread, p_intf, VLC_THREAD_PRIORITY_LOW ) ) { delete p_sys; free (display); return VLC_ENOMEM; } /* */ vlc_sem_wait (&ready); vlc_sem_destroy (&ready); busy = active = true; if( !p_sys->b_isDialogProvider ) { playlist_t *pl = pl_Get(p_this); var_Create (pl, "qt4-iface", VLC_VAR_ADDRESS); var_SetAddress (pl, "qt4-iface", p_this); } return VLC_SUCCESS; }
/** * Creates a progress bar dialog. */ dialog_progress_bar_t * dialog_ProgressCreate (vlc_object_t *obj, const char *title, const char *message, const char *cancel) { if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) return NULL; vlc_object_t *provider = dialog_GetProvider (obj); if (provider == NULL) return NULL; dialog_progress_bar_t *dialog = malloc (sizeof (*dialog)); if (dialog != NULL) { dialog->title = title; dialog->message = message; dialog->cancel = cancel; var_SetAddress (provider, "dialog-progress-bar", dialog); #ifndef NDEBUG dialog->title = dialog->message = dialog->cancel = NULL; #endif assert (dialog->pf_update); assert (dialog->pf_check); assert (dialog->pf_destroy); } /* FIXME: This could conceivably crash if the dialog provider is destroyed * before the dialog user. Holding the provider does not help, as it only * protects object variable operations. For instance, it does not prevent * unloading of the interface plugin. In the short term, the only solution * is to not use progress dialog after deinitialization of the interfaces. */ vlc_object_release (provider); return dialog; }
/** * Asks a total (Yes/No/Cancel) question through the user interface. * @param obj VLC object emitting the question * @param title dialog box title * @param fmt format string for the dialog box text * @param yes first choice/button text * @param no second choice/button text * @param cancel third answer/button text, or NULL if no third option * @return 0 if the user could not answer the question (e.g. there is no UI), * 1, 2 resp. 3 if the user pressed the first, second resp. third button. */ int dialog_Question (vlc_object_t *obj, const char *title, const char *fmt, const char *yes, const char *no, const char *cancel, ...) { if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) return 0; vlc_object_t *provider = dialog_GetProvider (obj); if (provider == NULL) return 0; char *text; va_list ap; int answer = 0; va_start (ap, cancel); if (vasprintf (&text, fmt, ap) != -1) { dialog_question_t dialog = { title, text, yes, no, cancel, 0, }; var_SetAddress (provider, "dialog-question", &dialog); answer = dialog.answer; } va_end (ap); vlc_object_release (provider); return answer; }
/** * This function preparses an item when needed. */ static void Preparse( playlist_t *p_playlist, input_item_t *p_item ) { vlc_mutex_lock( &p_item->lock ); int i_type = p_item->i_type; vlc_mutex_unlock( &p_item->lock ); if( i_type != ITEM_TYPE_FILE ) { input_item_SetPreparsed( p_item, true ); return; } stats_TimerStart( p_playlist, "Preparse run", STATS_TIMER_PREPARSE ); /* Do not preparse if it is already done (like by playing it) */ if( !input_item_IsPreparsed( p_item ) ) { input_Preparse( VLC_OBJECT(p_playlist), p_item ); input_item_SetPreparsed( p_item, true ); var_SetAddress( p_playlist, "item-change", p_item ); } stats_TimerStop( p_playlist, STATS_TIMER_PREPARSE ); }
/***************************************************************************** * An input item's meta or duration has changed (Event Callback) *****************************************************************************/ static void input_item_changed( const vlc_event_t * p_event, void * user_data ) { playlist_item_t *p_item = user_data; VLC_UNUSED( p_event ); var_SetAddress( p_item->p_playlist, "item-change", p_item->p_input ); }
/** * This function will handle a snapshot request and provide the image pointer */ static void VoutSnapshotAddr( vout_thread_t *p_vout ) { char *psz_format = var_GetNonEmptyString( p_vout, "snapshot-format" ); char *psz_prefix = var_GetNonEmptyString( p_vout, "snapshot-prefix" ); /* */ picture_t *p_picture; block_t *p_image; video_format_t fmt; /* 500ms timeout * XXX it will cause trouble with low fps video (< 2fps) */ if( vout_GetSnapshot( p_vout, &p_image, &p_picture, &fmt, psz_format, 500*1000 ) ) { p_picture = NULL; p_image = NULL; goto exit; } msg_Dbg( p_vout, "p_image addr: %i", p_image ); var_Create( p_vout, "snapshot-addr", VLC_VAR_ADDRESS ); var_SetAddress( p_vout, "snapshot-addr", (void *) p_image ); exit: if( p_picture ) picture_Release( p_picture ); free( psz_prefix ); free( psz_format ); }
/** Remove this drawable from the list of busy ones */ static void ReleaseDrawable (vlc_object_t *obj, xcb_window_t window) { xcb_window_t *used; size_t n = 0; vlc_mutex_lock (&serializer); used = var_GetAddress (obj->p_libvlc, "xid-in-use"); assert (used); while (used[n] != window) { assert (used[n]); n++; } do used[n] = used[n + 1]; while (used[++n]); if (n == 0) var_SetAddress (obj->p_libvlc, "xid-in-use", NULL); vlc_mutex_unlock (&serializer); if (n == 0) free (used); /* Variables are reference-counted... */ var_Destroy (obj->p_libvlc, "xid-in-use"); }
void libvlc_audio_set_volume_callback( libvlc_media_player_t *mp, libvlc_audio_set_volume_cb cb ) { var_SetAddress( mp, "amem-set-volume", cb ); input_resource_ResetAout(mp->input.p_resource); }
/** * Release the drawable. */ static void Close (vlc_object_t *obj) { vout_window_t *wnd = (vout_window_t *)obj; void **used, *val = wnd->p_sys; size_t n = 0; /* Remove this drawable from the list of busy ones */ vlc_mutex_lock (&serializer); used = var_GetAddress (VLC_OBJECT (obj->p_libvlc), "drawables-in-use"); assert (used); while (used[n] != val) { assert (used[n]); n++; } do used[n] = used[n + 1]; while (used[++n] != NULL); if (n == 0) /* should not be needed (var_Destroy...) but better safe than sorry: */ var_SetAddress (obj->p_libvlc, "drawables-in-use", NULL); vlc_mutex_unlock (&serializer); if (n == 0) free (used); /* Variables are reference-counted... */ var_Destroy (obj->p_libvlc, "drawables-in-use"); }
static void RegisterIntf( intf_thread_t *p_this ) { playlist_t *pl = p_this->p_sys->p_playlist; var_Create (pl, "qt4-iface", VLC_VAR_ADDRESS); var_SetAddress (pl, "qt4-iface", p_this); var_Create (pl, "window", VLC_VAR_STRING); var_SetString (pl, "window", "qt4,any"); }
/************************************************************************** * set_nsobject **************************************************************************/ void libvlc_media_player_set_nsobject( libvlc_media_player_t *p_mi, void * drawable ) { assert (p_mi != NULL); #ifdef __APPLE__ var_SetAddress (p_mi, "drawable-nsobject", drawable); #else (void) p_mi; (void)drawable; #endif }
static void TriggerInstanceState( vlm_t *p_vlm, int i_type, int64_t id, const char *psz_name, const char *psz_instance_name, input_state_e input_state ) { vlm_event_t event; event.i_type = i_type; event.id = id; event.psz_name = psz_name; event.input_state = input_state; event.psz_instance_name = psz_instance_name; var_SetAddress( p_vlm, "intf-event", &event ); }
/************************************************************************** * set_hwnd **************************************************************************/ void libvlc_media_player_set_hwnd( libvlc_media_player_t *p_mi, void *drawable ) { assert (p_mi != NULL); #ifdef WIN32 var_SetString (p_mi, "window", (drawable != NULL) ? "embed-hwnd,any" : ""); var_SetAddress (p_mi, "drawable-hwnd", drawable); #else (void) p_mi; (void) drawable; #endif }
/** * Start the input for an item * * \param p_playlist the playlist object * \param p_item the item to play * \return nothing */ static void PlayItem( playlist_t *p_playlist, playlist_item_t *p_item ) { playlist_private_t *p_sys = pl_priv(p_playlist); input_item_t *p_input = p_item->p_input; PL_ASSERT_LOCKED; msg_Dbg( p_playlist, "creating new input thread" ); p_item->i_nb_played++; set_current_status_item( p_playlist, p_item ); p_sys->status.i_status = PLAYLIST_RUNNING; assert( p_sys->p_input == NULL ); PL_UNLOCK; input_thread_t *p_input_thread = input_Create( p_playlist, p_input, NULL, p_sys->p_input_resource ); if( likely(p_input_thread != NULL) ) { var_AddCallback( p_input_thread, "intf-event", InputEvent, p_playlist ); if( input_Start( p_input_thread ) ) { var_DelCallback( p_input_thread, "intf-event", InputEvent, p_playlist ); vlc_object_release( p_input_thread ); p_input_thread = NULL; } } var_SetAddress( p_playlist, "input-current", p_input_thread ); /* TODO store art policy in playlist private data */ char *psz_arturl = input_item_GetArtURL( p_input ); /* p_input->p_meta should not be null after a successful CreateThread */ bool b_has_art = !EMPTY_STR( psz_arturl ); if( !b_has_art || strncmp( psz_arturl, "attachment://", 13 ) ) { PL_DEBUG( "requesting art for new input thread" ); libvlc_ArtRequest( p_playlist->p_libvlc, p_input, META_REQUEST_OPTION_NONE ); } free( psz_arturl ); var_TriggerCallback( p_playlist, "activity" ); PL_LOCK; p_sys->p_input = p_input_thread; }
/** * Asks a total (Yes/No/Cancel) question through the user interface. * @param obj VLC object emitting the question * @param title dialog box title * @param text dialog box text * @param yes first choice/button text * @param no second choice/button text * @param cancel third answer/button text, or NULL if no third option * @return 0 if the user could not answer the question (e.g. there is no UI), * 1, 2 resp. 3 if the user pressed the first, second resp. third button. */ int dialog_Question (vlc_object_t *obj, const char *title, const char *text, const char *yes, const char *no, const char *cancel) { if (obj->i_flags & OBJECT_FLAGS_NOINTERACT) return 0; vlc_object_t *provider = dialog_GetProvider (obj); if (provider == NULL) return 0; dialog_question_t dialog = { title, text, yes, no, cancel, 0, }; var_SetAddress (provider, "dialog-question", &dialog); vlc_object_release (provider); return dialog.answer; }
/** * Send a notification that an item has been added to a node * * \param p_playlist the playlist object * \param i_item_id id of the item added * \param i_node_id id of the node in which the item was added * \param b_signal TRUE if the function must send a signal * \return nothing */ void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id, int i_node_id, bool b_signal ) { playlist_private_t *p_sys = pl_priv(p_playlist); PL_ASSERT_LOCKED; p_sys->b_reset_currently_playing = true; if( b_signal ) vlc_cond_signal( &p_sys->signal ); playlist_add_t add; add.i_item = i_item_id; add.i_node = i_node_id; var_SetAddress( p_playlist, "playlist-item-append", &add ); }
void input_item_ApplyOptions(vlc_object_t *obj, input_item_t *item) { vlc_mutex_lock(&item->lock); assert(item->optflagc == (unsigned)item->i_options); for (unsigned i = 0; i < (unsigned)item->i_options; i++) var_OptionParse(obj, item->ppsz_options[i], !!(item->optflagv[i] & VLC_INPUT_OPTION_TRUSTED)); for (const input_item_opaque_t *o = item->opaques; o != NULL; o = o->next) { var_Create(obj, o->name, VLC_VAR_ADDRESS); var_SetAddress(obj, o->name, o->value); } vlc_mutex_unlock(&item->lock); }
void osd_MenuDelete( vlc_object_t *p_this, osd_menu_t *p_osd ) { if( !p_osd || !p_this ) return; vlc_mutex_lock( &osd_mutex ); if( vlc_internals( VLC_OBJECT(p_osd) )->i_refcount == 1 ) { var_Destroy( p_osd, "osd-menu-visible" ); var_Destroy( p_osd, "osd-menu-update" ); osd_ParserUnload( p_osd ); var_SetAddress( p_this->p_libvlc, "osd-object", NULL ); } vlc_object_release( p_osd ); vlc_mutex_unlock( &osd_mutex ); }
/** * This function preparses an item when needed. */ static void Preparse( playlist_preparser_t *preparser, input_item_t *p_item, input_item_meta_request_option_t i_options ) { vlc_mutex_lock( &p_item->lock ); int i_type = p_item->i_type; bool b_net = p_item->b_net; vlc_mutex_unlock( &p_item->lock ); bool b_preparse = false; switch (i_type) { case ITEM_TYPE_FILE: case ITEM_TYPE_DIRECTORY: case ITEM_TYPE_PLAYLIST: case ITEM_TYPE_NODE: if (!b_net || i_options & META_REQUEST_OPTION_SCOPE_NETWORK) b_preparse = true; break; } /* Do not preparse if it is already done (like by playing it) */ if( b_preparse && !input_item_IsPreparsed( p_item ) ) { input_thread_t *input = input_CreatePreparser( preparser->object, p_item ); if( input == NULL ) return; var_AddCallback( input, "intf-event", InputEvent, &preparser->item_done ); if( input_Start( input ) == VLC_SUCCESS ) vlc_sem_wait( &preparser->item_done ); var_DelCallback( input, "intf-event", InputEvent, &preparser->item_done ); /* Normally, the input is already stopped since we waited for it. But * if the playlist preparser is being deleted, then the input might * still be running. Force it to stop. */ input_Stop( input ); input_Close( input ); var_SetAddress( preparser->object, "item-change", p_item ); } input_item_SetPreparsed( p_item, true ); input_item_SignalPreparseEnded( p_item ); }
static void LoopInput( playlist_t *p_playlist ) { playlist_private_t *p_sys = pl_priv(p_playlist); input_thread_t *p_input = p_sys->p_input; assert( p_input != NULL ); if( p_sys->request.b_request || p_sys->killed ) { PL_DEBUG( "incoming request - stopping current input" ); input_Stop( p_input, true ); } #warning Unsynchronized access to *p_input flags... /* This input is dead. Remove it ! */ if( p_input->b_dead ) { p_sys->p_input = NULL; PL_DEBUG( "dead input" ); PL_UNLOCK; var_SetAddress( p_playlist, "input-current", NULL ); /* WARNING: Input resource manipulation and callback deletion are * incompatible with the playlist lock. */ if( !var_InheritBool( p_input, "sout-keep" ) ) input_resource_TerminateSout( p_sys->p_input_resource ); var_DelCallback( p_input, "intf-event", InputEvent, p_playlist ); input_Close( p_input ); var_TriggerCallback( p_playlist, "activity" ); PL_LOCK; return; } /* This input has finished, ask it to die ! */ else if( p_input->b_error || p_input->b_eof ) { PL_DEBUG( "finished input" ); input_Stop( p_input, false ); } vlc_cond_wait( &p_sys->signal, &p_sys->lock ); }
/* Actually convert an item to a node */ static void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item ) { int i; if( p_item->i_children != -1 ) return; p_item->i_children = 0; input_item_t *p_input = p_item->p_input; vlc_mutex_lock( &p_input->lock ); p_input->i_type = ITEM_TYPE_NODE; vlc_mutex_unlock( &p_input->lock ); var_SetAddress( p_playlist, "item-change", p_item->p_input ); /* Remove it from the array of available items */ ARRAY_BSEARCH( p_playlist->items,->i_id, int, p_item->i_id, i ); if( i != -1 ) ARRAY_REMOVE( p_playlist->items, i ); }
int dialog_ExtensionUpdate (vlc_object_t *obj, extension_dialog_t *dialog) { assert (obj); assert (dialog); vlc_object_t *dp = dialog_GetProvider(obj); if (!dp) { msg_Warn (obj, "Dialog provider is not set, can't update dialog '%s'", dialog->psz_title); return VLC_EGENERIC; } // Signaling the dialog provider int ret = var_SetAddress (dp, "dialog-extension", dialog); vlc_object_release (dp); return ret; }
/** * This function preparses an item when needed. */ static void Preparse( vlc_object_t *obj, input_item_t *p_item ) { vlc_mutex_lock( &p_item->lock ); int i_type = p_item->i_type; vlc_mutex_unlock( &p_item->lock ); if( i_type != ITEM_TYPE_FILE ) { input_item_SetPreparsed( p_item, true ); return; } /* Do not preparse if it is already done (like by playing it) */ if( !input_item_IsPreparsed( p_item ) ) { input_Preparse( obj, p_item ); input_item_SetPreparsed( p_item, true ); var_SetAddress( obj, "item-change", p_item ); } }