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,
......
This diff is collapsed.
......@@ -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,
vlc_value_t oldval, vlc_value_t newval, void * );
static int ESCallback ( vlc_object_t *p_this, char const *psz_cmd,
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,
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");
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 */
var_Create( p_input, "video-es", VLC_VAR_INTEGER | VLC_VAR_HASCHOICE );
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-offset" );
var_Destroy( p_input, "audio-delay" );
var_Destroy( p_input, "spu-delay" );
var_Destroy( p_input, "bookmark" );
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, "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;
}
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,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment