/************************************************************************** * Delete a media descriptor object **************************************************************************/ void libvlc_media_release( libvlc_media_t *p_md ) { if (!p_md) return; p_md->i_refcount--; if( p_md->i_refcount > 0 ) return; if( p_md->p_subitems ) libvlc_media_list_release( p_md->p_subitems ); uninstall_input_item_observer( p_md ); vlc_gc_decref( p_md->p_input_item ); vlc_cond_destroy( &p_md->parsed_cond ); vlc_mutex_destroy( &p_md->parsed_lock ); /* Construct the event */ libvlc_event_t event; event.type = libvlc_MediaFreed; event.u.media_freed.md = p_md; /* Send the event */ libvlc_event_send( p_md->p_event_manager, &event ); libvlc_event_manager_release( p_md->p_event_manager ); free( p_md ); }
/************************************************************************** * notify_item_addition (private) * * Do the appropriate action when an item is deleted. **************************************************************************/ static void notify_item_addition( libvlc_media_list_t * p_mlist, libvlc_media_t * p_md, int index, EventPlaceInTime event_status ) { libvlc_event_t event; /* Construct the event */ if( event_status == EventDidHappen ) { event.type = libvlc_MediaListItemAdded; event.u.media_list_item_added.item = p_md; event.u.media_list_item_added.index = index; } else /* if( event_status == EventWillHappen ) */ { event.type = libvlc_MediaListWillAddItem; event.u.media_list_will_add_item.item = p_md; event.u.media_list_will_add_item.index = index; } /* Send the event */ libvlc_event_send( p_mlist->p_event_manager, &event ); }
/************************************************************************** * notify_item_deletion (private) * * Do the appropriate action when an item is added. **************************************************************************/ static void notify_item_deletion( libvlc_media_list_t * p_mlist, libvlc_media_t * p_md, int index, EventPlaceInTime event_status ) { libvlc_event_t event; /* Construct the event */ if( event_status == EventDidHappen ) { trace("item at index %d was deleted\n", index); event.type = libvlc_MediaListItemDeleted; event.u.media_list_item_deleted.item = p_md; event.u.media_list_item_deleted.index = index; } else /* if( event_status == EventWillHappen ) */ { event.type = libvlc_MediaListWillDeleteItem; event.u.media_list_will_delete_item.item = p_md; event.u.media_list_will_delete_item.index = index; } /* Send the event */ libvlc_event_send( p_mlist->p_event_manager, &event ); }
/************************************************************************** * input_item_subitem_added (Private) (vlc event Callback) **************************************************************************/ static void input_item_subitem_added( const vlc_event_t *p_event, void * user_data ) { libvlc_media_t * p_md = user_data; libvlc_media_t * p_md_child; libvlc_event_t event; p_md_child = libvlc_media_new_from_input_item( p_md->p_libvlc_instance, p_event->u.input_item_subitem_added.p_new_child ); /* Add this to our media list */ if( !p_md->p_subitems ) { p_md->p_subitems = libvlc_media_list_new( p_md->p_libvlc_instance ); libvlc_media_list_set_media( p_md->p_subitems, p_md ); } if( p_md->p_subitems ) { libvlc_media_list_add_media( p_md->p_subitems, p_md_child ); } /* Construct the event */ event.type = libvlc_MediaSubItemAdded; event.u.media_subitem_added.new_child = p_md_child; /* Send the event */ libvlc_event_send( p_md->p_event_manager, &event ); libvlc_media_release( p_md_child ); }
/* LibVLC internal */ void libvlc_media_list_internal_end_reached( libvlc_media_list_t * p_mlist ) { libvlc_event_t event; event.type = libvlc_MediaListEndReached; /* Send the event */ libvlc_event_send( p_mlist->p_event_manager, &event ); }
static void renderer_discovery_item_added( vlc_renderer_discovery_t *rd, vlc_renderer_item_t *p_item ) { libvlc_renderer_discoverer_t *p_lrd = rd->owner.sys; vlc_renderer_item_hold( p_item ); TAB_APPEND( p_lrd->i_items, p_lrd->pp_items, p_item ); libvlc_event_t event = { .type = libvlc_RendererDiscovererItemAdded, .u.renderer_discoverer_item_added.item = (libvlc_renderer_item_t*) p_item, }; libvlc_event_send( &p_lrd->event_manager, &event ); } static void renderer_discovery_item_removed( vlc_renderer_discovery_t *rd, vlc_renderer_item_t *p_item ) { libvlc_renderer_discoverer_t *p_lrd = rd->owner.sys; int i_idx; TAB_FIND( p_lrd->i_items, p_lrd->pp_items, p_item, i_idx ); assert( i_idx != -1 ); TAB_ERASE( p_lrd->i_items, p_lrd->pp_items, i_idx ); libvlc_event_t event = { .type = libvlc_RendererDiscovererItemDeleted, .u.renderer_discoverer_item_deleted.item = (libvlc_renderer_item_t*) p_item, }; libvlc_event_send( &p_lrd->event_manager, &event ); vlc_renderer_item_release( p_item ); } libvlc_renderer_item_t * libvlc_renderer_item_hold(libvlc_renderer_item_t *p_item) { vlc_renderer_item_hold( (vlc_renderer_item_t *) p_item ); return p_item; }
static void services_discovery_ended( const vlc_event_t * p_event, void * user_data ) { VLC_UNUSED(p_event); libvlc_media_discoverer_t * p_mdis = user_data; libvlc_event_t event; p_mdis->running = false; event.type = libvlc_MediaDiscovererEnded; libvlc_event_send( p_mdis->p_event_manager, &event ); }
/************************************************************************** * Snapshot Taken Event. * * FIXME: This snapshot API interface makes no sense in media_player. *************************************************************************/ static int snapshot_was_taken(vlc_object_t *p_this, char const *psz_cmd, vlc_value_t oldval, vlc_value_t newval, void *p_data ) { VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval); VLC_UNUSED(p_this); libvlc_media_player_t *mp = p_data; libvlc_event_t event; event.type = libvlc_MediaPlayerSnapshotTaken; event.u.media_player_snapshot_taken.psz_filename = newval.psz_string; libvlc_event_send(mp->p_event_manager, &event); return VLC_SUCCESS; }
/************************************************************************** * Play item at index (Public) **************************************************************************/ int libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp, int i_index) { lock(p_mlp); set_current_playing_item(p_mlp, libvlc_media_list_path_with_root_index(i_index)); libvlc_media_player_play(p_mlp->p_mi); unlock(p_mlp); /* Send the next item event */ libvlc_event_t event; event.type = libvlc_MediaListPlayerNextItemSet; libvlc_event_send(p_mlp->p_event_manager, &event); return 0; }
/************************************************************************** * input_item_subitemtree_added (Private) (vlc event Callback) **************************************************************************/ static void input_item_subitemtree_added( const vlc_event_t * p_event, void * user_data ) { VLC_UNUSED( p_event ); libvlc_media_t * p_md = user_data; libvlc_event_t event; /* Construct the event */ event.type = libvlc_MediaSubItemTreeAdded; event.u.media_subitemtree_added.item = p_md; /* Send the event */ libvlc_event_send( p_md->p_event_manager, &event ); }
/************************************************************************** * input_item_meta_changed (Private) (vlc event Callback) **************************************************************************/ static void input_item_meta_changed( const vlc_event_t *p_event, void * user_data ) { libvlc_media_t * p_md = user_data; libvlc_event_t event; /* Construct the event */ event.type = libvlc_MediaMetaChanged; event.u.media_meta_changed.meta_type = vlc_to_libvlc_meta[p_event->u.input_item_meta_changed.meta_type]; /* Send the event */ libvlc_event_send( p_md->p_event_manager, &event ); }
/************************************************************************** * input_item_duration_changed (Private) (vlc event Callback) **************************************************************************/ static void input_item_duration_changed( const vlc_event_t *p_event, void * user_data ) { libvlc_media_t * p_md = user_data; libvlc_event_t event; /* Construct the event */ event.type = libvlc_MediaDurationChanged; event.u.media_duration_changed.new_duration = from_mtime(p_event->u.input_item_duration_changed.new_duration); /* Send the event */ libvlc_event_send( p_md->p_event_manager, &event ); }
/************************************************************************** * Play item at index (Public) **************************************************************************/ void libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp, int i_index, libvlc_exception_t * p_e) { VLC_UNUSED(p_e); lock(p_mlp); set_current_playing_item(p_mlp, libvlc_media_list_path_with_root_index(i_index)); libvlc_media_player_play(p_mlp->p_mi, p_e); unlock(p_mlp); /* Send the next item event */ libvlc_event_t event; event.type = libvlc_MediaListPlayerNextItemSet; libvlc_event_send(p_mlp->p_event_manager, &event); }
void libvlc_media_set_state( libvlc_media_t *p_md, libvlc_state_t state ) { libvlc_event_t event; p_md->state = state; /* Construct the event */ event.type = libvlc_MediaStateChanged; event.u.media_state_changed.new_state = state; /* Send the event */ libvlc_event_send( p_md->p_event_manager, &event ); }
/************************************************************************** * stop (Public) **************************************************************************/ LIBVLC_API void libvlc_media_discoverer_stop( libvlc_media_discoverer_t * p_mdis ) { libvlc_media_list_t * p_mlist = p_mdis->p_mlist; libvlc_media_list_lock( p_mlist ); libvlc_media_list_internal_end_reached( p_mlist ); libvlc_media_list_unlock( p_mlist ); libvlc_event_t event; event.type = libvlc_MediaDiscovererEnded; libvlc_event_send( &p_mdis->event_manager, &event ); vlc_sd_Destroy( p_mdis->p_sd ); p_mdis->p_sd = NULL; }
/************************************************************************** * libvlc_media_list_view_notify_deletion (Internal) **************************************************************************/ void libvlc_media_list_view_will_delete_item( libvlc_media_list_view_t * p_mlv, libvlc_media_t * p_item, int index ) { libvlc_event_t event; /* Construct the event */ event.type = libvlc_MediaListViewWillDeleteItem; event.u.media_list_view_will_delete_item.item = p_item; event.u.media_list_view_will_delete_item.index = index; /* Send the event */ libvlc_event_send( p_mlv->p_event_manager, &event ); }
/************************************************************************** * libvlc_media_list_view_item_added (Internal) **************************************************************************/ void libvlc_media_list_view_item_added( libvlc_media_list_view_t * p_mlv, libvlc_media_t * p_item, int index ) { libvlc_event_t event; /* Construct the event */ event.type = libvlc_MediaListViewItemAdded; event.u.media_list_view_item_added.item = p_item; event.u.media_list_view_item_added.index = index; /* Send the event */ libvlc_event_send( p_mlv->p_event_manager, &event ); }
static int input_scrambled_changed( vlc_object_t * p_this, char const * psz_cmd, vlc_value_t oldval, vlc_value_t newval, void * p_userdata ) { VLC_UNUSED(oldval); VLC_UNUSED(p_this); VLC_UNUSED(psz_cmd); libvlc_media_player_t * p_mi = p_userdata; libvlc_event_t event; event.type = libvlc_MediaPlayerScrambledChanged; event.u.media_player_scrambled_changed.new_scrambled = newval.b_bool; libvlc_event_send( p_mi->p_event_manager, &event ); return VLC_SUCCESS; }
static void services_discovery_ended( const vlc_event_t * p_event, void * user_data ) { VLC_UNUSED(p_event); libvlc_media_discoverer_t * p_mdis = user_data; libvlc_media_list_t * p_mlist = p_mdis->p_mlist; libvlc_event_t event; p_mdis->running = false; libvlc_media_list_lock( p_mlist ); libvlc_media_list_internal_end_reached( p_mlist ); libvlc_media_list_unlock( p_mlist ); event.type = libvlc_MediaDiscovererEnded; libvlc_event_send( p_mdis->p_event_manager, &event ); }
/************************************************************************** * Stop (Private) * * Lock must be held. **************************************************************************/ static void stop(libvlc_media_list_player_t * p_mlp) { assert_locked(p_mlp); /* We are not interested in getting media stop event now */ uninstall_media_player_observer(p_mlp); libvlc_media_player_stop(p_mlp->p_mi); install_media_player_observer(p_mlp); free(p_mlp->current_playing_item_path); p_mlp->current_playing_item_path = NULL; /* Send the event */ libvlc_event_t event; event.type = libvlc_MediaListPlayerStopped; libvlc_event_send(&p_mlp->event_manager, &event); }
void libvlc_media_player_set_title( libvlc_media_player_t *p_mi, int i_title ) { input_thread_t *p_input_thread; p_input_thread = libvlc_get_input_thread ( p_mi ); if( !p_input_thread ) return; var_SetInteger( p_input_thread, "title", i_title ); vlc_object_release( p_input_thread ); //send event libvlc_event_t event; event.type = libvlc_MediaPlayerTitleChanged; event.u.media_player_title_changed.new_title = i_title; libvlc_event_send( p_mi->p_event_manager, &event ); }
static void send_parsed_changed( libvlc_media_t *p_md, libvlc_media_parsed_status_t new_status ) { libvlc_event_t event; vlc_mutex_lock( &p_md->parsed_lock ); if( p_md->parsed_status == new_status ) { vlc_mutex_unlock( &p_md->parsed_lock ); return; } /* Legacy: notify libvlc_media_parse */ if( !p_md->is_parsed ) { p_md->is_parsed = true; vlc_cond_broadcast( &p_md->parsed_cond ); } p_md->parsed_status = new_status; if( p_md->parsed_status == libvlc_media_parsed_status_skipped ) p_md->has_asked_preparse = false; vlc_mutex_unlock( &p_md->parsed_lock ); if( new_status == libvlc_media_parsed_status_done ) { libvlc_media_list_t *p_subitems = media_get_subitems( p_md, false ); if( p_subitems != NULL ) { /* notify the media list */ libvlc_media_list_lock( p_subitems ); libvlc_media_list_internal_end_reached( p_subitems ); libvlc_media_list_unlock( p_subitems ); } } /* Construct the event */ event.type = libvlc_MediaParsedChanged; event.u.media_parsed_changed.new_status = new_status; /* Send the event */ libvlc_event_send( p_md->p_event_manager, &event ); }
/************************************************************************** * input_item_preparse_ended (Private) (vlc event Callback) **************************************************************************/ static void input_item_preparse_ended( const vlc_event_t * p_event, void * user_data ) { VLC_UNUSED( p_event ); libvlc_media_t * p_md = user_data; libvlc_media_list_t *p_subitems = media_get_subitems( p_md, false ); libvlc_event_t event; event.type = libvlc_MediaParsedStatus; vlc_mutex_lock(&p_md->parsed_lock); switch (p_event->u.input_item_preparse_ended.new_status) { case ITEM_PREPARSE_SKIPPED: p_md->parsed_status = libvlc_media_parse_skipped; p_md->has_asked_preparse = false; break; case ITEM_PREPARSE_FAILED: p_md->parsed_status = libvlc_media_parse_failed; break; case ITEM_PREPARSE_DONE: p_md->parsed_status = libvlc_media_parse_done; break; } event.u.media_parsed_status.new_status = p_md->parsed_status; vlc_mutex_unlock(&p_md->parsed_lock); if( p_subitems != NULL ) { /* notify the media list */ libvlc_media_list_lock( p_subitems ); libvlc_media_list_internal_end_reached( p_subitems ); libvlc_media_list_unlock( p_subitems ); } /* XXX: libVLC 2.2.0 compat: even if case of preparse failure, * libvlc_MediaParsedChanged was sent with a true status. Therefore, send * this event if it was not previously sent */ send_preparsed_event(p_md); libvlc_event_send(p_md->p_event_manager, &event); }
/************************************************************************** * Set the Media descriptor associated with the instance. * * Enter without lock -- function will lock the object. **************************************************************************/ void libvlc_media_player_set_media( libvlc_media_player_t *p_mi, libvlc_media_t *p_md ) { lock_input(p_mi); /* FIXME I am not sure if it is a user request or on die(eof/error) * request here */ release_input_thread( p_mi, p_mi->input.p_thread && !p_mi->input.p_thread->b_eof && !p_mi->input.p_thread->b_error ); lock( p_mi ); set_state( p_mi, libvlc_NothingSpecial, true ); unlock_input( p_mi ); libvlc_media_release( p_mi->p_md ); if( !p_md ) { p_mi->p_md = NULL; unlock(p_mi); return; /* It is ok to pass a NULL md */ } libvlc_media_retain( p_md ); p_mi->p_md = p_md; /* The policy here is to ignore that we were created using a different * libvlc_instance, because we don't really care */ p_mi->p_libvlc_instance = p_md->p_libvlc_instance; unlock(p_mi); /* Send an event for the newly available media */ libvlc_event_t event; event.type = libvlc_MediaPlayerMediaChanged; event.u.media_player_media_changed.new_media = p_md; libvlc_event_send( p_mi->p_event_manager, &event ); }
/************************************************************************** * Play item at index (Public) **************************************************************************/ int libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp, int i_index) { lock(p_mlp); libvlc_media_list_path_t path = libvlc_media_list_path_with_root_index(i_index); set_current_playing_item(p_mlp, path); libvlc_media_t *p_md = libvlc_media_player_get_media(p_mlp->p_mi); libvlc_media_player_play(p_mlp->p_mi); unlock(p_mlp); if (!p_md) return -1; /* Send the next item event */ libvlc_event_t event; event.type = libvlc_MediaListPlayerNextItemSet; event.u.media_list_player_next_item_set.item = p_md; libvlc_event_send(&p_mlp->event_manager, &event); libvlc_media_release(p_md); return 0; }
/************************************************************************** * input_item_preparsed_changed (Private) (vlc event Callback) **************************************************************************/ static void input_item_preparsed_changed(const vlc_event_t *p_event, void * user_data) { libvlc_media_t *media = user_data; libvlc_event_t event; /* Eventually notify libvlc_media_parse() */ vlc_mutex_lock(&media->parsed_lock); media->is_parsed = true; vlc_cond_broadcast(&media->parsed_cond); vlc_mutex_unlock(&media->parsed_lock); /* Construct the event */ event.type = libvlc_MediaParsedChanged; event.u.media_parsed_changed.new_status = p_event->u.input_item_preparsed_changed.new_status; /* Send the event */ libvlc_event_send(media->p_event_manager, &event); }
/************************************************************************** * Stop playing. **************************************************************************/ void libvlc_media_player_stop( libvlc_media_player_t *p_mi ) { libvlc_state_t state = libvlc_media_player_get_state( p_mi ); lock_input(p_mi); release_input_thread( p_mi, true ); /* This will stop the input thread */ /* Force to go to stopped state, in case we were in Ended, or Error * state. */ if( state != libvlc_Stopped ) { set_state( p_mi, libvlc_Stopped, false ); /* Construct and send the event */ libvlc_event_t event; event.type = libvlc_MediaPlayerStopped; libvlc_event_send( p_mi->p_event_manager, &event ); } input_resource_Terminate( p_mi->input.p_resource ); unlock_input(p_mi); }
/************************************************************************** * start (Public) **************************************************************************/ LIBVLC_API int libvlc_media_discoverer_start( libvlc_media_discoverer_t * p_mdis ) { struct services_discovery_owner_t owner = { p_mdis, services_discovery_item_added, services_discovery_item_removed, }; /* Here we go */ p_mdis->p_sd = vlc_sd_Create( (vlc_object_t *)p_mdis->p_libvlc_instance->p_libvlc_int, p_mdis->name, &owner ); if( p_mdis->p_sd == NULL ) { libvlc_printerr( "%s: no such discovery module found", p_mdis->name ); return -1; } libvlc_event_t event; event.type = libvlc_MediaDiscovererStarted; libvlc_event_send( &p_mdis->event_manager, &event ); return 0; }
static void send_preparsed_event(libvlc_media_t *media) { libvlc_event_t event; /* Eventually notify libvlc_media_parse() */ vlc_mutex_lock(&media->parsed_lock); if (media->is_parsed == true) { vlc_mutex_unlock(&media->parsed_lock); return; } media->is_parsed = true; vlc_cond_broadcast(&media->parsed_cond); vlc_mutex_unlock(&media->parsed_lock); /* Construct the event */ event.type = libvlc_MediaParsedChanged; event.u.media_parsed_changed.new_status = true; /* Send the event */ libvlc_event_send(media->p_event_manager, &event); }
/************************************************************************** * Set relative playlist position and play (Private) * * Sets the currently played item to the given relative play item position * (based on the currently playing item) and then begins the new item playback. * Lock must be held. **************************************************************************/ static void set_relative_playlist_position_and_play( libvlc_media_list_player_t * p_mlp, int i_relative_position, libvlc_exception_t * p_e) { assert_locked(p_mlp); if (!p_mlp->p_mlist) { libvlc_exception_raise(p_e); libvlc_printerr("No media list"); return; } libvlc_media_list_lock(p_mlp->p_mlist); libvlc_media_list_path_t path = p_mlp->current_playing_item_path; if(p_mlp->e_playback_mode != libvlc_playback_mode_repeat) { bool b_loop = (p_mlp->e_playback_mode == libvlc_playback_mode_loop); if(i_relative_position > 0) { do { path = get_next_path(p_mlp, b_loop); set_current_playing_item(p_mlp, path); --i_relative_position; } while(i_relative_position > 0); } else if(i_relative_position < 0) { do { path = get_previous_path(p_mlp, b_loop); set_current_playing_item(p_mlp, path); ++i_relative_position; } while (i_relative_position < 0); } } else { set_current_playing_item(p_mlp, path); } #ifdef DEBUG_MEDIA_LIST_PLAYER printf("Playing:"); libvlc_media_list_path_dump(path); #endif if (!path) { libvlc_media_list_unlock(p_mlp->p_mlist); stop(p_mlp, p_e); return; } libvlc_media_player_play(p_mlp->p_mi, p_e); libvlc_media_list_unlock(p_mlp->p_mlist); /* Send the next item event */ libvlc_event_t event; event.type = libvlc_MediaListPlayerNextItemSet; libvlc_media_t * p_md = libvlc_media_list_item_at_path(p_mlp->p_mlist, path); event.u.media_list_player_next_item_set.item = p_md; libvlc_event_send(p_mlp->p_event_manager, &event); libvlc_media_release(p_md); }