Commit 2aebce79 authored by Laurent Aimar's avatar Laurent Aimar

* 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.
parent cb45b4c5
......@@ -311,8 +311,19 @@ enum input_query_e
INPUT_GET_STATE, /* arg1= int * res= */
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 */
INPUT_GET_BOOKMARKS, /* arg1= seekpoint_t *** arg2= int * 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_DEL_BOOKMARK, /* arg1= seekpoint_t * 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 ) );
......
......@@ -291,29 +291,25 @@ static void Run( intf_thread_t *p_intf )
else if( i_action == ACTIONID_SUBDELAY_DOWN )
{
int i_delay;
if( input_Control( p_input, INPUT_GET_SUBDELAY, &i_delay ) ==
VLC_SUCCESS )
{
i_delay--;
input_Control( p_input, INPUT_SET_SUBDELAY, i_delay );
ClearChannels( p_intf, p_vout );
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
i_delay*100);
}
int64_t i_delay = var_GetTime( p_input, "spu-delay" );
i_delay -= 10000; /* 10 ms */
var_SetTime( p_input, "spu-delay", i_delay );
ClearChannels( p_intf, p_vout );
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
(int)(i_delay/1000) );
}
else if( i_action == ACTIONID_SUBDELAY_UP )
{
int i_delay;
if( input_Control( p_input, INPUT_GET_SUBDELAY, &i_delay ) ==
VLC_SUCCESS )
{
i_delay++;
input_Control( p_input, INPUT_SET_SUBDELAY, i_delay );
ClearChannels( p_intf, p_vout );
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
i_delay*100);
}
int64_t i_delay = var_GetTime( p_input, "spu-delay" );
i_delay += 10000; /* 10 ms */
var_SetTime( p_input, "spu-delay", i_delay );
ClearChannels( p_intf, p_vout );
vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
(int)(i_delay/1000) );
}
else if( i_action == ACTIONID_FULLSCREEN && p_vout )
{
......
......@@ -76,9 +76,6 @@ vlc_module_begin();
add_float( "sub-fps", 0.0, NULL,
N_("Frames per second"),
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",
SUB_TYPE_LONGTEXT, VLC_TRUE );
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;
vlc_bool_t b;
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 );
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 )
{
var_Get( p_sub, "sub-delay", &val );
i_delay = (mtime_t) val.i_int * 100000;
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;
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;
}
/* 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 )
{
p_sub->i_subtitle++;
......@@ -686,24 +673,6 @@ static void sub_fix( subtitle_demux_t *p_sub )
}
}
} 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
* - i_microsecperframe is used only for microdvd file. (overriden
* 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,
......
......@@ -30,6 +30,7 @@
static void UpdateBookmarksOption( input_thread_t * );
static void NotifyPlaylist( input_thread_t * );
/****************************************************************************
* 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 )
{
seekpoint_t *p_bkmk, ***ppp_bkmk;
/* seekpoint_t *p_bkmk, ***ppp_bkmk;
int i_bkmk = 0;
int *pi_bkmk;
int i, *pi;
vlc_value_t val, text;
char *psz_option, *psz_value;
*/
int i_int, *pi_int;
double f, *pf;
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 );
return var_SetInteger( p_input, "state", i_int );
#if 0
case INPUT_ADD_OPTION:
{
psz_option = (char *)va_arg( args, char * );
psz_value = (char *)va_arg( args, char * );
i_ret = VLC_EGENERIC;
vlc_mutex_lock( &p_input->p_item->lock );
/* Check if option already exists */
for( i = 0; i < p_input->p_item->i_options; i++ )
{
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],
"%s=%s", psz_option, psz_value ) ;
vlc_mutex_unlock( &p_input->p_item->lock );
case INPUT_GET_AUDIO_DELAY:
pi_64 = (int64_t*)va_arg( args, int64_t * );
*pi_64 = var_GetTime( p_input, "audio-delay" );
return VLC_SUCCESS;
i_ret = VLC_SUCCESS;
break;
}
case INPUT_GET_SPU_DELAY:
pi_64 = (int64_t*)va_arg( args, int64_t * );
*pi_64 = var_GetTime( p_input, "spu-delay" );
return VLC_SUCCESS;
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;
case INPUT_SET_AUDIO_DELAY:
i_64 = (int64_t)va_arg( args, int64_t );
return var_SetTime( p_input, "audio-delay", i_64 );
/* 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_SET_SPU_DELAY:
i_64 = (int64_t)va_arg( args, int64_t );
return var_SetTime( p_input, "spu-delay", i_64 );
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;
int i;
i_ret = VLC_EGENERIC;
vlc_mutex_lock( &p_input->p_item->lock );
for( i = 0; i < p_input->p_item->i_categories; i++ )
vlc_mutex_lock( &p_input->input.p_item->lock );
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 ) )
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 ) );
if( !p_cat ) break;
if( !p_cat )
return VLC_EGENERIC;
p_cat->psz_name = strdup( psz_cat );
p_cat->i_infos = 0;
p_cat->pp_infos = NULL;
INSERT_ELEM( p_input->p_item->pp_categories,
p_input->p_item->i_categories,
p_input->p_item->i_categories, p_cat );
INSERT_ELEM( p_input->input.p_item->pp_categories,
p_input->input.p_item->i_categories,
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++ )
{
......@@ -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 )
free( p_cat->pp_infos[i]->psz_value );
break;
return VLC_EGENERIC;
}
}
if( i == p_cat->i_infos )
{
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,
p_cat->i_infos, p_info );
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];
vasprintf( &p_info->psz_value, psz_format, args );
vlc_mutex_unlock( &p_input->p_item->lock );
i_ret = VLC_SUCCESS;
vlc_mutex_unlock( &p_input->input.p_item->lock );
/* 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 );
}
}
NotifyPlaylist( p_input );
}
break;
return VLC_SUCCESS;
case INPUT_GET_INFO:
{
char *psz_cat = (char *)va_arg( args, char * );
char *psz_name = (char *)va_arg( args, char * );
char **ppsz_value = (char **)va_arg( args, char ** );
int i_ret = VLC_EGENERIC;
int i;
i_ret = VLC_EGENERIC;
*ppsz_value = NULL;
vlc_mutex_lock( &p_input->p_item->lock );
for( i = 0; i < p_input->p_item->i_categories; i++ )
vlc_mutex_lock( &p_input->input.p_item->lock );
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 ) )
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;
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++ )
{
......@@ -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;
}
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;
}
break;
#if 0
case INPUT_ADD_BOOKMARK:
p_bkmk = (seekpoint_t *)va_arg( args, seekpoint_t * );
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;
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
case INPUT_GET_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_DEL_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 */
msg_Err( p_input, "unimplemented query in input_vaControl" );
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 )
{
#if 0
int i, i_len = 0;
char *psz_value = NULL, *psz_next = NULL;
/* FIXME */
#if 0
vlc_mutex_unlock( &p_input->stream.stream_lock );
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_video;
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 * );
......@@ -153,6 +157,9 @@ es_out_t *input_EsOutNew( input_thread_t *p_input )
p_sys->p_es_video = NULL;
p_sys->p_es_sub = NULL;
p_sys->i_audio_delay= 0;
p_sys->i_spu_delay = 0;
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;
input_thread_t *p_input = p_sys->p_input;
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 */
if( p_block->i_dts > 0 )
{
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 )
{
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;
......
......@@ -75,10 +75,12 @@ static void DecodeUrl ( char * );
* - title,title-next,title-prev
* - chapter,chapter-next, chapter-prev
* - program, audio-es, video-es, spu-es
* - audio-delay, spu-delay
* - bookmark
* * Get only:
* - length
* - 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
* - intf-change
* TODO explain when Callback is called
......@@ -280,6 +282,10 @@ void input_DestroyThread( input_thread_t *p_input )
* Run: main thread loop
*****************************************************************************
* 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 )
{
......@@ -673,6 +679,11 @@ static int Init( input_thread_t * p_input )
&p_input->input.b_can_pace_control );
demux2_Control( p_input->input.p_demux, DEMUX_CAN_PAUSE,
&p_input->input.b_can_pause );
/* FIXME todo
demux2_Control( p_input->input.p_demux, DEMUX_CAN_SEEK,
&val.b_bool );
*/
}
else
{
......@@ -728,6 +739,9 @@ static int Init( input_thread_t * p_input )
&p_input->input.b_can_pace_control );
access2_Control( p_input->input.p_access, ACCESS_CAN_PAUSE,
&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 */
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 ) );
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_NEXT:
case INPUT_CONTROL_SET_TITLE_PREV:
......
......@@ -56,6 +56,9 @@ enum input_control_e
INPUT_CONTROL_SET_BOOKMARK,
INPUT_CONTROL_SET_ES,
INPUT_CONTROL_SET_AUDIO_DELAY,
INPUT_CONTROL_SET_SPU_DELAY,
};
struct input_thread_sys_t
{
......@@ -119,6 +122,7 @@ es_out_t *input_EsOutNew( input_thread_t * );
void input_EsOutDelete( es_out_t * );
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_EsOutSetDelay( es_out_t *, int i_cat, int64_t );
/* clock.c */
enum /* Synchro states */
......
......@@ -62,6 +62,9 @@ static int NavigationCallback( vlc_object_t *p_this, char const *psz_cmd,