X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fvlm.c;h=6a517d53c1ce918e1a01cda506d8d3032b978fe8;hb=3267066db2af32d3d5838d9575ae8c6a189b8333;hp=7119ec4f66ea1650980568a2ed3b39374a005341;hpb=1856ddb7cf42f53773c4f86f040de10e5529d357;p=vlc diff --git a/src/misc/vlm.c b/src/misc/vlm.c index 7119ec4f66..6a517d53c1 100644 --- a/src/misc/vlm.c +++ b/src/misc/vlm.c @@ -26,11 +26,12 @@ /***************************************************************************** * Preamble *****************************************************************************/ +#include + +#include #include /* malloc(), free() */ #include /* tolower() */ -#include - #ifdef ENABLE_VLM #include @@ -41,11 +42,9 @@ # include /* ftime() */ #endif -#include "vlc_vlm.h" -#include "vlc_vod.h" - -#define FREE( p ) \ - if( p ) { free( p ); (p) = NULL; } +#include +#include +#include /***************************************************************************** * Local prototypes. @@ -53,7 +52,6 @@ static vlm_message_t *vlm_Show( vlm_t *, vlm_media_t *, vlm_schedule_t *, char * ); static vlm_message_t *vlm_Help( vlm_t *, char * ); -static vlm_media_t *vlm_MediaSearch ( vlm_t *, const char * ); static vlm_media_instance_t *vlm_MediaInstanceSearch( vlm_t *, vlm_media_t *, const char * ); static vlm_message_t *vlm_MessageNew( char *, const char *, ... ); @@ -76,20 +74,20 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) char *psz_vlmconf; /* to be sure to avoid multiple creation */ - var_Create( p_this->p_libvlc, "vlm_mutex", VLC_VAR_MUTEX ); - var_Get( p_this->p_libvlc, "vlm_mutex", &lockval ); + var_Create( p_this->p_libvlc_global, "vlm_mutex", VLC_VAR_MUTEX ); + var_Get( p_this->p_libvlc_global, "vlm_mutex", &lockval ); vlc_mutex_lock( lockval.p_address ); if( !(p_vlm = vlc_object_find( p_this, VLC_OBJECT_VLM, FIND_ANYWHERE )) ) { - msg_Info( p_this, "creating vlm" ); + msg_Info( p_this, "creating VLM" ); if( ( p_vlm = vlc_object_create( p_this, VLC_OBJECT_VLM ) ) == NULL ) { vlc_mutex_unlock( lockval.p_address ); return NULL; } - vlc_mutex_init( p_this->p_vlc, &p_vlm->lock ); + vlc_mutex_init( p_this->p_libvlc, &p_vlm->lock ); p_vlm->i_media = 0; p_vlm->media = NULL; p_vlm->i_vod = 0; @@ -97,7 +95,7 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) p_vlm->schedule = NULL; vlc_object_yield( p_vlm ); - vlc_object_attach( p_vlm, p_this->p_vlc ); + vlc_object_attach( p_vlm, p_this->p_libvlc ); } vlc_mutex_unlock( lockval.p_address ); @@ -117,15 +115,15 @@ vlm_t *__vlm_New ( vlc_object_t *p_this ) vlm_message_t *p_message = NULL; char *psz_buffer = NULL; - msg_Dbg( p_this, "loading vlm conf ..." ); + msg_Dbg( p_this, "loading VLM configuration" ); asprintf(&psz_buffer, "load %s", psz_vlmconf ); if( psz_buffer ) { msg_Dbg( p_this, psz_buffer); if( vlm_ExecuteCommand( p_vlm, psz_buffer, &p_message ) ){ - msg_Warn( p_this, "error while loading the vlm conf file" ); + msg_Warn( p_this, "error while loading the configuration file" ); } - free(p_message); + vlm_MessageDelete(p_message); free(psz_buffer); } } @@ -141,7 +139,7 @@ void vlm_Delete( vlm_t *p_vlm ) { vlc_value_t lockval; - var_Get( p_vlm->p_libvlc, "vlm_mutex", &lockval ); + var_Get( p_vlm->p_libvlc_global, "vlm_mutex", &lockval ); vlc_mutex_lock( lockval.p_address ); vlc_object_release( p_vlm ); @@ -158,11 +156,11 @@ void vlm_Delete( vlm_t *p_vlm ) vlc_mutex_destroy( &p_vlm->lock ); while( p_vlm->i_media ) vlm_MediaDelete( p_vlm, p_vlm->media[0], NULL ); - FREE( p_vlm->media ); + FREENULL( p_vlm->media ); while( p_vlm->i_schedule ) vlm_ScheduleDelete( p_vlm, p_vlm->schedule[0], NULL ); - FREE( p_vlm->schedule ); + FREENULL( p_vlm->schedule ); vlc_object_detach( p_vlm ); vlc_object_destroy( p_vlm ); @@ -194,7 +192,7 @@ int vlm_Save( vlm_t *p_vlm, const char *psz_file ) if( !p_vlm || !psz_file ) return 1; - file = fopen( psz_file, "wt" ); + file = utf8_fopen( psz_file, "wt" ); if( file == NULL ) return 1; psz_save = Save( p_vlm ); @@ -215,40 +213,42 @@ int vlm_Save( vlm_t *p_vlm, const char *psz_file ) *****************************************************************************/ int vlm_Load( vlm_t *p_vlm, const char *psz_file ) { - FILE *file; + stream_t *p_stream; int64_t i_size; char *psz_buffer; if( !p_vlm || !psz_file ) return 1; - file = fopen( psz_file, "r" ); - if( file == NULL ) return 1; + p_stream = stream_UrlNew( p_vlm, psz_file ); + if( p_stream == NULL ) return 1; - if( fseek( file, 0, SEEK_END) != 0 ) + if( stream_Seek( p_stream, 0 ) != 0 ) { - fclose( file ); + stream_Delete( p_stream ); return 2; } - i_size = ftell( file ); - fseek( file, 0, SEEK_SET ); + i_size = stream_Size( p_stream ); + psz_buffer = malloc( i_size + 1 ); if( !psz_buffer ) { - fclose( file ); + stream_Delete( p_stream ); return 2; } - fread( psz_buffer, 1, i_size, file ); + + stream_Read( p_stream, psz_buffer, i_size ); psz_buffer[ i_size ] = '\0'; + + stream_Delete( p_stream ); + if( Load( p_vlm, psz_buffer ) ) { - fclose( file ); free( psz_buffer ); return 3; } free( psz_buffer ); - fclose( file ); return 0; } @@ -258,19 +258,24 @@ int vlm_Load( vlm_t *p_vlm, const char *psz_file ) *****************************************************************************/ static const char *FindEndCommand( const char *psz_sent ) { + vlc_bool_t b_escape = VLC_FALSE; + switch( *psz_sent ) { case '\"': psz_sent++; - - while( ( *psz_sent != '\"' ) && ( *psz_sent != '\0' ) ) + while( ( *psz_sent != '\"' || b_escape == VLC_TRUE ) + && ( *psz_sent != '\0' ) ) { - if( *psz_sent == '\'' ) + if( *psz_sent == '\'' && b_escape == VLC_FALSE ) { psz_sent = FindEndCommand( psz_sent ); if( psz_sent == NULL ) return NULL; } - else psz_sent++; + else if( *psz_sent++ == '\\' && b_escape == VLC_FALSE ) + b_escape = VLC_TRUE; + else + b_escape = VLC_FALSE; } if( *psz_sent == '\"' ) @@ -286,15 +291,18 @@ static const char *FindEndCommand( const char *psz_sent ) case '\'': psz_sent++; - - while( ( *psz_sent != '\'' ) && ( *psz_sent != '\0' ) ) + while( ( *psz_sent != '\'' || b_escape == VLC_TRUE ) + && ( *psz_sent != '\0' ) ) { - if( *psz_sent == '\"' ) + if( *psz_sent == '\"' && b_escape == VLC_FALSE ) { psz_sent = FindEndCommand( psz_sent ); if( psz_sent == NULL ) return NULL; } - else psz_sent++; + else if( *psz_sent++ == '\\' && b_escape == VLC_FALSE ) + b_escape = VLC_TRUE; + else + b_escape = VLC_FALSE; } if( *psz_sent == '\'' ) @@ -311,12 +319,17 @@ static const char *FindEndCommand( const char *psz_sent ) default: /* now we can look for spaces */ while( ( *psz_sent != ' ' ) && ( *psz_sent != '\0' ) ) { - if( ( *psz_sent == '\'' ) || ( *psz_sent == '\"' ) ) + if( ( ( *psz_sent == '\'' ) || ( *psz_sent == '\"' ) ) + && b_escape == VLC_FALSE ) { psz_sent = FindEndCommand( psz_sent ); if( psz_sent == NULL ) return NULL; } - else psz_sent++; + else if( *psz_sent++ == '\\' && b_escape == VLC_FALSE ) + b_escape = VLC_TRUE; + else + b_escape = VLC_FALSE; + } return psz_sent; @@ -348,6 +361,9 @@ static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, else { const char *psz_temp; + const char *psz_buf; + char *psz_dst; + vlc_bool_t b_escape = VLC_FALSE; int i_temp; /* support for comments */ @@ -370,8 +386,23 @@ static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, ppsz_command = realloc( ppsz_command, (i_command + 1) * sizeof(char*) ); ppsz_command[ i_command ] = malloc( (i_temp + 1) * sizeof(char) ); - strncpy( ppsz_command[ i_command ], psz_cmd, i_temp ); - ppsz_command[ i_command ][ i_temp ] = '\0'; + + /* unescape ", ' and \ ... and everything else */ + psz_buf = psz_cmd; + psz_dst = ppsz_command[ i_command ]; + while( i_temp-- ) + { + if( *psz_buf == '\\' && b_escape == VLC_FALSE ) + b_escape = VLC_TRUE; + else + { + b_escape = VLC_FALSE; + *psz_dst = *psz_buf; + psz_dst++; + } + psz_buf++; + } + *psz_dst = '\0'; i_command++; @@ -617,6 +648,18 @@ static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, } } + else if( !strcmp(ppsz_command[0], "export" ) ) + { + char *psz_buf; + + if( i_command != 1 ) goto syntax_error; + + p_message = vlm_MessageNew( "export", psz_buf = Save( p_vlm ) ); + free( psz_buf ); + + goto success; + } + else if( !strcmp(ppsz_command[0], "load") ) { if( i_command != 2 ) goto syntax_error; @@ -627,11 +670,11 @@ static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, p_message = vlm_MessageNew( "load", NULL ); goto success; case 2: - p_message = vlm_MessageNew( "load", "read file error" ); + p_message = vlm_MessageNew( "load", "Read file error" ); goto error; case 3: p_message = - vlm_MessageNew( "load", "error while loading file" ); + vlm_MessageNew( "load", "Error while loading file" ); goto error; default: p_message = @@ -759,7 +802,7 @@ static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, } else { - if( i + 1 >= i_command && + if( ( (i + 1) >= i_command ) && !strcmp(ppsz_command[0], "new") ) { vlm_MediaDelete( p_vlm, p_media, NULL ); @@ -768,7 +811,7 @@ static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, "Wrong properties syntax" ); goto error; } - else if( i + 1 >= i_command ) + else if( (i + 1) >= i_command ) { p_message = vlm_MessageNew( ppsz_command[0], @@ -788,8 +831,8 @@ static int ExecuteCommand( vlm_t *p_vlm, const char *psz_command, } success: - for( i = 0 ; i < i_command ; i++ ) FREE( ppsz_command[i] ); - FREE( ppsz_command ); + for( i = 0 ; i < i_command ; i++ ) FREENULL( ppsz_command[i] ); + FREENULL( ppsz_command ); *pp_message = p_message; return VLC_SUCCESS; @@ -798,14 +841,14 @@ syntax_error: p_message = vlm_MessageNew( ppsz_command[0], "Wrong command syntax" ); error: - for( i = 0 ; i < i_command ; i++ ) FREE( ppsz_command[i] ); - FREE( ppsz_command ); + for( i = 0 ; i < i_command ; i++ ) FREENULL( ppsz_command[i] ); + FREENULL( ppsz_command ); *pp_message = p_message; return VLC_EGENERIC; } -static vlm_media_t *vlm_MediaSearch( vlm_t *vlm, const char *psz_name ) +vlm_media_t *vlm_MediaSearch( vlm_t *vlm, const char *psz_name ) { int i; @@ -889,8 +932,7 @@ vlm_media_t *vlm_MediaNew( vlm_t *vlm, const char *psz_name, int i_type ) media->i_instance = 0; media->instance = NULL; - media->item.psz_uri = strdup( psz_name ); - vlc_input_item_Init( VLC_OBJECT(vlm), &media->item ); + input_ItemInit( VLC_OBJECT(vlm), &media->item ); TAB_APPEND( vlm->i_media, vlm->media, media ); @@ -938,7 +980,7 @@ void vlm_MediaDelete( vlm_t *vlm, vlm_media_t *media, const char *psz_name ) while( media->i_option-- ) free( media->option[media->i_option] ); if( media->option ) free( media->option ); - vlc_input_item_Clean( &media->item ); + input_ItemClean( &media->item ); free( media ); } @@ -1071,8 +1113,8 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd, char *psz_header; int i; - vlc_input_item_Clean( &media->item ); - vlc_input_item_Init( VLC_OBJECT(vlm), &media->item ); + input_ItemClean( &media->item ); + input_ItemInit( VLC_OBJECT(vlm), &media->item ); if( media->psz_output ) asprintf( &psz_output, "%s:description", media->psz_output ); @@ -1106,6 +1148,7 @@ int vlm_MediaSetup( vlm_t *vlm, vlm_media_t *media, const char *psz_cmd, vlc_object_destroy( p_input ); } free( psz_output ); + free( psz_header ); if( media->psz_mux ) { @@ -1154,10 +1197,10 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, p_instance = malloc( sizeof(vlm_media_instance_t) ); if( !p_instance ) return VLC_EGENERIC; memset( p_instance, 0, sizeof(vlm_media_instance_t) ); - vlc_input_item_Init( VLC_OBJECT(vlm), &p_instance->item ); + input_ItemInit( VLC_OBJECT(vlm), &p_instance->item ); p_instance->p_input = NULL; - if( media->psz_output != NULL || media->psz_vod_output != NULL ) + if( ( media->psz_output != NULL ) || ( media->psz_vod_output != NULL ) ) { p_instance->item.ppsz_options = malloc( sizeof( char* ) ); asprintf( &p_instance->item.ppsz_options[0], "sout=%s%s%s", @@ -1182,7 +1225,7 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, TAB_APPEND( media->i_instance, media->instance, p_instance ); } - if( psz_args && sscanf(psz_args, "%d", &i) == 1 && i < media->i_input ) + if( ( psz_args && sscanf(psz_args, "%d", &i) == 1 ) && ( i < media->i_input ) ) { p_instance->i_index = i; } @@ -1205,9 +1248,10 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, if( !p_instance->p_input ) { TAB_REMOVE( media->i_instance, media->instance, p_instance ); - vlc_input_item_Clean( &p_instance->item ); + input_ItemClean( &p_instance->item ); if( p_instance->psz_name ) free( p_instance->psz_name ); } + free( psz_header ); return VLC_SUCCESS; } @@ -1219,9 +1263,47 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, vlc_value_t val; float f_percentage; - if( psz_args && sscanf( psz_args, "%f", &f_percentage ) == 1 ) + if( psz_args ) { - val.f_float = f_percentage / 100.0 ; + f_percentage = i18n_atof( psz_args ); + if( f_percentage >= 0.0 && f_percentage <= 100.0 ) + { + val.f_float = f_percentage / 100.0 ; + var_Set( p_instance->p_input, "position", val ); + return VLC_SUCCESS; + } + } + } + else if( !strcmp( psz_command, "rewind" ) ) + { + float f_pos; + float f_scale; + vlc_value_t val; + + if( psz_args ) + { + f_scale = i18n_atof( psz_args ); + f_pos = var_GetFloat( p_instance->p_input, "position" ); + val.f_float = f_pos - (f_scale / 1000.0); + if( val.f_float < 0.0 ) + val.f_float = 0.0; + var_Set( p_instance->p_input, "position", val ); + return VLC_SUCCESS; + } + } + else if( !strcmp( psz_command, "forward" ) ) + { + float f_pos; + float f_scale; + vlc_value_t val; + + if( psz_args ) + { + f_scale = i18n_atof( psz_args ); + f_pos = var_GetFloat( p_instance->p_input, "position" ); + val.f_float = f_pos + (f_scale / 1000.0); + if( val.f_float > 1.0 ) + val.f_float = 1.0; var_Set( p_instance->p_input, "position", val ); return VLC_SUCCESS; } @@ -1238,7 +1320,7 @@ int vlm_MediaControl( vlm_t *vlm, vlm_media_t *media, const char *psz_id, vlc_object_destroy( p_instance->p_input ); } - vlc_input_item_Clean( &p_instance->item ); + input_ItemClean( &p_instance->item ); if( p_instance->psz_name ) free( p_instance->psz_name ); free( p_instance ); @@ -1313,7 +1395,12 @@ void vlm_ScheduleDelete( vlm_t *vlm, vlm_schedule_t *sched, if( vlm->i_schedule == 0 && vlm->schedule ) free( vlm->schedule ); free( sched->psz_name ); - while( sched->i_command-- ) free( sched->command[sched->i_command] ); + while( sched->i_command ) + { + char *psz_cmd = sched->command[0]; + TAB_REMOVE( sched->i_command, sched->command, psz_cmd ); + free( psz_cmd ); + } free( sched ); } @@ -1368,7 +1455,9 @@ int vlm_ScheduleSetup( vlm_schedule_t *schedule, const char *psz_cmd, { schedule->i_date = 0; } - else if( p == NULL && sscanf( psz_value, "%d:%d:%d", &time.tm_hour, &time.tm_min, &time.tm_sec ) != 3 ) /* it must be a hour:minutes:seconds */ + else if( (p == NULL) && sscanf( psz_value, "%d:%d:%d", &time.tm_hour, + &time.tm_min, &time.tm_sec ) != 3 ) + /* it must be a hour:minutes:seconds */ { return 1; } @@ -1449,7 +1538,6 @@ int vlm_ScheduleSetup( vlm_schedule_t *schedule, const char *psz_cmd, psz_time = psz_value; } - switch( sscanf( psz_time, "%u:%u:%u", &i, &j, &k ) ) { case 1: @@ -1639,16 +1727,35 @@ static vlm_message_t *vlm_Show( vlm_t *vlm, vlm_media_t *media, { vlm_media_instance_t *p_instance = media->instance[i]; vlc_value_t val; + vlm_message_t *msg_instance; + char *psz_tmp; if( !p_instance->p_input ) val.i_int = END_S; else var_Get( p_instance->p_input, "state", &val ); - vlm_MessageAdd( msg_child, - vlm_MessageNew( p_instance->psz_name ? - p_instance->psz_name : "default", + msg_instance = vlm_MessageNew( "instance" , NULL ); + vlm_MessageAdd( msg_instance, vlm_MessageNew( "name" , p_instance->psz_name ? p_instance->psz_name : "default" ) ); + vlm_MessageAdd( msg_instance, vlm_MessageNew( "state", val.i_int == PLAYING_S ? "playing" : val.i_int == PAUSE_S ? "paused" : "stopped" ) ); +#define APPEND_INPUT_INFO( a, format, type ) \ + asprintf( &psz_tmp, format, \ + var_Get ## type( p_instance->p_input, a ) ); \ + vlm_MessageAdd( msg_instance, vlm_MessageNew( a, psz_tmp ) ); \ + free( psz_tmp ); + APPEND_INPUT_INFO( "position", "%f", Float ); + APPEND_INPUT_INFO( "time", "%d", Integer ); + APPEND_INPUT_INFO( "length", "%d", Integer ); + APPEND_INPUT_INFO( "rate", "%d", Integer ); + APPEND_INPUT_INFO( "title", "%d", Integer ); + APPEND_INPUT_INFO( "chapter", "%d", Integer ); + APPEND_INPUT_INFO( "seekable", "%d", Bool ); +#undef APPEND_INPUT_INFO + asprintf( &psz_tmp, "%d", p_instance->i_index + 1 ); + vlm_MessageAdd( msg_instance, vlm_MessageNew( "playlistindex", psz_tmp ) ); + free( psz_tmp ); + vlm_MessageAdd( msg_child, msg_instance ); } return msg; @@ -1831,12 +1938,6 @@ static vlm_message_t *vlm_Show( vlm_t *vlm, vlm_media_t *media, vlm_MessageNew( "enabled", s->b_enabled ? "yes" : "no" ) ); - if( !s->b_enabled ) return msg; - - - vlm_MessageAdd( msg_schedule, - vlm_MessageNew( "enabled", "yes" ) ); - /* calculate next date */ i_time = vlm_Date(); i_next_date = s->i_date; @@ -1874,7 +1975,7 @@ static vlm_message_t *vlm_Show( vlm_t *vlm, vlm_media_t *media, return msg; } - else if( psz_filter == NULL && media == NULL && schedule == NULL ) + else if( ( psz_filter == NULL ) && ( media == NULL ) && ( schedule == NULL ) ) { vlm_message_t *show1 = vlm_Show( vlm, NULL, NULL, "media" ); vlm_message_t *show2 = vlm_Show( vlm, NULL, NULL, "schedule" ); @@ -1915,6 +2016,7 @@ static vlm_message_t *vlm_Help( vlm_t *vlm, char *psz_filter ) MessageAddChild( "del (name)|all|media|schedule" ); MessageAddChild( "control (name) [instance_name] (command)" ); MessageAddChild( "save (config_file)" ); + MessageAddChild( "export" ); MessageAddChild( "load (config_file)" ); message_child = MessageAdd( "Media Proprieties Syntax:" ); @@ -1980,11 +2082,11 @@ static int Load( vlm_t *vlm, char *file ) if( message->psz_value ) msg_Err( vlm, "Load error on line %d: %s: %s", i_line, message->psz_name, message->psz_value ); - free( message ); + vlm_MessageDelete( message ); } return 1; } - if( message ) free( message ); + if( message ) vlm_MessageDelete( message ); pf += i_end; i_line++; @@ -1996,9 +2098,12 @@ static int Load( vlm_t *vlm, char *file ) static char *Save( vlm_t *vlm ) { char *save = NULL; + char psz_header[] = "\n" + "# VLC media player VLM command batch\n" + "# http://www.videolan.org/vlc/\n\n" ; char *p; int i,j; - int i_length = 0; + int i_length = strlen( psz_header ); for( i = 0; i < vlm->i_media; i++ ) { @@ -2100,6 +2205,8 @@ static char *Save( vlm_t *vlm ) p = save = malloc( i_length ); *save = '\0'; + p += sprintf( p, "%s", psz_header ); + /* finally we can write in it */ for( i = 0; i < vlm->i_media; i++ ) { @@ -2272,12 +2379,32 @@ int vlm_MediaVodControl( void *p_private, vod_media_t *p_vod_media, { double f_pos = (double)va_arg( args, double ); char psz_pos[50]; - - sprintf( psz_pos, "%f", f_pos ); + lldiv_t div = lldiv( f_pos * 10000000, 10000000 ); + sprintf( psz_pos, I64Fd".%07u", div.quot, (unsigned int) div.rem ); i_ret = vlm_MediaControl( vlm, vlm->media[i], psz_id, "seek", psz_pos); break; } + case VOD_MEDIA_REWIND: + { + double f_scale = (double)va_arg( args, double ); + char psz_scale[50]; + lldiv_t div = lldiv( f_scale * 10000000, 10000000 ); + sprintf( psz_scale, I64Fd".%07u", div.quot, (unsigned int) div.rem ); + i_ret = vlm_MediaControl( vlm, vlm->media[i], psz_id, "rewind", psz_scale ); + break; + } + + case VOD_MEDIA_FORWARD: + { + double f_scale = (double)va_arg( args, double ); + char psz_scale[50]; + lldiv_t div = lldiv( f_scale * 10000000, 10000000 ); + sprintf( psz_scale, I64Fd".%07u", div.quot, (unsigned int) div.rem ); + i_ret = vlm_MediaControl( vlm, vlm->media[i], psz_id, "forward", psz_scale ); + break; + } + default: break; } @@ -2287,6 +2414,7 @@ int vlm_MediaVodControl( void *p_private, vod_media_t *p_vod_media, return i_ret; } + /***************************************************************************** * Manage: *****************************************************************************/ @@ -2303,6 +2431,8 @@ static int Manage( vlc_object_t* p_object ) while( !vlm->b_die ) { + char **ppsz_scheduled_commands = NULL; + int i_scheduled_commands = 0; vlc_mutex_lock( &vlm->lock ); /* destroy the inputs that wants to die, and launch the next input */ @@ -2338,7 +2468,10 @@ static int Manage( vlc_object_t* p_object ) else { if( vlm_MediaControl( vlm, p_media, p_instance->psz_name, - "stop", 0 ) == VLC_SUCCESS ) i--; + "stop", 0 ) == VLC_SUCCESS ) + { + j--; /* the aray is one element smaller now. */ + } } } } @@ -2376,17 +2509,26 @@ static int Manage( vlc_object_t* p_object ) { for( j = 0; j < vlm->schedule[i]->i_command; j++ ) { - vlm_message_t *message = NULL; - - ExecuteCommand( vlm, vlm->schedule[i]->command[j], - &message ); - - /* for now, drop the message */ - free( message ); + TAB_APPEND( i_scheduled_commands, + ppsz_scheduled_commands, + strdup(vlm->schedule[i]->command[j] ) ); } } } } + while( i_scheduled_commands ) + { + vlm_message_t *message = NULL; + char *psz_command = ppsz_scheduled_commands[0]; + ExecuteCommand( vlm, psz_command,&message ); + + /* for now, drop the message */ + vlm_MessageDelete( message ); + TAB_REMOVE( i_scheduled_commands, + ppsz_scheduled_commands, + psz_command ); + free( psz_command ); + } i_lastcheck = i_time; @@ -2410,6 +2552,7 @@ void vlm_Delete( vlm_t *a ){} int vlm_ExecuteCommand( vlm_t *a, char *b, vlm_message_t **c ){ return -1; } void vlm_MessageDelete( vlm_message_t *a ){} vlm_media_t *vlm_MediaNew( vlm_t *a, char *b, int c ){ return NULL; } +vlm_media_t *vlm_MediaSearch (vlm_t *a, const char *b ) { return NULL; } void vlm_MediaDelete( vlm_t *a, vlm_media_t *b, char *c ){} int vlm_MediaSetup( vlm_t *a, vlm_media_t *b, char *c, char *d ){ return -1; } int vlm_MediaControl( vlm_t *a, vlm_media_t *b, char *c, char *d, char *e )