+/* New API
+ */
+/*
+typedef struct
+{
+ struct
+ {
+ int i_connection_count;
+ int i_connection_active;
+ } vod;
+ struct
+ {
+ int i_count;
+ vlc_bool_t b_playing;
+ int i_playing_index;
+ } broadcast;
+
+} vlm_media_status_t;
+*/
+
+/* */
+static vlm_media_sys_t *vlm_ControlMediaGetById( vlm_t *p_vlm, int64_t id )
+{
+ int i;
+
+ for( i = 0; i < p_vlm->i_media; i++ )
+ {
+ if( p_vlm->media[i]->cfg.id == id )
+ return p_vlm->media[i];
+ }
+ return NULL;
+}
+static vlm_media_sys_t *vlm_ControlMediaGetByName( vlm_t *p_vlm, const char *psz_name )
+{
+ int i;
+
+ for( i = 0; i < p_vlm->i_media; i++ )
+ {
+ if( !strcmp( p_vlm->media[i]->cfg.psz_name, psz_name ) )
+ return p_vlm->media[i];
+ }
+ return NULL;
+}
+static int vlm_MediaDescriptionCheck( vlm_t *p_vlm, vlm_media_t *p_cfg )
+{
+ int i;
+
+ if( !p_cfg || !p_cfg->psz_name ||
+ !strcmp( p_cfg->psz_name, "all" ) || !strcmp( p_cfg->psz_name, "media" ) || !strcmp( p_cfg->psz_name, "schedule" ) )
+ return VLC_EGENERIC;
+
+ for( i = 0; i < p_vlm->i_media; i++ )
+ {
+ if( p_vlm->media[i]->cfg.id == p_cfg->id )
+ continue;
+ if( !strcmp( p_vlm->media[i]->cfg.psz_name, p_cfg->psz_name ) )
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+
+
+/* Called after a media description is changed/added */
+static int vlm_OnMediaUpdate( vlm_t *p_vlm, vlm_media_sys_t *p_media )
+{
+ vlm_media_t *p_cfg = &p_media->cfg;
+ /* Check if we need to create/delete a vod media */
+ if( p_cfg->b_vod )
+ {
+ if( !p_cfg->b_enabled && p_media->vod.p_media )
+ {
+ p_vlm->p_vod->pf_media_del( p_vlm->p_vod, p_media->vod.p_media );
+ p_media->vod.p_media = NULL;
+ }
+ else if( p_cfg->b_enabled && !p_media->vod.p_media && p_cfg->i_input )
+ {
+ /* Pre-parse the input */
+ input_thread_t *p_input;
+ char *psz_output;
+ char *psz_header;
+ char *psz_dup;
+ int i;
+
+ input_ItemClean( &p_media->vod.item );
+ input_ItemInit( VLC_OBJECT(p_vlm), &p_media->vod.item );
+
+ if( p_cfg->psz_output )
+ asprintf( &psz_output, "%s:description", p_cfg->psz_output );
+ else
+ asprintf( &psz_output, "#description" );
+
+ p_media->vod.item.psz_uri = strdup( p_cfg->ppsz_input[0] );
+
+ TAB_INIT( p_media->vod.item.i_options, p_media->vod.item.ppsz_options );
+
+ asprintf( &psz_dup, "sout=%s", psz_output);
+ TAB_APPEND( p_media->vod.item.i_options, p_media->vod.item.ppsz_options, psz_dup );
+ for( i = 0; i < p_cfg->i_option; i++ )
+ {
+ psz_dup = strdup( p_cfg->ppsz_option[i] );
+ TAB_APPEND( p_media->vod.item.i_options, p_media->vod.item.ppsz_options, psz_dup );
+ }
+ psz_dup = strdup( "no-sout-keep" );
+ TAB_APPEND( p_media->vod.item.i_options, p_media->vod.item.ppsz_options, psz_dup );
+
+ asprintf( &psz_header, _("Media: %s"), p_cfg->psz_name );
+
+ if( (p_input = input_CreateThreadExtended( p_vlm, &p_media->vod.item, psz_header, NULL ) ) )
+ {
+ while( !p_input->b_eof && !p_input->b_error )
+ msleep( 100000 );
+
+ input_StopThread( p_input );
+ input_DestroyThreadExtended( p_input, NULL );
+ }
+ free( psz_output );
+ free( psz_header );
+
+ if( p_cfg->vod.psz_mux )
+ {
+ input_item_t item;
+ es_format_t es, *p_es = &es;
+ char fourcc[5];
+
+ sprintf( fourcc, "%4.4s", p_cfg->vod.psz_mux );
+ fourcc[0] = tolower(fourcc[0]); fourcc[1] = tolower(fourcc[1]);
+ fourcc[2] = tolower(fourcc[2]); fourcc[3] = tolower(fourcc[3]);
+
+ item = p_media->vod.item;
+ item.i_es = 1;
+ item.es = &p_es;
+ es_format_Init( &es, VIDEO_ES, *((int *)fourcc) );
+
+ p_media->vod.p_media =
+ p_vlm->p_vod->pf_media_new( p_vlm->p_vod, p_cfg->psz_name, &item );
+ }
+ else
+ {
+ p_media->vod.p_media =
+ p_vlm->p_vod->pf_media_new( p_vlm->p_vod, p_cfg->psz_name, &p_media->vod.item );
+ }
+ }
+ }
+ else
+ {
+ /* TODO start media if needed */
+ }
+
+ /* TODO add support of var vlm_media_broadcast/vlm_media_vod */
+
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaChange( vlm_t *p_vlm, vlm_media_t *p_cfg )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, p_cfg->id );
+
+ /* */
+ if( !p_media || vlm_MediaDescriptionCheck( p_vlm, p_cfg ) )
+ return VLC_EGENERIC;
+ if( ( p_media->cfg.b_vod && !p_cfg->b_vod ) || ( !p_media->cfg.b_vod && p_cfg->b_vod ) )
+ return VLC_EGENERIC;
+
+ if( 0 )
+ {
+ /* TODO check what are the changes being done (stop instance if needed) */
+ }
+
+ vlm_media_Clean( &p_media->cfg );
+ vlm_media_Copy( &p_media->cfg, p_cfg );
+
+ return vlm_OnMediaUpdate( p_vlm, p_media );
+}
+
+static int vlm_ControlMediaAdd( vlm_t *p_vlm, vlm_media_t *p_cfg, int64_t *p_id )
+{
+ vlm_media_sys_t *p_media;
+
+ if( vlm_MediaDescriptionCheck( p_vlm, p_cfg ) || vlm_ControlMediaGetByName( p_vlm, p_cfg->psz_name ) )
+ {
+ msg_Err( p_vlm, "invalid media description" );
+ return VLC_EGENERIC;
+ }
+ /* Check if we need to load the VOD server */
+ if( p_cfg->b_vod && !p_vlm->i_vod )
+ {
+ p_vlm->p_vod = vlc_object_create( p_vlm, VLC_OBJECT_VOD );
+ 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 );
+ if( !p_vlm->p_vod->p_module )
+ {
+ msg_Err( p_vlm, "cannot find vod server" );
+ vlc_object_detach( p_vlm->p_vod );
+ vlc_object_destroy( p_vlm->p_vod );
+ p_vlm->p_vod = 0;
+ return VLC_EGENERIC;
+ }
+
+ p_vlm->p_vod->p_data = p_vlm;
+ p_vlm->p_vod->pf_media_control = vlm_MediaVodControl;
+ }
+
+ p_media = malloc( 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++;
+
+ vlm_media_Copy( &p_media->cfg, p_cfg );
+ p_media->cfg.id = p_vlm->i_id++;
+ /* FIXME do we do something here if enabled is true ? */
+
+ input_ItemInit( VLC_OBJECT(p_vlm), &p_media->vod.item );
+
+ p_media->vod.p_media = NULL;
+ TAB_INIT( p_media->i_instance, p_media->instance );
+
+ /* */
+ TAB_APPEND( p_vlm->i_media, p_vlm->media, p_media );
+
+ if( p_id )
+ *p_id = p_media->cfg.id;
+
+ return vlm_OnMediaUpdate( p_vlm, p_media );
+}
+
+static int vlm_ControlMediaDel( vlm_t *p_vlm, int64_t id )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ while( p_media->i_instance > 0 )
+ vlm_ControlInternal( p_vlm, VLM_STOP_MEDIA_INSTANCE, id, p_media->instance[0]->psz_name );
+
+ if( p_media->cfg.b_vod )
+ {
+ p_media->cfg.b_enabled = VLC_FALSE;
+ vlm_OnMediaUpdate( p_vlm, p_media );
+ p_vlm->i_vod--;
+ }
+
+ vlm_media_Clean( &p_media->cfg );
+
+ input_ItemClean( &p_media->vod.item );
+
+ TAB_REMOVE( p_vlm->i_media, p_vlm->media, p_media );
+
+ free( p_media );
+
+ /* 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 );
+ vlc_object_detach( p_vlm->p_vod );
+ vlc_object_destroy( p_vlm->p_vod );
+ p_vlm->p_vod = NULL;
+ }
+ return VLC_SUCCESS;
+}
+
+static int vlm_ControlMediaGets( vlm_t *p_vlm, vlm_media_t ***ppp_dsc, int *pi_dsc )
+{
+ vlm_media_t **pp_dsc;
+ int i_dsc;
+ int i;
+
+ TAB_INIT( i_dsc, pp_dsc );
+ for( i = 0; i < p_vlm->i_media; i++ )
+ {
+ vlm_media_t *p_dsc = vlm_media_Duplicate( &p_vlm->media[i]->cfg );
+ TAB_APPEND( i_dsc, pp_dsc, p_dsc );
+ }
+
+ *ppp_dsc = pp_dsc;
+ *pi_dsc = i_dsc;
+
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaClear( vlm_t *p_vlm )
+{
+ while( p_vlm->i_media > 0 )
+ vlm_ControlMediaDel( p_vlm, p_vlm->media[0]->cfg.id );
+
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaGet( vlm_t *p_vlm, int64_t id, vlm_media_t **pp_dsc )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ *pp_dsc = vlm_media_Duplicate( &p_media->cfg );
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaGetId( vlm_t *p_vlm, const char *psz_name, int64_t *p_id )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetByName( p_vlm, psz_name );
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ *p_id = p_media->cfg.id;
+ return VLC_SUCCESS;
+}
+
+static vlm_media_instance_sys_t *vlm_ControlMediaInstanceGetByName( vlm_media_sys_t *p_media, const char *psz_id )
+{
+ int i;
+
+ for( i = 0; i < p_media->i_instance; i++ )
+ {
+ const char *psz = p_media->instance[i]->psz_name;
+ if( ( psz == NULL && psz_id == NULL ) ||
+ ( psz && psz_id && !strcmp( psz, psz_id ) ) )
+ return p_media->instance[i];
+ }
+ return NULL;
+}
+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) );
+ 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 );
+
+ input_ItemInit( VLC_OBJECT(p_vlm), &p_instance->item );
+
+ p_instance->i_index = 0;
+ p_instance->b_sout_keep = VLC_FALSE;
+ p_instance->p_input = NULL;
+ p_instance->p_sout = NULL;
+
+ return p_instance;
+}
+static void vlm_MediaInstanceDelete( vlm_media_instance_sys_t *p_instance )
+{
+ if( p_instance->p_input )
+ {
+ input_StopThread( p_instance->p_input );
+ input_DestroyThreadExtended( p_instance->p_input, &p_instance->p_sout );
+ }
+ if( p_instance->p_sout )
+ sout_DeleteInstance( p_instance->p_sout );
+
+ input_ItemClean( &p_instance->item );
+ if( p_instance->psz_name )
+ free( p_instance->psz_name );
+ free( p_instance );
+}
+
+
+static int vlm_ControlMediaInstanceStart( vlm_t *p_vlm, int64_t id, const char *psz_id, int i_input_index, const char *psz_vod_output )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+ vlm_media_instance_sys_t *p_instance;
+ char *psz_log;
+
+ if( !p_media || !p_media->cfg.b_enabled || p_media->cfg.i_input <= 0 )
+ return VLC_EGENERIC;
+
+ /* TODO support multiple input for VOD with sout-keep ? */
+
+ if( ( p_media->cfg.b_vod && !psz_vod_output ) || ( !p_media->cfg.b_vod && psz_vod_output ) )
+ return VLC_EGENERIC;
+
+ if( i_input_index < 0 || i_input_index >= p_media->cfg.i_input )
+ return VLC_EGENERIC;
+
+ p_instance = vlm_ControlMediaInstanceGetByName( p_media, psz_id );
+ if( !p_instance )
+ {
+ vlm_media_t *p_cfg = &p_media->cfg;
+ char *psz_keep;
+ int i;
+
+ p_instance = vlm_MediaInstanceNew( p_vlm, psz_id );
+ if( !p_instance )
+ return VLC_ENOMEM;
+
+ TAB_INIT( p_instance->item.i_options, p_instance->item.ppsz_options );
+
+ if( p_cfg->psz_output != NULL || psz_vod_output != NULL )
+ {
+ char *psz_buffer;
+ 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 : "" );
+ TAB_APPEND( p_instance->item.i_options, p_instance->item.ppsz_options, psz_buffer );
+ }
+
+ for( i = 0; i < p_cfg->i_option; i++ )
+ {
+ if( !strcmp( p_cfg->ppsz_option[i], "sout-keep" ) )
+ p_instance->b_sout_keep = VLC_TRUE;
+ else if( !strcmp( p_cfg->ppsz_option[i], "nosout-keep" ) || !strcmp( p_cfg->ppsz_option[i], "no-sout-keep" ) )
+ p_instance->b_sout_keep = VLC_FALSE;
+ else
+ TAB_APPEND( p_instance->item.i_options, p_instance->item.ppsz_options, strdup( p_cfg->ppsz_option[i] ) );
+ }
+ /* We force the right sout-keep value (avoid using the sout-keep from the global configuration)
+ * FIXME implement input list for VOD (need sout-keep)
+ * */
+ if( !p_cfg->b_vod && p_instance->b_sout_keep )
+ psz_keep = strdup( "sout-keep" );
+ else
+ psz_keep = strdup( "no-sout-keep" );
+ TAB_APPEND( p_instance->item.i_options, p_instance->item.ppsz_options, psz_keep );
+
+ TAB_APPEND( p_media->i_instance, p_media->instance, p_instance );
+ }
+
+ /* Stop old instance */
+ if( p_instance->p_input )
+ {
+ if( p_instance->i_index == i_input_index &&
+ !p_instance->p_input->b_eof && !p_instance->p_input->b_error )
+ {
+ if( var_GetInteger( p_instance->p_input, "state" ) == PAUSE_S )
+ var_SetInteger( p_instance->p_input, "state", PLAYING_S );
+ return VLC_SUCCESS;
+ }
+
+ input_StopThread( p_instance->p_input );
+ input_DestroyThreadExtended( p_instance->p_input, &p_instance->p_sout );
+ if( !p_instance->b_sout_keep && p_instance->p_sout )
+ {
+ sout_DeleteInstance( p_instance->p_sout );
+ p_instance->p_sout = NULL;
+ }
+ }
+
+ /* Start new one */
+ p_instance->i_index = i_input_index;
+ input_item_SetURI( &p_instance->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->item, psz_log, p_instance->p_sout );
+ if( !p_instance->p_input )
+ {
+ TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance );
+ vlm_MediaInstanceDelete( p_instance );
+ }
+ free( psz_log );
+
+ return VLC_SUCCESS;
+}
+
+static int vlm_ControlMediaInstanceStop( vlm_t *p_vlm, int64_t id, const char *psz_id )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+ vlm_media_instance_sys_t *p_instance;
+
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ p_instance = vlm_ControlMediaInstanceGetByName( p_media, psz_id );
+ if( !p_instance )
+ return VLC_EGENERIC;
+
+ TAB_REMOVE( p_media->i_instance, p_media->instance, p_instance );
+
+ vlm_MediaInstanceDelete( p_instance );
+
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaInstancePause( vlm_t *p_vlm, int64_t id, const char *psz_id )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+ vlm_media_instance_sys_t *p_instance;
+ int i_state;
+
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ p_instance = vlm_ControlMediaInstanceGetByName( p_media, psz_id );
+ if( !p_instance || !p_instance->p_input )
+ return VLC_EGENERIC;
+
+ /* Toggle pause state */
+ i_state = var_GetInteger( p_instance->p_input, "state" );
+ if( i_state == PAUSE_S )
+ var_SetInteger( p_instance->p_input, "state", PLAYING_S );
+ else if( i_state == PLAYING_S )
+ var_SetInteger( p_instance->p_input, "state", PAUSE_S );
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaInstanceGetTimePosition( vlm_t *p_vlm, int64_t id, const char *psz_id, int64_t *pi_time, double *pd_position )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+ vlm_media_instance_sys_t *p_instance;
+
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ p_instance = vlm_ControlMediaInstanceGetByName( p_media, psz_id );
+ if( !p_instance || !p_instance->p_input )
+ return VLC_EGENERIC;
+
+ if( pi_time )
+ *pi_time = var_GetTime( p_instance->p_input, "time" );
+ if( pd_position )
+ *pd_position = var_GetFloat( p_instance->p_input, "position" );
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaInstanceSetTimePosition( vlm_t *p_vlm, int64_t id, const char *psz_id, int64_t i_time, double d_position )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+ vlm_media_instance_sys_t *p_instance;
+
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ p_instance = vlm_ControlMediaInstanceGetByName( p_media, psz_id );
+ if( !p_instance || !p_instance->p_input )
+ return VLC_EGENERIC;
+
+ if( i_time >= 0 )
+ return var_SetTime( p_instance->p_input, "time", i_time );
+ else if( d_position >= 0 && d_position <= 100 )
+ return var_SetFloat( p_instance->p_input, "position", d_position );
+ return VLC_EGENERIC;
+}
+
+static int vlm_ControlMediaInstanceGets( vlm_t *p_vlm, int64_t id, vlm_media_instance_t ***ppp_idsc, int *pi_instance )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+ vlm_media_instance_t **pp_idsc;
+ int i_idsc;
+ int i;
+
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ TAB_INIT( i_idsc, pp_idsc );
+ for( i = 0; i < p_media->i_instance; i++ )
+ {
+ vlm_media_instance_sys_t *p_instance = p_media->instance[i];
+ vlm_media_instance_t *p_idsc = vlm_media_instance_New();
+
+ if( p_instance->psz_name )
+ p_idsc->psz_name = strdup( p_instance->psz_name );
+ if( p_instance->p_input )
+ {
+ p_idsc->i_time = var_GetTime( p_instance->p_input, "time" );
+ p_idsc->i_length = var_GetTime( p_instance->p_input, "length" );
+ p_idsc->d_position = var_GetFloat( p_instance->p_input, "position" );
+ if( var_GetInteger( p_instance->p_input, "state" ) == PAUSE_S )
+ p_idsc->b_paused = VLC_TRUE;
+ p_idsc->i_rate = var_GetInteger( p_instance->p_input, "rate" );
+ }
+
+ TAB_APPEND( i_idsc, pp_idsc, p_idsc );
+ }
+ *ppp_idsc = pp_idsc;
+ *pi_instance = i_idsc;
+ return VLC_SUCCESS;
+}
+static int vlm_ControlMediaInstanceClear( vlm_t *p_vlm, int64_t id )
+{
+ vlm_media_sys_t *p_media = vlm_ControlMediaGetById( p_vlm, id );
+
+ if( !p_media )
+ return VLC_EGENERIC;
+
+ while( p_media->i_instance > 0 )
+ vlm_ControlMediaInstanceStop( p_vlm, id, p_media->instance[0]->psz_name );
+
+ return VLC_SUCCESS;
+}
+
+static int vlm_ControlScheduleClear( vlm_t *p_vlm )
+{
+ while( p_vlm->i_schedule > 0 )
+ vlm_ScheduleDelete( p_vlm, p_vlm->schedule[0] );
+
+ return VLC_SUCCESS;
+}
+static int vlm_vaControlInternal( vlm_t *p_vlm, int i_query, va_list args )
+{
+ vlm_media_t *p_dsc;
+ vlm_media_t **pp_dsc;
+ vlm_media_t ***ppp_dsc;
+ vlm_media_instance_t ***ppp_idsc;
+ const char *psz_id;
+ const char *psz_vod;
+ int64_t *p_id;
+ int64_t id;
+ int i_int;
+ int *pi_int;
+
+ int64_t *pi_i64;
+ int64_t i_i64;
+ double *pd_double;
+ double d_double;
+
+ switch( i_query )
+ {
+ /* Media control */
+ case VLM_GET_MEDIAS:
+ ppp_dsc = (vlm_media_t ***)va_arg( args, vlm_media_t *** );
+ pi_int = (int *)va_arg( args, int * );
+ return vlm_ControlMediaGets( p_vlm, ppp_dsc, pi_int );
+
+ case VLM_CLEAR_MEDIAS:
+ return vlm_ControlMediaClear( p_vlm );
+
+ case VLM_CHANGE_MEDIA:
+ p_dsc = (vlm_media_t*)va_arg( args, vlm_media_t * );
+ return vlm_ControlMediaChange( p_vlm, p_dsc );
+
+ case VLM_ADD_MEDIA:
+ p_dsc = (vlm_media_t*)va_arg( args, vlm_media_t * );
+ p_id = (int64_t*)va_arg( args, int64_t * );
+ return vlm_ControlMediaAdd( p_vlm, p_dsc, p_id );
+
+ case VLM_DEL_MEDIA:
+ id = (int64_t)va_arg( args, int64_t );
+ return vlm_ControlMediaDel( p_vlm, id );
+
+ case VLM_GET_MEDIA:
+ id = (int64_t)va_arg( args, int64_t );
+ pp_dsc = (vlm_media_t **)va_arg( args, vlm_media_t ** );
+ return vlm_ControlMediaGet( p_vlm, id, pp_dsc );
+
+ case VLM_GET_MEDIA_ID:
+ psz_id = (const char*)va_arg( args, const char * );
+ p_id = (int64_t*)va_arg( args, int64_t * );
+ return vlm_ControlMediaGetId( p_vlm, psz_id, p_id );
+
+
+ /* Media instance control */
+ case VLM_GET_MEDIA_INSTANCES:
+ id = (int64_t)va_arg( args, int64_t );
+ ppp_idsc = (vlm_media_instance_t ***)va_arg( args, vlm_media_instance_t *** );
+ pi_int = (int *)va_arg( args, int *);
+ return vlm_ControlMediaInstanceGets( p_vlm, id, ppp_idsc, pi_int );
+
+ case VLM_CLEAR_MEDIA_INSTANCES:
+ id = (int64_t)va_arg( args, int64_t );
+ return vlm_ControlMediaInstanceClear( p_vlm, id );
+
+
+ case VLM_START_MEDIA_BROADCAST_INSTANCE:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ i_int = (int)va_arg( args, int );
+ return vlm_ControlMediaInstanceStart( p_vlm, id, psz_id, i_int, NULL );
+
+ case VLM_START_MEDIA_VOD_INSTANCE:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ i_int = (int)va_arg( args, int );
+ psz_vod = (const char*)va_arg( args, const char* );
+ if( !psz_vod )
+ return VLC_EGENERIC;
+ return vlm_ControlMediaInstanceStart( p_vlm, id, psz_id, i_int, psz_vod );
+
+ case VLM_STOP_MEDIA_INSTANCE:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ return vlm_ControlMediaInstanceStop( p_vlm, id, psz_id );
+
+ case VLM_PAUSE_MEDIA_INSTANCE:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ return vlm_ControlMediaInstancePause( p_vlm, id, psz_id );
+
+ case VLM_GET_MEDIA_INSTANCE_TIME:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ pi_i64 = (int64_t*)va_arg( args, int64_t * );
+ return vlm_ControlMediaInstanceGetTimePosition( p_vlm, id, psz_id, pi_i64, NULL );
+ case VLM_GET_MEDIA_INSTANCE_POSITION:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ pd_double = (double*)va_arg( args, double* );
+ return vlm_ControlMediaInstanceGetTimePosition( p_vlm, id, psz_id, NULL, pd_double );
+
+ case VLM_SET_MEDIA_INSTANCE_TIME:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ i_i64 = (int64_t)va_arg( args, int64_t);
+ return vlm_ControlMediaInstanceSetTimePosition( p_vlm, id, psz_id, i_i64, -1 );
+ case VLM_SET_MEDIA_INSTANCE_POSITION:
+ id = (int64_t)va_arg( args, int64_t );
+ psz_id = (const char*)va_arg( args, const char* );
+ d_double = (double)va_arg( args, double );
+ return vlm_ControlMediaInstanceSetTimePosition( p_vlm, id, psz_id, -1, d_double );
+
+ case VLM_CLEAR_SCHEDULES:
+ return vlm_ControlScheduleClear( p_vlm );
+
+ default:
+ msg_Err( p_vlm, "unknown VLM query" );
+ return VLC_EGENERIC;
+ }
+}
+static int vlm_ControlInternal( vlm_t *p_vlm, int i_query, ... )
+{
+ va_list args;
+ int i_result;
+
+ va_start( args, i_query );
+ i_result = vlm_vaControlInternal( p_vlm, i_query, args );
+ va_end( args );
+
+ return i_result;
+}
+
+int vlm_Control( vlm_t *p_vlm, int i_query, ... )
+{
+ va_list args;
+ int i_result;
+
+ va_start( args, i_query );
+
+ vlc_mutex_lock( &p_vlm->lock );
+ i_result = vlm_vaControlInternal( p_vlm, i_query, args );
+ vlc_mutex_unlock( &p_vlm->lock );
+
+ va_end( args );
+
+ return i_result;
+}
+