[vlc-devel] [PATCH] libvlc: merge libvlc_MediaParsedStatus and libvlc_MediaParsedCharged events
Thomas Guillem
thomas at gllm.fr
Mon May 23 18:39:32 CEST 2016
Because having two differents events for the same objective is way too
confusing (libvlc_MediaParsedStatus was recently added by me).
libvlc_MediaParsedCharged is now always sent after a call to
libvlc_media_parse_*() (this was not the case if the pre-parsing was skipped).
The core vlc_InputItemPreparsedChanged event is now only attached from the
media player. This allows the libvlc_MediaParsedCharged event to be sent when a
media is parsed from a media player.
/!\ Behavior change in libvlc API /!\
libvlc_event_t.u.media_parsed_changed.new_status changed from an int to a
libvlc_media_parsed_status_t. Before this patch, this value was always set to
true, even in case of parse failure/skipped. Now this value can be skipped (1),
failed (2) or done (3). There should be no changes for users that were checking
if new_status was true, since this events was called for these 3 cases (that
are all > 0).
---
include/vlc/libvlc_events.h | 7 +---
include/vlc/libvlc_media.h | 14 +++----
lib/event.c | 1 -
lib/media.c | 98 +++++++++++++++++++--------------------------
lib/media_internal.h | 2 +-
lib/media_player.c | 35 ++++++++++++++++
test/libvlc/media.c | 10 ++---
7 files changed, 90 insertions(+), 77 deletions(-)
diff --git a/include/vlc/libvlc_events.h b/include/vlc/libvlc_events.h
index 45ce86e..05666a3 100644
--- a/include/vlc/libvlc_events.h
+++ b/include/vlc/libvlc_events.h
@@ -53,7 +53,6 @@ enum libvlc_event_e {
libvlc_MediaFreed,
libvlc_MediaStateChanged,
libvlc_MediaSubItemTreeAdded,
- libvlc_MediaParsedStatus,
libvlc_MediaPlayerMediaChanged=0x100,
libvlc_MediaPlayerNothingSpecial,
@@ -141,7 +140,7 @@ typedef struct libvlc_event_t
} media_duration_changed;
struct
{
- int new_status;
+ libvlc_media_parsed_status_t new_status;
} media_parsed_changed;
struct
{
@@ -155,10 +154,6 @@ typedef struct libvlc_event_t
{
libvlc_media_t * item;
} media_subitemtree_added;
- struct
- {
- int new_status;
- } media_parsed_status;
/* media instance */
struct
diff --git a/include/vlc/libvlc_media.h b/include/vlc/libvlc_media.h
index d05f642..173c78a 100644
--- a/include/vlc/libvlc_media.h
+++ b/include/vlc/libvlc_media.h
@@ -265,10 +265,10 @@ typedef enum libvlc_media_parse_flag_t
*/
typedef enum libvlc_media_parsed_status_t
{
- libvlc_media_parse_init,
- libvlc_media_parse_skipped,
- libvlc_media_parse_failed,
- libvlc_media_parse_done,
+ libvlc_media_parsed_status_init,
+ libvlc_media_parsed_status_skipped,
+ libvlc_media_parsed_status_failed,
+ libvlc_media_parsed_status_done,
} libvlc_media_parsed_status_t;
/**
@@ -655,7 +655,7 @@ libvlc_media_parse( libvlc_media_t *p_md );
* This fetches (local or network) art, meta data and/or tracks information.
* This method is the extended version of libvlc_media_parse_with_options().
*
- * To track when this is over you can listen to libvlc_MediaParsedStatus
+ * To track when this is over you can listen to libvlc_MediaParsedChanged
* event. However if this functions returns an error, you will not receive any
* events.
*
@@ -663,7 +663,7 @@ libvlc_media_parse( libvlc_media_t *p_md );
* these flags can be combined. By default, media is parsed if it's a local
* file.
*
- * \see libvlc_MediaParsedStatus
+ * \see libvlc_MediaParsedChanged
* \see libvlc_media_get_meta
* \see libvlc_media_tracks_get
* \see libvlc_media_get_parsed_status
@@ -681,7 +681,7 @@ libvlc_media_parse_with_options( libvlc_media_t *p_md,
/**
* Get Parsed status for media descriptor object.
*
- * \see libvlc_MediaParsedStatus
+ * \see libvlc_MediaParsedChanged
* \see libvlc_media_parsed_status_t
*
* \param p_md media descriptor object
diff --git a/lib/event.c b/lib/event.c
index 56db14f..6beeacd 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -171,7 +171,6 @@ static const event_name_t event_list[] = {
DEF(MediaFreed)
DEF(MediaStateChanged)
DEF(MediaSubItemTreeAdded)
- DEF(MediaParsedStatus)
DEF(MediaPlayerMediaChanged)
DEF(MediaPlayerNothingSpecial)
diff --git a/lib/media.c b/lib/media.c
index 0b20aaa..c11f8f9 100644
--- a/lib/media.c
+++ b/lib/media.c
@@ -213,39 +213,49 @@ static void input_item_duration_changed( const vlc_event_t *p_event,
libvlc_event_send( p_md->p_event_manager, &event );
}
-static void send_preparsed_event(libvlc_media_t *media)
+static void send_parsed_changed( libvlc_media_t *p_md,
+ libvlc_media_parsed_status_t new_status )
{
libvlc_event_t event;
- /* Eventually notify libvlc_media_parse() */
- vlc_mutex_lock(&media->parsed_lock);
- if (media->is_parsed == true)
+ vlc_mutex_lock( &p_md->parsed_lock );
+ if( p_md->parsed_status == new_status )
{
- vlc_mutex_unlock(&media->parsed_lock);
+ vlc_mutex_unlock( &p_md->parsed_lock );
return;
}
- media->is_parsed = true;
- vlc_cond_broadcast(&media->parsed_cond);
- vlc_mutex_unlock(&media->parsed_lock);
+ /* 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 = true;
+ event.u.media_parsed_changed.new_status = new_status;
/* Send the event */
- libvlc_event_send(media->p_event_manager, &event);
-}
-
-/**************************************************************************
- * input_item_preparsed_changed (Private) (vlc event Callback)
- **************************************************************************/
-static void input_item_preparsed_changed(const vlc_event_t *p_event,
- void * user_data)
-{
- VLC_UNUSED( p_event );
- libvlc_media_t *media = user_data;
- send_preparsed_event(media);
+ libvlc_event_send( p_md->p_event_manager, &event );
}
/**************************************************************************
@@ -254,44 +264,24 @@ static void input_item_preparsed_changed(const vlc_event_t *p_event,
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;
+ libvlc_media_parsed_status_t new_status;
- event.type = libvlc_MediaParsedStatus;
-
- vlc_mutex_lock(&p_md->parsed_lock);
- switch (p_event->u.input_item_preparse_ended.new_status)
+ 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;
+ new_status = libvlc_media_parsed_status_skipped;
break;
case ITEM_PREPARSE_FAILED:
- p_md->parsed_status = libvlc_media_parse_failed;
+ new_status = libvlc_media_parsed_status_failed;
break;
case ITEM_PREPARSE_DONE:
- p_md->parsed_status = libvlc_media_parse_done;
+ new_status = libvlc_media_parsed_status_done;
break;
+ default:
+ return;
}
- 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);
+ send_parsed_changed( p_md, new_status );
}
/**************************************************************************
@@ -312,10 +302,6 @@ static void install_input_item_observer( libvlc_media_t *p_md )
input_item_duration_changed,
p_md );
vlc_event_attach( &p_md->p_input_item->event_manager,
- vlc_InputItemPreparsedChanged,
- input_item_preparsed_changed,
- p_md );
- vlc_event_attach( &p_md->p_input_item->event_manager,
vlc_InputItemSubItemTreeAdded,
input_item_subitemtree_added,
p_md );
@@ -343,10 +329,6 @@ static void uninstall_input_item_observer( libvlc_media_t *p_md )
input_item_duration_changed,
p_md );
vlc_event_detach( &p_md->p_input_item->event_manager,
- vlc_InputItemPreparsedChanged,
- input_item_preparsed_changed,
- p_md );
- vlc_event_detach( &p_md->p_input_item->event_manager,
vlc_InputItemSubItemTreeAdded,
input_item_subitemtree_added,
p_md );
@@ -756,6 +738,8 @@ static int media_parse(libvlc_media_t *media, bool b_async,
vlc_mutex_lock(&media->parsed_lock);
needed = !media->has_asked_preparse;
media->has_asked_preparse = true;
+ if (needed)
+ media->is_parsed = false;
vlc_mutex_unlock(&media->parsed_lock);
if (needed)
diff --git a/lib/media_internal.h b/lib/media_internal.h
index dd12176..f063ddb 100644
--- a/lib/media_internal.h
+++ b/lib/media_internal.h
@@ -45,7 +45,7 @@ struct libvlc_media_t
vlc_mutex_t parsed_lock;
vlc_mutex_t subitems_lock;
- int parsed_status;
+ libvlc_media_parsed_status_t parsed_status;
bool is_parsed;
bool has_asked_preparse;
};
diff --git a/lib/media_player.c b/lib/media_player.c
index 4761fee..b561daa 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -124,6 +124,35 @@ static inline void unlock_input(libvlc_media_player_t *mp)
vlc_mutex_unlock(&mp->input.lock);
}
+static void input_item_preparsed_changed( const vlc_event_t *p_event,
+ void * user_data )
+{
+ libvlc_media_t *p_md = user_data;
+ if( p_event->u.input_item_preparsed_changed.new_status & ITEM_PREPARSED )
+ {
+ /* Send the event */
+ libvlc_event_t event;
+ event.type = libvlc_MediaParsedChanged;
+ event.u.media_parsed_changed.new_status = libvlc_media_parsed_status_done;
+ libvlc_event_send( p_md->p_event_manager, &event );
+ }
+}
+
+static void media_attach_preparsed_event( libvlc_media_t *p_md )
+{
+ vlc_event_attach( &p_md->p_input_item->event_manager,
+ vlc_InputItemPreparsedChanged,
+ input_item_preparsed_changed, p_md );
+}
+
+static void media_detach_preparsed_event( libvlc_media_t *p_md )
+{
+ vlc_event_detach( &p_md->p_input_item->event_manager,
+ vlc_InputItemPreparsedChanged,
+ input_item_preparsed_changed,
+ p_md );
+}
+
/*
* Release the associated input thread.
*
@@ -139,6 +168,8 @@ static void release_input_thread( libvlc_media_player_t *p_mi )
return;
p_mi->input.p_thread = NULL;
+ media_detach_preparsed_event( p_mi->p_md );
+
var_DelCallback( p_input_thread, "can-seek",
input_seekable_changed, p_mi );
var_DelCallback( p_input_thread, "can-pause",
@@ -914,12 +945,15 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi )
return -1;
}
+ media_attach_preparsed_event( p_mi->p_md );
+
p_input_thread = input_Create( p_mi, p_mi->p_md->p_input_item, NULL,
p_mi->input.p_resource );
unlock(p_mi);
if( !p_input_thread )
{
unlock_input(p_mi);
+ media_detach_preparsed_event( p_mi->p_md );
libvlc_printerr( "Not enough memory" );
return -1;
}
@@ -939,6 +973,7 @@ int libvlc_media_player_play( libvlc_media_player_t *p_mi )
var_DelCallback( p_input_thread, "program-scrambled", input_scrambled_changed, p_mi );
var_DelCallback( p_input_thread, "can-seek", input_seekable_changed, p_mi );
input_Close( p_input_thread );
+ media_detach_preparsed_event( p_mi->p_md );
libvlc_printerr( "Input initialization failure" );
return -1;
}
diff --git a/test/libvlc/media.c b/test/libvlc/media.c
index 51adb6a..f9de060 100644
--- a/test/libvlc/media.c
+++ b/test/libvlc/media.c
@@ -61,7 +61,7 @@ static void test_media_preparsed(int argc, const char** argv,
// Check to see if we are properly receiving the event.
libvlc_event_manager_t *em = libvlc_media_event_manager (media);
- libvlc_event_attach (em, libvlc_MediaParsedStatus, media_parse_ended, &sem);
+ libvlc_event_attach (em, libvlc_MediaParsedChanged, media_parse_ended, &sem);
// Parse the media. This is synchronous.
int i_ret = libvlc_media_parse_with_options(media, libvlc_media_parse_local);
@@ -159,7 +159,7 @@ static void test_media_subitems_media(libvlc_media_t *media, bool play,
}
else
{
- libvlc_event_attach (em, libvlc_MediaParsedStatus, subitem_parse_ended, &sem);
+ libvlc_event_attach (em, libvlc_MediaParsedChanged, subitem_parse_ended, &sem);
int i_ret = libvlc_media_parse_with_options(media, libvlc_media_parse_local);
assert(i_ret == 0);
@@ -238,13 +238,13 @@ int main (void)
test_media_preparsed (test_defaults_nargs, test_defaults_args,
SRCDIR"/samples/image.jpg", NULL,
- libvlc_media_parse_done);
+ libvlc_media_parsed_status_done);
test_media_preparsed (test_defaults_nargs, test_defaults_args,
NULL, "http://parsing_should_be_skipped.org/video.mp4",
- libvlc_media_parse_skipped);
+ libvlc_media_parsed_status_skipped);
test_media_preparsed (test_defaults_nargs, test_defaults_args,
NULL, "unknown://parsing_should_be_skipped.org/video.mp4",
- libvlc_media_parse_skipped);
+ libvlc_media_parsed_status_skipped);
test_media_subitems (test_defaults_nargs, test_defaults_args);
return 0;
--
2.8.1
More information about the vlc-devel
mailing list