[vlc-devel] [VLC3 2/2] vlm: temporize on errors
Romain Vimont
rom1v at videolabs.io
Tue Jun 4 15:09:05 CEST 2019
VLM suffered from the same "infinite live loop on error" issue as the
playlist:
<https://forum.videolan.org/viewtopic.php?t=149608>
Apply the same strategy as in d06622651fcd4a608c06cb35e725fad57bf38167:
wait some delay before starting the next item, depending on the number
of consecutive errors:
- 1st error: 100ms
- 2nd error: 200ms
- 3rd error: 400ms
- 4th error: 800ms
- 5th error: 1.6s
- further errors: 3.2s
A single successful playback resets the errors counter.
---
src/input/vlm.c | 32 +++++++++++++++++++++++++++++++-
src/input/vlm_internal.h | 7 +++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/src/input/vlm.c b/src/input/vlm.c
index ed6a5bd3ff..d001cdb86c 100644
--- a/src/input/vlm.c
+++ b/src/input/vlm.c
@@ -99,9 +99,16 @@ static int InputEvent( vlc_object_t *p_this, char const *psz_cmd,
break;
}
}
- vlm_SendEventMediaInstanceState( p_vlm, p_media->cfg.id, p_media->cfg.psz_name, psz_instance_name, var_GetInteger( p_input, "state" ) );
+ int state = var_GetInteger(p_input, "state");
+ vlm_SendEventMediaInstanceState( p_vlm, p_media->cfg.id, p_media->cfg.psz_name, psz_instance_name, state );
vlc_mutex_lock( &p_vlm->lock_manage );
+
+ if (state == PLAYING_S)
+ p_vlm->i_consecutive_errors = 0;
+ else if (state == ERROR_S && p_vlm->i_consecutive_errors < 6)
+ p_vlm->i_consecutive_errors++;
+
p_vlm->input_state_changed = true;
vlc_cond_signal( &p_vlm->wait_manage );
vlc_mutex_unlock( &p_vlm->lock_manage );
@@ -145,6 +152,10 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
}
vlc_mutex_init( &p_vlm->lock );
+
+ vlc_mutex_init( &p_vlm->lock_delete );
+ vlc_cond_init( &p_vlm->wait_delete );
+
vlc_mutex_init( &p_vlm->lock_manage );
vlc_cond_init_daytime( &p_vlm->wait_manage );
p_vlm->users = 1;
@@ -153,13 +164,16 @@ vlm_t *vlm_New ( vlc_object_t *p_this )
TAB_INIT( p_vlm->i_media, p_vlm->media );
TAB_INIT( p_vlm->i_schedule, p_vlm->schedule );
p_vlm->p_vod = NULL;
+ p_vlm->i_consecutive_errors = 0;
var_Create( p_vlm, "intf-event", VLC_VAR_ADDRESS );
if( vlc_clone( &p_vlm->thread, Manage, p_vlm, VLC_THREAD_PRIORITY_LOW ) )
{
+ vlc_cond_destroy( &p_vlm->wait_delete );
vlc_cond_destroy( &p_vlm->wait_manage );
vlc_mutex_destroy( &p_vlm->lock );
vlc_mutex_destroy( &p_vlm->lock_manage );
+ vlc_mutex_destroy( &p_vlm->lock_delete );
vlc_object_release( p_vlm );
vlc_mutex_unlock( &vlm_mutex );
return NULL;
@@ -212,6 +226,8 @@ void vlm_Delete( vlm_t *p_vlm )
return;
}
+ vlc_cond_signal(&p_vlm->wait_delete);
+
/* Destroy and release VLM */
vlc_mutex_lock( &p_vlm->lock );
vlm_ControlInternal( p_vlm, VLM_CLEAR_MEDIAS );
@@ -234,9 +250,11 @@ void vlm_Delete( vlm_t *p_vlm )
vlc_join( p_vlm->thread, NULL );
+ vlc_cond_destroy( &p_vlm->wait_delete );
vlc_cond_destroy( &p_vlm->wait_manage );
vlc_mutex_destroy( &p_vlm->lock );
vlc_mutex_destroy( &p_vlm->lock_manage );
+ vlc_mutex_destroy( &p_vlm->lock_delete );
vlc_object_release( p_vlm );
}
@@ -1007,6 +1025,18 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *
{
var_AddCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
+ if (p_vlm->i_consecutive_errors)
+ {
+ int slowdown = 1 << (p_vlm->i_consecutive_errors - 1);
+ /* 100ms, 200ms, 400ms, 800ms, 1.6s, 3.2s */
+ mtime_t deadline = mdate() + slowdown * 100000L; /* usecs */
+
+ /* like a sleep, but interrupted on deletion */
+ vlc_mutex_lock(&p_vlm->lock_delete);
+ vlc_cond_timedwait(&p_vlm->wait_delete, &p_vlm->lock_delete, deadline);
+ vlc_mutex_unlock(&p_vlm->lock_delete);
+ }
+
if( input_Start( p_instance->p_input ) != VLC_SUCCESS )
{
var_DelCallback( p_instance->p_input, "intf-event", InputEvent, p_media );
diff --git a/src/input/vlm_internal.h b/src/input/vlm_internal.h
index d5a6905291..8c2a25b0b0 100644
--- a/src/input/vlm_internal.h
+++ b/src/input/vlm_internal.h
@@ -86,6 +86,11 @@ struct vlm_t
VLC_COMMON_MEMBERS
vlc_mutex_t lock;
+
+ /* a separate mutex is needed: "lock" must remain locked while waiting */
+ vlc_mutex_t lock_delete;
+ vlc_cond_t wait_delete;
+
vlc_thread_t thread;
vlc_mutex_t lock_manage;
vlc_cond_t wait_manage;
@@ -106,6 +111,8 @@ struct vlm_t
/* Schedule list */
int i_schedule;
vlm_schedule_sys_t **schedule;
+
+ unsigned i_consecutive_errors;
};
int vlm_ControlInternal( vlm_t *p_vlm, int i_query, ... );
--
2.20.1
More information about the vlc-devel
mailing list