mirror of
https://code.videolan.org/videolan/vlc
synced 2024-09-12 13:44:56 +02:00
* all: - added a boolean "seekable" object variable to p_input.
(becarefull, it's just if you can seek or not, and not if you have to display the progress bar, for thet last you have to check if "position" value get != 0.0 ) - added "audio-delay" and "spu-delay" object variables to delay audio/spu to the video. They can be changed on the fly (untested). - renamed INPUT__GET/SET_SUBDELAY into INPUT_SET_SPU_DELAY and added INPUT_SET_AUDIO_DELAY (wrapper to "audio-delay" and "spu-delay") - readded INPUT_ADD/GET_INFO/INPUT_SET_NAME. Becarefull to not over-use them, a demuxer should export DEMUX_GET_META and not using them.
This commit is contained in:
parent
cb45b4c518
commit
2aebce79d5
@ -311,8 +311,19 @@ enum input_query_e
|
|||||||
INPUT_GET_STATE, /* arg1= int * res= */
|
INPUT_GET_STATE, /* arg1= int * res= */
|
||||||
INPUT_SET_STATE, /* arg1= int res=can fail */
|
INPUT_SET_STATE, /* arg1= int res=can fail */
|
||||||
|
|
||||||
/* XXX: all next query aren't working for now */
|
/* input variable "audio-delay" and "spu-delay" */
|
||||||
|
INPUT_GET_AUDIO_DELAY, /* arg1 = int* res=can fail */
|
||||||
|
INPUT_SET_AUDIO_DELAY, /* arg1 = int res=can fail */
|
||||||
|
INPUT_GET_SPU_DELAY, /* arg1 = int* res=can fail */
|
||||||
|
INPUT_SET_SPU_DELAY, /* arg1 = int res=can fail */
|
||||||
|
|
||||||
|
/* Meta datas */
|
||||||
|
INPUT_ADD_INFO, /* arg1= char * arg2= char * arg3=... res=can fail */
|
||||||
|
INPUT_GET_INFO, /* arg1= char * arg2= char * arg3= char ** res=can fail*/
|
||||||
|
|
||||||
|
INPUT_SET_NAME, /* arg1= char * res=can fail */
|
||||||
|
|
||||||
|
/* XXX: all next query aren't working for now */
|
||||||
/* bookmarks */
|
/* bookmarks */
|
||||||
INPUT_GET_BOOKMARKS, /* arg1= seekpoint_t *** arg2= int * res=can fail */
|
INPUT_GET_BOOKMARKS, /* arg1= seekpoint_t *** arg2= int * res=can fail */
|
||||||
INPUT_CLEAR_BOOKMARKS, /* res=can fail */
|
INPUT_CLEAR_BOOKMARKS, /* res=can fail */
|
||||||
@ -320,18 +331,6 @@ enum input_query_e
|
|||||||
INPUT_CHANGE_BOOKMARK, /* arg1= seekpoint_t * arg2= int * res=can fail */
|
INPUT_CHANGE_BOOKMARK, /* arg1= seekpoint_t * arg2= int * res=can fail */
|
||||||
INPUT_DEL_BOOKMARK, /* arg1= seekpoint_t * res=can fail */
|
INPUT_DEL_BOOKMARK, /* arg1= seekpoint_t * res=can fail */
|
||||||
INPUT_SET_BOOKMARK, /* arg1= int res=can fail */
|
INPUT_SET_BOOKMARK, /* arg1= int res=can fail */
|
||||||
|
|
||||||
INPUT_ADD_OPTION, /* arg1= char * arg2= char * res=can fail */
|
|
||||||
|
|
||||||
/* */
|
|
||||||
INPUT_ADD_INFO, /* arg1= char * arg2= char * arg3=... res=can fail */
|
|
||||||
INPUT_GET_INFO, /* arg1= char * arg2= char * arg3= char ** res=can fail*/
|
|
||||||
|
|
||||||
INPUT_SET_NAME, /* arg1= char * res=can fail */
|
|
||||||
|
|
||||||
/* */
|
|
||||||
INPUT_GET_SUBDELAY, /* arg1 = int* res=can fail */
|
|
||||||
INPUT_SET_SUBDELAY, /* arg1 = int res=can fail */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
VLC_EXPORT( int, input_vaControl,( input_thread_t *, int i_query, va_list ) );
|
VLC_EXPORT( int, input_vaControl,( input_thread_t *, int i_query, va_list ) );
|
||||||
|
@ -291,29 +291,25 @@ static void Run( intf_thread_t *p_intf )
|
|||||||
|
|
||||||
else if( i_action == ACTIONID_SUBDELAY_DOWN )
|
else if( i_action == ACTIONID_SUBDELAY_DOWN )
|
||||||
{
|
{
|
||||||
int i_delay;
|
int64_t i_delay = var_GetTime( p_input, "spu-delay" );
|
||||||
if( input_Control( p_input, INPUT_GET_SUBDELAY, &i_delay ) ==
|
|
||||||
VLC_SUCCESS )
|
i_delay -= 10000; /* 10 ms */
|
||||||
{
|
|
||||||
i_delay--;
|
var_SetTime( p_input, "spu-delay", i_delay );
|
||||||
input_Control( p_input, INPUT_SET_SUBDELAY, i_delay );
|
ClearChannels( p_intf, p_vout );
|
||||||
ClearChannels( p_intf, p_vout );
|
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
|
||||||
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
|
(int)(i_delay/1000) );
|
||||||
i_delay*100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if( i_action == ACTIONID_SUBDELAY_UP )
|
else if( i_action == ACTIONID_SUBDELAY_UP )
|
||||||
{
|
{
|
||||||
int i_delay;
|
int64_t i_delay = var_GetTime( p_input, "spu-delay" );
|
||||||
if( input_Control( p_input, INPUT_GET_SUBDELAY, &i_delay ) ==
|
|
||||||
VLC_SUCCESS )
|
i_delay += 10000; /* 10 ms */
|
||||||
{
|
|
||||||
i_delay++;
|
var_SetTime( p_input, "spu-delay", i_delay );
|
||||||
input_Control( p_input, INPUT_SET_SUBDELAY, i_delay );
|
ClearChannels( p_intf, p_vout );
|
||||||
ClearChannels( p_intf, p_vout );
|
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
|
||||||
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
|
(int)(i_delay/1000) );
|
||||||
i_delay*100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if( i_action == ACTIONID_FULLSCREEN && p_vout )
|
else if( i_action == ACTIONID_FULLSCREEN && p_vout )
|
||||||
{
|
{
|
||||||
|
@ -76,9 +76,6 @@ vlc_module_begin();
|
|||||||
add_float( "sub-fps", 0.0, NULL,
|
add_float( "sub-fps", 0.0, NULL,
|
||||||
N_("Frames per second"),
|
N_("Frames per second"),
|
||||||
SUB_FPS_LONGTEXT, VLC_TRUE );
|
SUB_FPS_LONGTEXT, VLC_TRUE );
|
||||||
add_integer( "sub-delay", 0, NULL,
|
|
||||||
N_("Delay subtitles (in 1/10s)"),
|
|
||||||
SUB_DELAY_LONGTEXT, VLC_TRUE );
|
|
||||||
add_string( "sub-type", "auto", NULL, "Subtitles fileformat",
|
add_string( "sub-type", "auto", NULL, "Subtitles fileformat",
|
||||||
SUB_TYPE_LONGTEXT, VLC_TRUE );
|
SUB_TYPE_LONGTEXT, VLC_TRUE );
|
||||||
change_string_list( ppsz_sub_type, 0, 0 );
|
change_string_list( ppsz_sub_type, 0, 0 );
|
||||||
@ -490,7 +487,6 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
|
|||||||
input_thread_t *p_input = p_sub->p_input;
|
input_thread_t *p_input = p_sub->p_input;
|
||||||
vlc_bool_t b;
|
vlc_bool_t b;
|
||||||
vlc_value_t val;
|
vlc_value_t val;
|
||||||
mtime_t i_delay;
|
|
||||||
|
|
||||||
es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, p_sub->p_es, &b );
|
es_out_Control( p_input->p_es_out, ES_OUT_GET_ES_STATE, p_sub->p_es, &b );
|
||||||
if( b && !p_sub->i_previously_selected )
|
if( b && !p_sub->i_previously_selected )
|
||||||
@ -507,10 +503,8 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
|
|||||||
|
|
||||||
if( p_sub->i_sub_type != SUB_TYPE_VOBSUB )
|
if( p_sub->i_sub_type != SUB_TYPE_VOBSUB )
|
||||||
{
|
{
|
||||||
var_Get( p_sub, "sub-delay", &val );
|
|
||||||
i_delay = (mtime_t) val.i_int * 100000;
|
|
||||||
while( p_sub->i_subtitle < p_sub->i_subtitles &&
|
while( p_sub->i_subtitle < p_sub->i_subtitles &&
|
||||||
p_sub->subtitle[p_sub->i_subtitle].i_start < i_maxdate - i_delay )
|
p_sub->subtitle[p_sub->i_subtitle].i_start < i_maxdate )
|
||||||
{
|
{
|
||||||
block_t *p_block;
|
block_t *p_block;
|
||||||
int i_len = strlen( p_sub->subtitle[p_sub->i_subtitle].psz_text ) + 1;
|
int i_len = strlen( p_sub->subtitle[p_sub->i_subtitle].psz_text ) + 1;
|
||||||
@ -528,13 +522,6 @@ static int sub_demux( subtitle_demux_t *p_sub, mtime_t i_maxdate )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX we should convert all demuxers to use es_out_Control to set * pcr and then remove that */
|
|
||||||
if( i_delay != 0 )
|
|
||||||
{
|
|
||||||
p_sub->subtitle[p_sub->i_subtitle].i_start += i_delay;
|
|
||||||
p_sub->subtitle[p_sub->i_subtitle].i_stop += i_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( p_sub->subtitle[p_sub->i_subtitle].i_start < 0 )
|
if( p_sub->subtitle[p_sub->i_subtitle].i_start < 0 )
|
||||||
{
|
{
|
||||||
p_sub->i_subtitle++;
|
p_sub->i_subtitle++;
|
||||||
@ -686,24 +673,6 @@ static void sub_fix( subtitle_demux_t *p_sub )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while( !i_done );
|
} while( !i_done );
|
||||||
#if 0
|
|
||||||
/* We do not do this here anymore */
|
|
||||||
/* *** and at the end add delay *** */
|
|
||||||
var_Get( p_sub, "sub-delay", &val );
|
|
||||||
i_delay = (mtime_t) val.i_int * 100000;
|
|
||||||
if( i_delay != 0 )
|
|
||||||
{
|
|
||||||
for( i = 0; i < p_sub->i_subtitles; i++ )
|
|
||||||
{
|
|
||||||
p_sub->subtitle[i].i_start += i_delay;
|
|
||||||
p_sub->subtitle[i].i_stop += i_delay;
|
|
||||||
if( p_sub->subtitle[i].i_start < 0 )
|
|
||||||
{
|
|
||||||
p_sub->i_subtitle = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +81,6 @@ typedef struct subtitle_demux_s
|
|||||||
* XXX: - if psz_name is NULL then --sub-file is read
|
* XXX: - if psz_name is NULL then --sub-file is read
|
||||||
* - i_microsecperframe is used only for microdvd file. (overriden
|
* - i_microsecperframe is used only for microdvd file. (overriden
|
||||||
* by --sub-fps )
|
* by --sub-fps )
|
||||||
* - it's at this point that --sub-delay is applied
|
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static inline subtitle_demux_t *subtitle_New( input_thread_t *p_input,
|
static inline subtitle_demux_t *subtitle_New( input_thread_t *p_input,
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
|
|
||||||
static void UpdateBookmarksOption( input_thread_t * );
|
static void UpdateBookmarksOption( input_thread_t * );
|
||||||
|
static void NotifyPlaylist( input_thread_t * );
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* input_Control
|
* input_Control
|
||||||
@ -54,12 +55,10 @@ int input_Control( input_thread_t *p_input, int i_query, ... )
|
|||||||
|
|
||||||
int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
||||||
{
|
{
|
||||||
seekpoint_t *p_bkmk, ***ppp_bkmk;
|
/* seekpoint_t *p_bkmk, ***ppp_bkmk;
|
||||||
int i_bkmk = 0;
|
int i_bkmk = 0;
|
||||||
int *pi_bkmk;
|
int *pi_bkmk;
|
||||||
int i, *pi;
|
*/
|
||||||
vlc_value_t val, text;
|
|
||||||
char *psz_option, *psz_value;
|
|
||||||
int i_int, *pi_int;
|
int i_int, *pi_int;
|
||||||
double f, *pf;
|
double f, *pf;
|
||||||
int64_t i_64, *pi_64;
|
int64_t i_64, *pi_64;
|
||||||
@ -107,70 +106,23 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
i_int = (int)va_arg( args, int );
|
i_int = (int)va_arg( args, int );
|
||||||
return var_SetInteger( p_input, "state", i_int );
|
return var_SetInteger( p_input, "state", i_int );
|
||||||
|
|
||||||
#if 0
|
case INPUT_GET_AUDIO_DELAY:
|
||||||
case INPUT_ADD_OPTION:
|
pi_64 = (int64_t*)va_arg( args, int64_t * );
|
||||||
{
|
*pi_64 = var_GetTime( p_input, "audio-delay" );
|
||||||
psz_option = (char *)va_arg( args, char * );
|
return VLC_SUCCESS;
|
||||||
psz_value = (char *)va_arg( args, char * );
|
|
||||||
i_ret = VLC_EGENERIC;
|
|
||||||
|
|
||||||
vlc_mutex_lock( &p_input->p_item->lock );
|
case INPUT_GET_SPU_DELAY:
|
||||||
/* Check if option already exists */
|
pi_64 = (int64_t*)va_arg( args, int64_t * );
|
||||||
for( i = 0; i < p_input->p_item->i_options; i++ )
|
*pi_64 = var_GetTime( p_input, "spu-delay" );
|
||||||
{
|
return VLC_SUCCESS;
|
||||||
if( !strncmp( p_input->p_item->ppsz_options[i], psz_option,
|
|
||||||
strlen( psz_option ) ) &&
|
|
||||||
p_input->p_item->ppsz_options[i][strlen(psz_option)]
|
|
||||||
== '=' )
|
|
||||||
{
|
|
||||||
free( p_input->p_item->ppsz_options[i] );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( i == p_input->p_item->i_options )
|
|
||||||
{
|
|
||||||
p_input->p_item->i_options++;
|
|
||||||
p_input->p_item->ppsz_options =
|
|
||||||
realloc( p_input->p_item->ppsz_options,
|
|
||||||
p_input->p_item->i_options * sizeof(char **) );
|
|
||||||
}
|
|
||||||
|
|
||||||
asprintf( &p_input->p_item->ppsz_options[i],
|
case INPUT_SET_AUDIO_DELAY:
|
||||||
"%s=%s", psz_option, psz_value ) ;
|
i_64 = (int64_t)va_arg( args, int64_t );
|
||||||
vlc_mutex_unlock( &p_input->p_item->lock );
|
return var_SetTime( p_input, "audio-delay", i_64 );
|
||||||
|
|
||||||
i_ret = VLC_SUCCESS;
|
case INPUT_SET_SPU_DELAY:
|
||||||
break;
|
i_64 = (int64_t)va_arg( args, int64_t );
|
||||||
}
|
return var_SetTime( p_input, "spu-delay", i_64 );
|
||||||
|
|
||||||
case INPUT_SET_NAME:
|
|
||||||
{
|
|
||||||
char *psz_name = (char *)va_arg( args, char * );
|
|
||||||
i_ret = VLC_EGENERIC;
|
|
||||||
if( !psz_name ) break;
|
|
||||||
vlc_mutex_lock( &p_input->p_item->lock );
|
|
||||||
if( p_input->p_item->psz_name ) free( p_input->p_item->psz_name );
|
|
||||||
p_input->p_item->psz_name = strdup( psz_name );
|
|
||||||
vlc_mutex_unlock( &p_input->p_item->lock );
|
|
||||||
i_ret = VLC_SUCCESS;
|
|
||||||
|
|
||||||
/* Notify playlist */
|
|
||||||
{
|
|
||||||
vlc_value_t val;
|
|
||||||
playlist_t *p_playlist =
|
|
||||||
(playlist_t *)vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
|
|
||||||
FIND_PARENT );
|
|
||||||
if( p_playlist )
|
|
||||||
{
|
|
||||||
val.i_int = p_playlist->i_index;
|
|
||||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
|
||||||
var_Set( p_playlist, "item-change", val );
|
|
||||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
|
||||||
vlc_object_release( p_playlist );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case INPUT_ADD_INFO:
|
case INPUT_ADD_INFO:
|
||||||
{
|
{
|
||||||
@ -182,29 +134,28 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
info_t *p_info;
|
info_t *p_info;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i_ret = VLC_EGENERIC;
|
vlc_mutex_lock( &p_input->input.p_item->lock );
|
||||||
|
for( i = 0; i < p_input->input.p_item->i_categories; i++ )
|
||||||
vlc_mutex_lock( &p_input->p_item->lock );
|
|
||||||
for( i = 0; i < p_input->p_item->i_categories; i++ )
|
|
||||||
{
|
{
|
||||||
if( !strcmp( p_input->p_item->pp_categories[i]->psz_name,
|
if( !strcmp( p_input->input.p_item->pp_categories[i]->psz_name,
|
||||||
psz_cat ) )
|
psz_cat ) )
|
||||||
break;
|
return VLC_EGENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i == p_input->p_item->i_categories )
|
if( i == p_input->input.p_item->i_categories )
|
||||||
{
|
{
|
||||||
p_cat = malloc( sizeof( info_category_t ) );
|
p_cat = malloc( sizeof( info_category_t ) );
|
||||||
if( !p_cat ) break;
|
if( !p_cat )
|
||||||
|
return VLC_EGENERIC;
|
||||||
p_cat->psz_name = strdup( psz_cat );
|
p_cat->psz_name = strdup( psz_cat );
|
||||||
p_cat->i_infos = 0;
|
p_cat->i_infos = 0;
|
||||||
p_cat->pp_infos = NULL;
|
p_cat->pp_infos = NULL;
|
||||||
INSERT_ELEM( p_input->p_item->pp_categories,
|
INSERT_ELEM( p_input->input.p_item->pp_categories,
|
||||||
p_input->p_item->i_categories,
|
p_input->input.p_item->i_categories,
|
||||||
p_input->p_item->i_categories, p_cat );
|
p_input->input.p_item->i_categories, p_cat );
|
||||||
}
|
}
|
||||||
|
|
||||||
p_cat = p_input->p_item->pp_categories[i];
|
p_cat = p_input->input.p_item->pp_categories[i];
|
||||||
|
|
||||||
for( i = 0; i < p_cat->i_infos; i++ )
|
for( i = 0; i < p_cat->i_infos; i++ )
|
||||||
{
|
{
|
||||||
@ -212,14 +163,15 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
{
|
{
|
||||||
if( p_cat->pp_infos[i]->psz_value )
|
if( p_cat->pp_infos[i]->psz_value )
|
||||||
free( p_cat->pp_infos[i]->psz_value );
|
free( p_cat->pp_infos[i]->psz_value );
|
||||||
break;
|
return VLC_EGENERIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i == p_cat->i_infos )
|
if( i == p_cat->i_infos )
|
||||||
{
|
{
|
||||||
p_info = malloc( sizeof( info_t ) );
|
p_info = malloc( sizeof( info_t ) );
|
||||||
if( !p_info ) break;
|
if( !p_info )
|
||||||
|
return VLC_EGENERIC;
|
||||||
INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos,
|
INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos,
|
||||||
p_cat->i_infos, p_info );
|
p_cat->i_infos, p_info );
|
||||||
p_info->psz_name = strdup( psz_name );
|
p_info->psz_name = strdup( psz_name );
|
||||||
@ -228,50 +180,33 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
p_info = p_cat->pp_infos[i];
|
p_info = p_cat->pp_infos[i];
|
||||||
vasprintf( &p_info->psz_value, psz_format, args );
|
vasprintf( &p_info->psz_value, psz_format, args );
|
||||||
|
|
||||||
vlc_mutex_unlock( &p_input->p_item->lock );
|
vlc_mutex_unlock( &p_input->input.p_item->lock );
|
||||||
|
|
||||||
i_ret = VLC_SUCCESS;
|
NotifyPlaylist( p_input );
|
||||||
|
|
||||||
/* Notify playlist */
|
|
||||||
{
|
|
||||||
vlc_value_t val;
|
|
||||||
playlist_t *p_playlist =
|
|
||||||
(playlist_t *)vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
|
|
||||||
FIND_PARENT );
|
|
||||||
if( p_playlist )
|
|
||||||
{
|
|
||||||
val.i_int = p_playlist->i_index;
|
|
||||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
|
||||||
var_Set( p_playlist, "item-change", val );
|
|
||||||
vlc_mutex_lock( &p_input->stream.stream_lock );
|
|
||||||
vlc_object_release( p_playlist );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
return VLC_SUCCESS;
|
||||||
|
|
||||||
case INPUT_GET_INFO:
|
case INPUT_GET_INFO:
|
||||||
{
|
{
|
||||||
char *psz_cat = (char *)va_arg( args, char * );
|
char *psz_cat = (char *)va_arg( args, char * );
|
||||||
char *psz_name = (char *)va_arg( args, char * );
|
char *psz_name = (char *)va_arg( args, char * );
|
||||||
char **ppsz_value = (char **)va_arg( args, char ** );
|
char **ppsz_value = (char **)va_arg( args, char ** );
|
||||||
|
int i_ret = VLC_EGENERIC;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i_ret = VLC_EGENERIC;
|
|
||||||
*ppsz_value = NULL;
|
*ppsz_value = NULL;
|
||||||
|
|
||||||
vlc_mutex_lock( &p_input->p_item->lock );
|
vlc_mutex_lock( &p_input->input.p_item->lock );
|
||||||
for( i = 0; i < p_input->p_item->i_categories; i++ )
|
for( i = 0; i < p_input->input.p_item->i_categories; i++ )
|
||||||
{
|
{
|
||||||
if( !strcmp( p_input->p_item->pp_categories[i]->psz_name,
|
if( !strcmp( p_input->input.p_item->pp_categories[i]->psz_name,
|
||||||
psz_cat ) )
|
psz_cat ) )
|
||||||
break;
|
return VLC_EGENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i != p_input->p_item->i_categories )
|
if( i != p_input->input.p_item->i_categories )
|
||||||
{
|
{
|
||||||
info_category_t *p_cat;
|
info_category_t *p_cat;
|
||||||
p_cat = p_input->p_item->pp_categories[i];
|
p_cat = p_input->input.p_item->pp_categories[i];
|
||||||
|
|
||||||
for( i = 0; i < p_cat->i_infos; i++ )
|
for( i = 0; i < p_cat->i_infos; i++ )
|
||||||
{
|
{
|
||||||
@ -286,10 +221,29 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vlc_mutex_unlock( &p_input->p_item->lock );
|
vlc_mutex_unlock( &p_input->input.p_item->lock );
|
||||||
|
return i_ret;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
|
case INPUT_SET_NAME:
|
||||||
|
{
|
||||||
|
char *psz_name = (char *)va_arg( args, char * );
|
||||||
|
|
||||||
|
if( !psz_name )
|
||||||
|
return VLC_EGENERIC;
|
||||||
|
|
||||||
|
vlc_mutex_lock( &p_input->input.p_item->lock );
|
||||||
|
if( p_input->input.p_item->psz_name )
|
||||||
|
free( p_input->input.p_item->psz_name );
|
||||||
|
p_input->input.p_item->psz_name = strdup( psz_name );
|
||||||
|
vlc_mutex_unlock( &p_input->input.p_item->lock );
|
||||||
|
|
||||||
|
NotifyPlaylist( p_input );
|
||||||
|
|
||||||
|
return VLC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
case INPUT_ADD_BOOKMARK:
|
case INPUT_ADD_BOOKMARK:
|
||||||
p_bkmk = (seekpoint_t *)va_arg( args, seekpoint_t * );
|
p_bkmk = (seekpoint_t *)va_arg( args, seekpoint_t * );
|
||||||
p_bkmk = vlc_seekpoint_Duplicate( p_bkmk );
|
p_bkmk = vlc_seekpoint_Duplicate( p_bkmk );
|
||||||
@ -440,51 +394,6 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case INPUT_GET_SUBDELAY:
|
|
||||||
pi = (int*)va_arg( args, int *);
|
|
||||||
/* We work on the first subtitle */
|
|
||||||
if( p_input->p_sys != NULL )
|
|
||||||
{
|
|
||||||
if( p_input->p_sys->i_sub > 0 )
|
|
||||||
{
|
|
||||||
i_ret = var_Get( (vlc_object_t *)p_input->p_sys->sub[0],
|
|
||||||
"sub-delay", &val );
|
|
||||||
*pi = val.i_int;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg_Dbg( p_input,"no subtitle track");
|
|
||||||
i_ret = VLC_EGENERIC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i_ret = VLC_EGENERIC;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case INPUT_SET_SUBDELAY:
|
|
||||||
i = (int)va_arg( args, int );
|
|
||||||
/* We work on the first subtitle */
|
|
||||||
if( p_input->p_sys )
|
|
||||||
{
|
|
||||||
if( p_input->p_sys->i_sub > 0 )
|
|
||||||
{
|
|
||||||
val.i_int = i;
|
|
||||||
i_ret = var_Set( (vlc_object_t *)p_input->p_sys->sub[0],
|
|
||||||
"sub-delay", val );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
msg_Dbg( p_input,"no subtitle track");
|
|
||||||
i_ret = VLC_EGENERIC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i_ret = VLC_EGENERIC;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
case INPUT_GET_BOOKMARKS:
|
case INPUT_GET_BOOKMARKS:
|
||||||
case INPUT_CLEAR_BOOKMARKS:
|
case INPUT_CLEAR_BOOKMARKS:
|
||||||
@ -492,12 +401,6 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
case INPUT_CHANGE_BOOKMARK:
|
case INPUT_CHANGE_BOOKMARK:
|
||||||
case INPUT_DEL_BOOKMARK:
|
case INPUT_DEL_BOOKMARK:
|
||||||
case INPUT_SET_BOOKMARK:
|
case INPUT_SET_BOOKMARK:
|
||||||
case INPUT_ADD_OPTION:
|
|
||||||
case INPUT_ADD_INFO:
|
|
||||||
case INPUT_GET_INFO:
|
|
||||||
case INPUT_SET_NAME:
|
|
||||||
case INPUT_GET_SUBDELAY:
|
|
||||||
case INPUT_SET_SUBDELAY:
|
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
msg_Err( p_input, "unimplemented query in input_vaControl" );
|
msg_Err( p_input, "unimplemented query in input_vaControl" );
|
||||||
default:
|
default:
|
||||||
@ -506,12 +409,24 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void NotifyPlaylist( input_thread_t *p_input )
|
||||||
|
{
|
||||||
|
playlist_t *p_playlist =
|
||||||
|
(playlist_t *)vlc_object_find( p_input, VLC_OBJECT_PLAYLIST,
|
||||||
|
FIND_PARENT );
|
||||||
|
if( p_playlist )
|
||||||
|
{
|
||||||
|
var_SetInteger( p_playlist, "item-change", p_playlist->i_index );
|
||||||
|
vlc_object_release( p_playlist );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void UpdateBookmarksOption( input_thread_t *p_input )
|
static void UpdateBookmarksOption( input_thread_t *p_input )
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
int i, i_len = 0;
|
int i, i_len = 0;
|
||||||
char *psz_value = NULL, *psz_next = NULL;
|
char *psz_value = NULL, *psz_next = NULL;
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
#if 0
|
|
||||||
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
vlc_mutex_unlock( &p_input->stream.stream_lock );
|
||||||
|
|
||||||
for( i = 0; i < p_input->i_bookmarks; i++ )
|
for( i = 0; i < p_input->i_bookmarks; i++ )
|
||||||
|
@ -97,6 +97,10 @@ struct es_out_sys_t
|
|||||||
es_out_id_t *p_es_audio;
|
es_out_id_t *p_es_audio;
|
||||||
es_out_id_t *p_es_video;
|
es_out_id_t *p_es_video;
|
||||||
es_out_id_t *p_es_sub;
|
es_out_id_t *p_es_sub;
|
||||||
|
|
||||||
|
/* delay */
|
||||||
|
int64_t i_audio_delay;
|
||||||
|
int64_t i_spu_delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
static es_out_id_t *EsOutAdd ( es_out_t *, es_format_t * );
|
static es_out_id_t *EsOutAdd ( es_out_t *, es_format_t * );
|
||||||
@ -153,6 +157,9 @@ es_out_t *input_EsOutNew( input_thread_t *p_input )
|
|||||||
p_sys->p_es_video = NULL;
|
p_sys->p_es_video = NULL;
|
||||||
p_sys->p_es_sub = NULL;
|
p_sys->p_es_sub = NULL;
|
||||||
|
|
||||||
|
p_sys->i_audio_delay= 0;
|
||||||
|
p_sys->i_spu_delay = 0;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,6 +232,16 @@ void input_EsOutDiscontinuity( es_out_t *out, vlc_bool_t b_audio )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay )
|
||||||
|
{
|
||||||
|
es_out_sys_t *p_sys = out->p_sys;
|
||||||
|
|
||||||
|
if( i_cat == AUDIO_ES )
|
||||||
|
p_sys->i_audio_delay = i_delay;
|
||||||
|
else if( i_cat == SPU_ES )
|
||||||
|
p_sys->i_spu_delay = i_delay;
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -715,17 +732,27 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
|
|||||||
es_out_sys_t *p_sys = out->p_sys;
|
es_out_sys_t *p_sys = out->p_sys;
|
||||||
input_thread_t *p_input = p_sys->p_input;
|
input_thread_t *p_input = p_sys->p_input;
|
||||||
es_out_pgrm_t *p_pgrm = es->p_pgrm;
|
es_out_pgrm_t *p_pgrm = es->p_pgrm;
|
||||||
|
int64_t i_delay;
|
||||||
|
|
||||||
|
if( es->fmt.i_cat == AUDIO_ES )
|
||||||
|
i_delay = p_sys->i_audio_delay;
|
||||||
|
else if( es->fmt.i_cat == SPU_ES )
|
||||||
|
i_delay = p_sys->i_spu_delay;
|
||||||
|
else
|
||||||
|
i_delay = 0;
|
||||||
|
|
||||||
/* +11 -> avoid null value with non null dts/pts */
|
/* +11 -> avoid null value with non null dts/pts */
|
||||||
if( p_block->i_dts > 0 )
|
if( p_block->i_dts > 0 )
|
||||||
{
|
{
|
||||||
p_block->i_dts =
|
p_block->i_dts =
|
||||||
input_ClockGetTS( p_input, &p_pgrm->clock, ( p_block->i_dts + 11 ) * 9 / 100 );
|
input_ClockGetTS( p_input, &p_pgrm->clock,
|
||||||
|
( p_block->i_dts + 11 ) * 9 / 100 ) + i_delay;
|
||||||
}
|
}
|
||||||
if( p_block->i_pts > 0 )
|
if( p_block->i_pts > 0 )
|
||||||
{
|
{
|
||||||
p_block->i_pts =
|
p_block->i_pts =
|
||||||
input_ClockGetTS( p_input, &p_pgrm->clock, ( p_block->i_pts + 11 )* 9 / 100 );
|
input_ClockGetTS( p_input, &p_pgrm->clock,
|
||||||
|
( p_block->i_pts + 11 ) * 9 / 100 ) + i_delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_block->i_rate = p_input->i_rate;
|
p_block->i_rate = p_input->i_rate;
|
||||||
|
@ -75,10 +75,12 @@ static void DecodeUrl ( char * );
|
|||||||
* - title,title-next,title-prev
|
* - title,title-next,title-prev
|
||||||
* - chapter,chapter-next, chapter-prev
|
* - chapter,chapter-next, chapter-prev
|
||||||
* - program, audio-es, video-es, spu-es
|
* - program, audio-es, video-es, spu-es
|
||||||
|
* - audio-delay, spu-delay
|
||||||
* - bookmark
|
* - bookmark
|
||||||
* * Get only:
|
* * Get only:
|
||||||
* - length
|
* - length
|
||||||
* - bookmarks
|
* - bookmarks
|
||||||
|
* - seekable (if you can seek, it doesn't say if 'bar display' has be shown or not, for that check position != 0.0)
|
||||||
* * For intf callback upon changes
|
* * For intf callback upon changes
|
||||||
* - intf-change
|
* - intf-change
|
||||||
* TODO explain when Callback is called
|
* TODO explain when Callback is called
|
||||||
@ -280,6 +282,10 @@ void input_DestroyThread( input_thread_t *p_input )
|
|||||||
* Run: main thread loop
|
* Run: main thread loop
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
* Thread in charge of processing the network packets and demultiplexing.
|
* Thread in charge of processing the network packets and demultiplexing.
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* read subtitle support (XXX take care of spu-delay in the right way).
|
||||||
|
* multi-input support (XXX may be done with subs)
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static int Run( input_thread_t *p_input )
|
static int Run( input_thread_t *p_input )
|
||||||
{
|
{
|
||||||
@ -673,6 +679,11 @@ static int Init( input_thread_t * p_input )
|
|||||||
&p_input->input.b_can_pace_control );
|
&p_input->input.b_can_pace_control );
|
||||||
demux2_Control( p_input->input.p_demux, DEMUX_CAN_PAUSE,
|
demux2_Control( p_input->input.p_demux, DEMUX_CAN_PAUSE,
|
||||||
&p_input->input.b_can_pause );
|
&p_input->input.b_can_pause );
|
||||||
|
|
||||||
|
/* FIXME todo
|
||||||
|
demux2_Control( p_input->input.p_demux, DEMUX_CAN_SEEK,
|
||||||
|
&val.b_bool );
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -728,6 +739,9 @@ static int Init( input_thread_t * p_input )
|
|||||||
&p_input->input.b_can_pace_control );
|
&p_input->input.b_can_pace_control );
|
||||||
access2_Control( p_input->input.p_access, ACCESS_CAN_PAUSE,
|
access2_Control( p_input->input.p_access, ACCESS_CAN_PAUSE,
|
||||||
&p_input->input.b_can_pace_control );
|
&p_input->input.b_can_pace_control );
|
||||||
|
access2_Control( p_input->input.p_access, ACCESS_CAN_SEEK,
|
||||||
|
&val.b_bool );
|
||||||
|
var_Set( p_input, "seekable", val );
|
||||||
|
|
||||||
/* Create the stream_t */
|
/* Create the stream_t */
|
||||||
p_input->input.p_stream = stream_AccessNew( p_input->input.p_access );
|
p_input->input.p_stream = stream_AccessNew( p_input->input.p_access );
|
||||||
@ -1528,6 +1542,18 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type, vlc_value_t val
|
|||||||
ES_OUT_SET_ES, input_EsOutGetFromID( p_input->p_es_out, val.i_int ) );
|
ES_OUT_SET_ES, input_EsOutGetFromID( p_input->p_es_out, val.i_int ) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case INPUT_CONTROL_SET_AUDIO_DELAY:
|
||||||
|
input_EsOutSetDelay( p_input->p_es_out,
|
||||||
|
AUDIO_ES, val.i_time );
|
||||||
|
var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INPUT_CONTROL_SET_SPU_DELAY:
|
||||||
|
input_EsOutSetDelay( p_input->p_es_out,
|
||||||
|
SPU_ES, val.i_time );
|
||||||
|
var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
|
||||||
|
break;
|
||||||
|
|
||||||
case INPUT_CONTROL_SET_TITLE:
|
case INPUT_CONTROL_SET_TITLE:
|
||||||
case INPUT_CONTROL_SET_TITLE_NEXT:
|
case INPUT_CONTROL_SET_TITLE_NEXT:
|
||||||
case INPUT_CONTROL_SET_TITLE_PREV:
|
case INPUT_CONTROL_SET_TITLE_PREV:
|
||||||
|
@ -56,6 +56,9 @@ enum input_control_e
|
|||||||
INPUT_CONTROL_SET_BOOKMARK,
|
INPUT_CONTROL_SET_BOOKMARK,
|
||||||
|
|
||||||
INPUT_CONTROL_SET_ES,
|
INPUT_CONTROL_SET_ES,
|
||||||
|
|
||||||
|
INPUT_CONTROL_SET_AUDIO_DELAY,
|
||||||
|
INPUT_CONTROL_SET_SPU_DELAY,
|
||||||
};
|
};
|
||||||
struct input_thread_sys_t
|
struct input_thread_sys_t
|
||||||
{
|
{
|
||||||
@ -119,6 +122,7 @@ es_out_t *input_EsOutNew( input_thread_t * );
|
|||||||
void input_EsOutDelete( es_out_t * );
|
void input_EsOutDelete( es_out_t * );
|
||||||
es_out_id_t *input_EsOutGetFromID( es_out_t *, int i_id );
|
es_out_id_t *input_EsOutGetFromID( es_out_t *, int i_id );
|
||||||
void input_EsOutDiscontinuity( es_out_t *, vlc_bool_t b_audio );
|
void input_EsOutDiscontinuity( es_out_t *, vlc_bool_t b_audio );
|
||||||
|
void input_EsOutSetDelay( es_out_t *, int i_cat, int64_t );
|
||||||
|
|
||||||
/* clock.c */
|
/* clock.c */
|
||||||
enum /* Synchro states */
|
enum /* Synchro states */
|
||||||
|
@ -62,6 +62,9 @@ static int NavigationCallback( vlc_object_t *p_this, char const *psz_cmd,
|
|||||||
vlc_value_t oldval, vlc_value_t newval, void * );
|
vlc_value_t oldval, vlc_value_t newval, void * );
|
||||||
static int ESCallback ( vlc_object_t *p_this, char const *psz_cmd,
|
static int ESCallback ( vlc_object_t *p_this, char const *psz_cmd,
|
||||||
vlc_value_t oldval, vlc_value_t newval, void * );
|
vlc_value_t oldval, vlc_value_t newval, void * );
|
||||||
|
static int EsDelayCallback ( vlc_object_t *p_this, char const *psz_cmd,
|
||||||
|
vlc_value_t oldval, vlc_value_t newval, void * );
|
||||||
|
|
||||||
static int BookmarkCallback( vlc_object_t *p_this, char const *psz_cmd,
|
static int BookmarkCallback( vlc_object_t *p_this, char const *psz_cmd,
|
||||||
vlc_value_t oldval, vlc_value_t newval, void * );
|
vlc_value_t oldval, vlc_value_t newval, void * );
|
||||||
|
|
||||||
@ -144,6 +147,17 @@ void input_ControlVarInit ( input_thread_t *p_input )
|
|||||||
text.psz_string = _("Navigation");
|
text.psz_string = _("Navigation");
|
||||||
var_Change( p_input, "navigation", VLC_VAR_SETTEXT, &text, NULL );
|
var_Change( p_input, "navigation", VLC_VAR_SETTEXT, &text, NULL );
|
||||||
|
|
||||||
|
/* Delay */
|
||||||
|
var_Create( p_input, "audio-delay", VLC_VAR_TIME );
|
||||||
|
val.i_time = 0;
|
||||||
|
var_Change( p_input, "audio-delay", VLC_VAR_SETVALUE, &val, NULL );
|
||||||
|
var_AddCallback( p_input, "audio-delay", EsDelayCallback, NULL );
|
||||||
|
var_Create( p_input, "spu-delay", VLC_VAR_TIME );
|
||||||
|
val.i_time = 0;
|
||||||
|
var_Change( p_input, "spu-delay", VLC_VAR_SETVALUE, &val, NULL );
|
||||||
|
var_AddCallback( p_input, "spu-delay", EsDelayCallback, NULL );
|
||||||
|
|
||||||
|
|
||||||
/* Video ES */
|
/* Video ES */
|
||||||
var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
|
var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
|
||||||
text.psz_string = _("Video Track");
|
text.psz_string = _("Video Track");
|
||||||
@ -193,6 +207,9 @@ void input_ControlVarClean( input_thread_t *p_input )
|
|||||||
var_Destroy( p_input, "time" );
|
var_Destroy( p_input, "time" );
|
||||||
var_Destroy( p_input, "time-offset" );
|
var_Destroy( p_input, "time-offset" );
|
||||||
|
|
||||||
|
var_Destroy( p_input, "audio-delay" );
|
||||||
|
var_Destroy( p_input, "spu-delay" );
|
||||||
|
|
||||||
var_Destroy( p_input, "bookmark" );
|
var_Destroy( p_input, "bookmark" );
|
||||||
|
|
||||||
var_Destroy( p_input, "program" );
|
var_Destroy( p_input, "program" );
|
||||||
@ -384,6 +401,11 @@ void input_ConfigVarInit ( input_thread_t *p_input )
|
|||||||
var_Create( p_input, "audio-desync", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
|
var_Create( p_input, "audio-desync", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
|
||||||
|
|
||||||
var_Create( p_input, "cr-average", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
|
var_Create( p_input, "cr-average", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
|
||||||
|
|
||||||
|
var_Create( p_input, "seekable", VLC_VAR_BOOL );
|
||||||
|
val.b_bool = VLC_TRUE; /* Fixed later*/
|
||||||
|
var_Change( p_input, "seekable", VLC_VAR_SETVALUE, &val, NULL );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -623,6 +645,18 @@ static int ESCallback ( vlc_object_t *p_this, char const *psz_cmd,
|
|||||||
return VLC_SUCCESS;
|
return VLC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int EsDelayCallback ( vlc_object_t *p_this, char const *psz_cmd,
|
||||||
|
vlc_value_t oldval, vlc_value_t newval, void *p )
|
||||||
|
{
|
||||||
|
input_thread_t *p_input = (input_thread_t*)p_this;
|
||||||
|
|
||||||
|
if( !strcmp( psz_cmd, "audio-delay" ) )
|
||||||
|
input_ControlPush( p_input, INPUT_CONTROL_SET_AUDIO_DELAY, &newval );
|
||||||
|
else if( !strcmp( psz_cmd, "spu-delay" ) )
|
||||||
|
input_ControlPush( p_input, INPUT_CONTROL_SET_SPU_DELAY, &newval );
|
||||||
|
return VLC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static int BookmarkCallback( vlc_object_t *p_this, char const *psz_cmd,
|
static int BookmarkCallback( vlc_object_t *p_this, char const *psz_cmd,
|
||||||
vlc_value_t oldval, vlc_value_t newval, void *p_data )
|
vlc_value_t oldval, vlc_value_t newval, void *p_data )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user