X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Finput%2Fvlm.c;h=23e6004346bdba3c27e9d1caa73a5b1782ae9acd;hb=97513e3145fe31f2fee94378888a59329ebe6fe2;hp=a9202b714eb87edeed339698d42ba5173ccf0c27;hpb=9b372ac695c839d5058d52be3860a870b69688c5;p=vlc diff --git a/src/input/vlm.c b/src/input/vlm.c index a9202b714e..23e6004346 100644 --- a/src/input/vlm.c +++ b/src/input/vlm.c @@ -38,21 +38,23 @@ #include -#ifdef ENABLE_VLM - #ifndef WIN32 # include /* gettimeofday() */ #endif +#ifdef UNDER_CE +#include /* gettimeofday() */ +#endif + #ifdef HAVE_TIME_H # include /* ctime() */ # include /* ftime() */ #endif #include -#include "input_internal.h" #include #include "vlm_internal.h" +#include "vlm_event.h" #include #include #include @@ -64,7 +66,7 @@ *****************************************************************************/ static void vlm_Destructor( vlm_t *p_vlm ); -static int Manage( vlc_object_t * ); +static void* Manage( void * ); static int vlm_MediaVodControl( void *, vod_media_t *, const char *, int, va_list ); /***************************************************************************** @@ -87,7 +89,7 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) p_vlm = *pp_vlm; if( p_vlm ) { /* VLM already exists */ - vlc_object_yield( p_vlm ); + vlc_object_hold( p_vlm ); vlc_mutex_unlock( lockval.p_address ); return p_vlm; } @@ -108,10 +110,10 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) TAB_INIT( p_vlm->i_schedule, p_vlm->schedule ); p_vlm->i_vod = 0; p_vlm->p_vod = NULL; + var_Create( p_vlm, "intf-event", VLC_VAR_ADDRESS ); vlc_object_attach( p_vlm, p_this->p_libvlc ); - if( vlc_thread_create( p_vlm, "vlm thread", - Manage, VLC_THREAD_PRIORITY_LOW, false ) ) + if( vlc_clone( &p_vlm->thread, Manage, p_vlm, VLC_THREAD_PRIORITY_LOW ) ) { vlc_mutex_destroy( &p_vlm->lock ); vlc_object_release( p_vlm ); @@ -126,19 +128,17 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) char *psz_buffer = NULL; msg_Dbg( p_this, "loading VLM configuration" ); - if( asprintf(&psz_buffer, "load %s", psz_vlmconf ) == -1 ) - psz_buffer = NULL; - if( psz_buffer ) + if( asprintf(&psz_buffer, "load %s", psz_vlmconf ) != -1 ) { - msg_Dbg( p_this, psz_buffer ); + msg_Dbg( p_this, "%s", psz_buffer ); if( vlm_ExecuteCommand( p_vlm, psz_buffer, &p_message ) ) msg_Warn( p_this, "error while loading the configuration file" ); - vlm_MessageDelete(p_message); - free(psz_buffer); + vlm_MessageDelete( p_message ); + free( psz_buffer ); } } - free(psz_vlmconf); + free( psz_vlmconf ); vlc_object_set_destructor( p_vlm, (vlc_destructor_t)vlm_Destructor ); *pp_vlm = p_vlm; /* for future reference */ @@ -176,6 +176,9 @@ static void vlm_Destructor( vlm_t *p_vlm ) vlm_ControlInternal( p_vlm, VLM_CLEAR_SCHEDULES ); TAB_CLEAN( p_vlm->schedule, p_vlm->schedule ); + vlc_object_kill( p_vlm ); + /*vlc_cancel( p_vlm->thread ); */ + vlc_join( p_vlm->thread, NULL ); vlc_mutex_destroy( &p_vlm->lock ); } @@ -197,7 +200,7 @@ int vlm_ExecuteCommand( vlm_t *p_vlm, const char *psz_command, int64_t vlm_Date(void) { -#ifdef WIN32 +#if defined (WIN32) && !defined (UNDER_CE) struct timeb tm; ftime( &tm ); return ((int64_t)tm.time) * 1000000 + ((int64_t)tm.millitm) * 1000; @@ -304,13 +307,14 @@ static int vlm_MediaVodControl( void *p_private, vod_media_t *p_vod_media, /***************************************************************************** * Manage: *****************************************************************************/ -static int Manage( vlc_object_t* p_object ) +static void* Manage( void* p_object ) { vlm_t *vlm = (vlm_t*)p_object; int i, j; mtime_t i_lastcheck; mtime_t i_time; + int canc = vlc_savecancel (); i_lastcheck = vlm_Date(); while( !vlm->b_die ) @@ -414,7 +418,8 @@ static int Manage( vlc_object_t* p_object ) msleep( 100000 ); } - return VLC_SUCCESS; + vlc_restorecancel (canc); + return NULL; } /* New API @@ -501,32 +506,40 @@ static int vlm_OnMediaUpdate( vlm_t *p_vlm, vlm_media_sys_t *p_media ) int i; vlc_gc_decref( p_media->vod.p_item ); - p_media->vod.p_item = input_ItemNew( p_vlm, p_cfg->ppsz_input[0], + p_media->vod.p_item = input_item_New( p_vlm, p_cfg->ppsz_input[0], p_cfg->psz_name ); if( p_cfg->psz_output ) - asprintf( &psz_output, "%s:description", p_cfg->psz_output ); + { + if( asprintf( &psz_output, "%s:description", p_cfg->psz_output ) == -1 ) + psz_output = NULL; + } else - asprintf( &psz_output, "#description" ); + psz_output = strdup( "#description" ); + + if( psz_output && asprintf( &psz_dup, "sout=%s", psz_output ) != -1 ) + { + input_item_AddOption( p_media->vod.p_item, psz_dup, VLC_INPUT_OPTION_TRUSTED ); + free( psz_dup ); + } + free( psz_output ); - asprintf( &psz_dup, "sout=%s", psz_output); - input_ItemAddOption( p_media->vod.p_item, psz_dup ); - free( psz_dup ); for( i = 0; i < p_cfg->i_option; i++ ) - input_ItemAddOption( p_media->vod.p_item, - p_cfg->ppsz_option[i] ); + input_item_AddOption( p_media->vod.p_item, + p_cfg->ppsz_option[i], VLC_INPUT_OPTION_TRUSTED ); - asprintf( &psz_header, _("Media: %s"), p_cfg->psz_name ); + if( asprintf( &psz_header, _("Media: %s"), p_cfg->psz_name ) == -1 ) + psz_header = NULL; if( (p_input = input_CreateThreadExtended( p_vlm, p_media->vod.p_item, psz_header, NULL ) ) ) { while( !p_input->b_eof && !p_input->b_error ) msleep( 100000 ); - input_StopThread( p_input ); + input_StopThread( p_input, false ); + vlc_thread_join( p_input ); vlc_object_release( p_input ); } - free( psz_output ); free( psz_header ); if( p_cfg->vod.psz_mux ) @@ -562,6 +575,7 @@ static int vlm_OnMediaUpdate( vlm_t *p_vlm, vlm_media_sys_t *p_media ) /* TODO add support of var vlm_media_broadcast/vlm_media_vod */ + vlm_SendEventMediaChanged( p_vlm, p_cfg->id ); return VLC_SUCCESS; } static int vlm_ControlMediaChange( vlm_t *p_vlm, vlm_media_t *p_cfg ) @@ -600,13 +614,13 @@ static int vlm_ControlMediaAdd( vlm_t *p_vlm, vlm_media_t *p_cfg, int64_t *p_id p_vlm->p_vod = vlc_custom_create( VLC_OBJECT(p_vlm), sizeof( vod_t ), VLC_OBJECT_GENERIC, "vod server" ); vlc_object_attach( p_vlm->p_vod, p_vlm ); - p_vlm->p_vod->p_module = module_Need( p_vlm->p_vod, "vod server", 0, 0 ); + p_vlm->p_vod->p_module = module_need( p_vlm->p_vod, "vod server", NULL, false ); if( !p_vlm->p_vod->p_module ) { msg_Err( p_vlm, "cannot find vod server" ); vlc_object_detach( p_vlm->p_vod ); vlc_object_release( p_vlm->p_vod ); - p_vlm->p_vod = 0; + p_vlm->p_vod = NULL; return VLC_EGENERIC; } @@ -614,13 +628,9 @@ static int vlm_ControlMediaAdd( vlm_t *p_vlm, vlm_media_t *p_cfg, int64_t *p_id p_vlm->p_vod->pf_media_control = vlm_MediaVodControl; } - p_media = malloc( sizeof( vlm_media_sys_t ) ); + p_media = calloc( 1, sizeof( vlm_media_sys_t ) ); if( !p_media ) - { - msg_Err( p_vlm, "out of memory" ); return VLC_ENOMEM; - } - memset( p_media, 0, sizeof(vlm_media_sys_t) ); if( p_cfg->b_vod ) p_vlm->i_vod++; @@ -629,7 +639,7 @@ static int vlm_ControlMediaAdd( vlm_t *p_vlm, vlm_media_t *p_cfg, int64_t *p_id p_media->cfg.id = p_vlm->i_id++; /* FIXME do we do something here if enabled is true ? */ - p_media->vod.p_item = input_ItemNew( p_vlm, NULL, NULL ); + p_media->vod.p_item = input_item_New( p_vlm, NULL, NULL ); p_media->vod.p_media = NULL; TAB_INIT( p_media->i_instance, p_media->instance ); @@ -640,6 +650,8 @@ static int vlm_ControlMediaAdd( vlm_t *p_vlm, vlm_media_t *p_cfg, int64_t *p_id if( p_id ) *p_id = p_media->cfg.id; + /* */ + vlm_SendEventMediaAdded( p_vlm, p_media->cfg.id ); return vlm_OnMediaUpdate( p_vlm, p_media ); } @@ -671,11 +683,14 @@ static int vlm_ControlMediaDel( vlm_t *p_vlm, int64_t id ) /* Check if we need to unload the VOD server */ if( p_vlm->p_vod && p_vlm->i_vod <= 0 ) { - module_Unneed( p_vlm->p_vod, p_vlm->p_vod->p_module ); + module_unneed( p_vlm->p_vod, p_vlm->p_vod->p_module ); vlc_object_detach( p_vlm->p_vod ); vlc_object_release( p_vlm->p_vod ); p_vlm->p_vod = NULL; } + + /* */ + vlm_SendEventMediaRemoved( p_vlm, id ); return VLC_SUCCESS; } @@ -738,35 +753,42 @@ static vlm_media_instance_sys_t *vlm_ControlMediaInstanceGetByName( vlm_media_sy } static vlm_media_instance_sys_t *vlm_MediaInstanceNew( vlm_t *p_vlm, const char *psz_name ) { - vlm_media_instance_sys_t *p_instance = malloc( sizeof(vlm_media_instance_sys_t) ); + vlm_media_instance_sys_t *p_instance = calloc( 1, sizeof(vlm_media_instance_sys_t) ); if( !p_instance ) return NULL; - memset( p_instance, 0, sizeof(vlm_media_instance_sys_t) ); - p_instance->psz_name = NULL; if( psz_name ) p_instance->psz_name = strdup( psz_name ); - p_instance->p_item = input_ItemNew( p_vlm, NULL, NULL ); + p_instance->p_item = input_item_New( p_vlm, NULL, NULL ); p_instance->i_index = 0; p_instance->b_sout_keep = false; p_instance->p_input = NULL; - p_instance->p_sout = NULL; + p_instance->p_input_resource = NULL; return p_instance; } -static void vlm_MediaInstanceDelete( vlm_media_instance_sys_t *p_instance ) +static void vlm_MediaInstanceDelete( vlm_t *p_vlm, int64_t id, vlm_media_instance_sys_t *p_instance ) { - if( p_instance->p_input ) + input_thread_t *p_input = p_instance->p_input; + if( p_input ) { - input_StopThread( p_instance->p_input ); - p_instance->p_sout = input_DetachSout( p_instance->p_input ); - vlc_object_release( p_instance->p_input ); + input_resource_t *p_resource; + + input_StopThread( p_input, true ); + vlc_thread_join( p_input ); + + p_resource = input_DetachResource( p_input ); + input_resource_Delete( p_resource ); + + vlc_object_release( p_input ); + + vlm_SendEventMediaInstanceStopped( p_vlm, id ); } - if( p_instance->p_sout ) - sout_DeleteInstance( p_instance->p_sout ); + if( p_instance->p_input_resource ) + input_resource_Delete( p_instance->p_input_resource ); vlc_gc_decref( p_instance->p_item ); free( p_instance->psz_name ); @@ -804,12 +826,14 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * if( p_cfg->psz_output != NULL || psz_vod_output != NULL ) { char *psz_buffer; - asprintf( &psz_buffer, "sout=%s%s%s", + if( asprintf( &psz_buffer, "sout=%s%s%s", p_cfg->psz_output ? p_cfg->psz_output : "", (p_cfg->psz_output && psz_vod_output) ? ":" : psz_vod_output ? "#" : "", - psz_vod_output ? psz_vod_output : "" ); - input_ItemAddOption( p_instance->p_item, psz_buffer ); - free( psz_buffer ); + psz_vod_output ? psz_vod_output : "" ) != -1 ) + { + input_item_AddOption( p_instance->p_item, psz_buffer, VLC_INPUT_OPTION_TRUSTED ); + free( psz_buffer ); + } } for( i = 0; i < p_cfg->i_option; i++ ) @@ -819,44 +843,58 @@ static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char * else if( !strcmp( p_cfg->ppsz_option[i], "nosout-keep" ) || !strcmp( p_cfg->ppsz_option[i], "no-sout-keep" ) ) p_instance->b_sout_keep = false; else - input_ItemAddOption( p_instance->p_item, p_cfg->ppsz_option[i] ); + input_item_AddOption( p_instance->p_item, p_cfg->ppsz_option[i], VLC_INPUT_OPTION_TRUSTED ); } TAB_APPEND( p_media->i_instance, p_media->instance, p_instance ); } /* Stop old instance */ - if( p_instance->p_input ) + input_thread_t *p_input = p_instance->p_input; + if( p_input ) { if( p_instance->i_index == i_input_index && - !p_instance->p_input->b_eof && !p_instance->p_input->b_error ) + !p_input->b_eof && !p_input->b_error ) { - if( var_GetInteger( p_instance->p_input, "state" ) == PAUSE_S ) - var_SetInteger( p_instance->p_input, "state", PLAYING_S ); + if( var_GetInteger( p_input, "state" ) == PAUSE_S ) + var_SetInteger( p_input, "state", PLAYING_S ); return VLC_SUCCESS; } - input_StopThread( p_instance->p_input ); - p_instance->p_sout = input_DetachSout( p_instance->p_input ); - vlc_object_release( p_instance->p_input ); - if( !p_instance->b_sout_keep && p_instance->p_sout ) - { - sout_DeleteInstance( p_instance->p_sout ); - p_instance->p_sout = NULL; - } + input_StopThread( p_input, !p_input->b_eof && !p_input->b_error ); + vlc_thread_join( p_input ); + + p_instance->p_input_resource = input_DetachResource( p_input ); + + vlc_object_release( p_input ); + + if( !p_instance->b_sout_keep ) + input_resource_TerminateSout( p_instance->p_input_resource ); + input_resource_TerminateVout( p_instance->p_input_resource ); + + vlm_SendEventMediaInstanceStopped( p_vlm, id ); } /* Start new one */ p_instance->i_index = i_input_index; input_item_SetURI( p_instance->p_item, p_media->cfg.ppsz_input[p_instance->i_index] ) ; - asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ); - p_instance->p_input = input_CreateThreadExtended( p_vlm, p_instance->p_item, psz_log, p_instance->p_sout ); - if( !p_instance->p_input ) + if( asprintf( &psz_log, _("Media: %s"), p_media->cfg.psz_name ) != -1 ) { - TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance ); - vlm_MediaInstanceDelete( p_instance ); + p_instance->p_input = input_CreateThreadExtended( p_vlm, p_instance->p_item, + psz_log, p_instance->p_input_resource ); + p_instance->p_input_resource = NULL; + + if( !p_instance->p_input ) + { + TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance ); + vlm_MediaInstanceDelete( p_vlm, id, p_instance ); + } + else + { + vlm_SendEventMediaInstanceStarted( p_vlm, id ); + } + free( psz_log ); } - free( psz_log ); return VLC_SUCCESS; } @@ -875,7 +913,7 @@ static int vlm_ControlMediaInstanceStop( vlm_t *p_vlm, int64_t id, const char *p TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance ); - vlm_MediaInstanceDelete( p_instance ); + vlm_MediaInstanceDelete( p_vlm, id, p_instance ); return VLC_SUCCESS; } @@ -1142,47 +1180,3 @@ int vlm_Control( vlm_t *p_vlm, int i_query, ... ) return i_result; } -#else /* ENABLE_VLM */ - -/* We just define an empty wrapper */ -vlm_t *__vlm_New( vlc_object_t *a ) -{ - msg_Err( a, "VideoLAN manager support is disabled" ); - return NULL; -} - -void vlm_Delete( vlm_t *a ) -{ - (void)a; -} - -int vlm_ExecuteCommand( vlm_t *a, const char *b, vlm_message_t **c ) -{ - abort(); -} - -vlm_message_t *vlm_MessageNew( const char *psz_name, - const char *psz_format, ... ) -{ - (void)psz_name; (void)psz_format; - return NULL; -} - -vlm_message_t *vlm_MessageAdd( vlm_message_t *p_message, - vlm_message_t *p_child ) -{ - abort(); -} - -void vlm_MessageDelete( vlm_message_t *a ) -{ - (void)a; -} - -int vlm_Control( vlm_t *p_vlm, int i_query, ... ) -{ - (void)p_vlm; (void)i_query; - return VLC_EGENERIC; -} - -#endif /* ENABLE_VLM */