lib: media_player: fix libvlc_MediaPlayerMediaChanged event

- Don't override the media set by the user from
  on_current_media_changed().

- Don't create a new media from an input_item. This will prevent to send
  media events with a media pointer that is unknown to the caller.

This callback is now always sending a media that is set with
libvlc_media_player_set_media().

Since the player is now fully asynchronous, a call to set_media() +
play() will be processed asynchronously if an older media is playing.
The user might want to know when its new media is actually playing.
Listening to the libvlc_MediaPlayerMediaChanged event is only way to do so.

Here is an example:

1. set_media(A) && play()
  -> get_media() -> A
2. set_media(B) && play()
  -> get_media() -> B
3. libvlc_MediaPlayerMediaChanged(A)
  -> get_media() -> B
4. libvlc_MediaPlayerMediaChanged(B)
  -> get_media() -> B
This commit is contained in:
Thomas Guillem 2020-09-18 14:29:32 +02:00
parent 094a092e22
commit d57a576434
3 changed files with 17 additions and 23 deletions

View File

@ -197,16 +197,25 @@ LIBVLC_API void libvlc_media_player_retain( libvlc_media_player_t *p_mi );
* Set the media that will be used by the media_player. If any,
* previous md will be released.
*
* \note The user should listen to the libvlc_MediaPlayerMediaChanged event, to
* know when the new media is actually used by the player (or to known that the
* older media is no longuer used).
*
* \param p_mi the Media Player
* \param p_md the Media. Afterwards the p_md can be safely
* destroyed.
*/
LIBVLC_API void libvlc_media_player_set_media( libvlc_media_player_t *p_mi,
libvlc_media_t *p_md );
libvlc_media_t *p_md );
/**
* Get the media used by the media_player.
*
* \warning Calling this function just after libvlc_media_player_set_media()
* will return the media that was just set, but this media might not be
* currently used internally by the player. To detect such case, the user
* should listen to the libvlc_MediaPlayerMediaChanged event.
*
* \param p_mi the Media Player
* \return the media associated with p_mi, or NULL if no
* media is associated

View File

@ -479,6 +479,7 @@ libvlc_media_t * libvlc_media_new_from_input_item(
/* A media descriptor can be a playlist. When you open a playlist
* It can give a bunch of item to read. */
p_md->p_subitems = NULL;
p_md->p_input_item->libvlc_owner = p_md;
libvlc_event_manager_init( &p_md->event_manager, p_md );

View File

@ -64,34 +64,18 @@ on_current_media_changed(vlc_player_t *player, input_item_t *new_media,
libvlc_media_player_t *mp = data;
libvlc_media_t *md = mp->p_md;
input_item_t *media = md ? md->p_input_item : NULL;
if (new_media == media)
/* no changes */
return;
if (md)
media_detach_preparsed_event(md);
if (new_media)
libvlc_media_t *libmedia;
if (new_media != NULL)
{
mp->p_md = libvlc_media_new_from_input_item(mp->p_libvlc_instance,
new_media);
if (!mp->p_md)
/* error already printed by the function call */
return;
media_attach_preparsed_event(mp->p_md);
libmedia = new_media->libvlc_owner;
assert(libmedia != NULL);
}
else
mp->p_md = NULL;
libvlc_media_release(md);
libmedia = NULL;
libvlc_event_t event;
event.type = libvlc_MediaPlayerMediaChanged;
event.u.media_player_media_changed.new_media = mp->p_md;
event.u.media_player_media_changed.new_media = libmedia;
libvlc_event_send(&mp->event_manager, &event);
}