Commit 9126e33f authored by Thomas Guillem's avatar Thomas Guillem

libvlc: merge libvlc_MediaParsedStatus and libvlc_MediaParsedCharged events

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 /!\

The libvlc_event_t.u.media_parsed_changed.new_status value changed, this is now
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).
parent b016524c
......@@ -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;
int new_status; /**< see @ref libvlc_media_parsed_status_t */
} 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
......
......@@ -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
......
......@@ -171,7 +171,6 @@ static const event_name_t event_list[] = {
DEF(MediaFreed)
DEF(MediaStateChanged)
DEF(MediaSubItemTreeAdded)
DEF(MediaParsedStatus)
DEF(MediaPlayerMediaChanged)
DEF(MediaPlayerNothingSpecial)
......
......@@ -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 );
}
/**************************************************************************
......@@ -311,10 +301,6 @@ static void install_input_item_observer( libvlc_media_t *p_md )
vlc_InputItemDurationChanged,
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,
......@@ -342,10 +328,6 @@ static void uninstall_input_item_observer( libvlc_media_t *p_md )
vlc_InputItemDurationChanged,
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,
......@@ -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)
......
......@@ -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;
};
......
......@@ -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;
}
......
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment