Commit fccbbf97 authored by Laurent Aimar's avatar Laurent Aimar

Convert remaining input_EsOut* to es_out_Control.

parent 2c73cfb4
......@@ -311,160 +311,6 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
return out;
}
void input_EsOutChangeRate( es_out_t *out, int i_rate )
{
es_out_sys_t *p_sys = out->p_sys;
p_sys->i_rate = i_rate;
if( !p_sys->b_paused )
EsOutProgramsChangeRate( out );
}
void input_EsOutChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
{
es_out_sys_t *p_sys = out->p_sys;
/* XXX the order is important */
if( b_paused )
{
EsOutDecodersChangePause( out, true, i_date );
EsOutProgramChangePause( out, true, i_date );
}
else
{
if( p_sys->i_buffering_extra_initial > 0 )
{
mtime_t i_stream_start;
mtime_t i_system_start;
mtime_t i_stream_duration;
mtime_t i_system_duration;
int i_ret;
i_ret = input_clock_GetState( p_sys->p_pgrm->p_clock,
&i_stream_start, &i_system_start,
&i_stream_duration, &i_system_duration );
if( !i_ret )
{
/* FIXME pcr != exactly what wanted */
const mtime_t i_used = /*(i_stream_duration - p_sys->p_input->i_pts_delay)*/ p_sys->i_buffering_extra_system - p_sys->i_buffering_extra_initial;
i_date -= i_used;
}
p_sys->i_buffering_extra_initial = 0;
p_sys->i_buffering_extra_stream = 0;
p_sys->i_buffering_extra_system = 0;
}
EsOutProgramChangePause( out, false, i_date );
EsOutDecodersChangePause( out, false, i_date );
EsOutProgramsChangeRate( out );
}
p_sys->b_paused = b_paused;
}
void input_EsOutChangePosition( es_out_t *out )
{
es_out_sys_t *p_sys = out->p_sys;
for( int i = 0; i < p_sys->i_es; i++ )
{
es_out_id_t *p_es = p_sys->es[i];
if( !p_es->p_dec )
continue;
input_DecoderStartBuffering( p_es->p_dec );
if( p_es->p_dec_record )
input_DecoderStartBuffering( p_es->p_dec );
}
for( int i = 0; i < p_sys->i_pgrm; i++ )
input_clock_Reset( p_sys->pgrm[i]->p_clock );
p_sys->b_buffering = true;
p_sys->i_buffering_extra_initial = 0;
p_sys->i_buffering_extra_stream = 0;
p_sys->i_buffering_extra_system = 0;
p_sys->i_preroll_end = -1;
}
void input_EsOutFrameNext( es_out_t *out )
{
es_out_sys_t *p_sys = out->p_sys;
es_out_id_t *p_es_video = NULL;
if( p_sys->b_buffering )
{
msg_Warn( p_sys->p_input, "buffering, ignoring 'frame next'" );
return;
}
assert( p_sys->b_paused );
for( int i = 0; i < p_sys->i_es; i++ )
{
es_out_id_t *p_es = p_sys->es[i];
if( p_es->fmt.i_cat == VIDEO_ES && p_es->p_dec )
{
p_es_video = p_es;
break;
}
}
if( !p_es_video )
{
msg_Warn( p_sys->p_input, "No video track selected, ignoring 'frame next'" );
return;
}
mtime_t i_duration;
input_DecoderFrameNext( p_es_video->p_dec, &i_duration );
msg_Dbg( out->p_sys->p_input, "input_EsOutFrameNext consummed %d ms", (int)(i_duration/1000) );
if( i_duration <= 0 )
i_duration = 40*1000;
/* FIXME it is not a clean way ? */
if( p_sys->i_buffering_extra_initial <= 0 )
{
mtime_t i_stream_start;
mtime_t i_system_start;
mtime_t i_stream_duration;
mtime_t i_system_duration;
int i_ret;
i_ret = input_clock_GetState( p_sys->p_pgrm->p_clock,
&i_stream_start, &i_system_start,
&i_stream_duration, &i_system_duration );
if( i_ret )
return;
p_sys->i_buffering_extra_initial = 1 + i_stream_duration - p_sys->p_input->i_pts_delay; /* FIXME < 0 ? */
p_sys->i_buffering_extra_system =
p_sys->i_buffering_extra_stream = p_sys->i_buffering_extra_initial;
}
const int i_rate = input_clock_GetRate( p_sys->p_pgrm->p_clock );
p_sys->b_buffering = true;
p_sys->i_buffering_extra_system += i_duration;
p_sys->i_buffering_extra_stream = p_sys->i_buffering_extra_initial +
( p_sys->i_buffering_extra_system - p_sys->i_buffering_extra_initial ) *
INPUT_RATE_DEFAULT / i_rate;
p_sys->i_preroll_end = -1;
}
void input_EsOutLock( es_out_t *out )
{
vlc_mutex_lock( &out->p_sys->lock );
}
void input_EsOutUnlock( es_out_t *out )
{
vlc_mutex_unlock( &out->p_sys->lock );
}
/*****************************************************************************
*
*****************************************************************************/
......@@ -668,6 +514,83 @@ static int EsOutSetRecord( es_out_t *out, bool b_record )
return VLC_SUCCESS;
}
static void EsOutChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
{
es_out_sys_t *p_sys = out->p_sys;
/* XXX the order is important */
if( b_paused )
{
EsOutDecodersChangePause( out, true, i_date );
EsOutProgramChangePause( out, true, i_date );
}
else
{
if( p_sys->i_buffering_extra_initial > 0 )
{
mtime_t i_stream_start;
mtime_t i_system_start;
mtime_t i_stream_duration;
mtime_t i_system_duration;
int i_ret;
i_ret = input_clock_GetState( p_sys->p_pgrm->p_clock,
&i_stream_start, &i_system_start,
&i_stream_duration, &i_system_duration );
if( !i_ret )
{
/* FIXME pcr != exactly what wanted */
const mtime_t i_used = /*(i_stream_duration - p_sys->p_input->i_pts_delay)*/ p_sys->i_buffering_extra_system - p_sys->i_buffering_extra_initial;
i_date -= i_used;
}
p_sys->i_buffering_extra_initial = 0;
p_sys->i_buffering_extra_stream = 0;
p_sys->i_buffering_extra_system = 0;
}
EsOutProgramChangePause( out, false, i_date );
EsOutDecodersChangePause( out, false, i_date );
EsOutProgramsChangeRate( out );
}
p_sys->b_paused = b_paused;
}
static void EsOutChangeRate( es_out_t *out, int i_rate )
{
es_out_sys_t *p_sys = out->p_sys;
p_sys->i_rate = i_rate;
if( !p_sys->b_paused )
EsOutProgramsChangeRate( out );
}
static void EsOutChangePosition( es_out_t *out )
{
es_out_sys_t *p_sys = out->p_sys;
for( int i = 0; i < p_sys->i_es; i++ )
{
es_out_id_t *p_es = p_sys->es[i];
if( !p_es->p_dec )
continue;
input_DecoderStartBuffering( p_es->p_dec );
if( p_es->p_dec_record )
input_DecoderStartBuffering( p_es->p_dec );
}
for( int i = 0; i < p_sys->i_pgrm; i++ )
input_clock_Reset( p_sys->pgrm[i]->p_clock );
p_sys->b_buffering = true;
p_sys->i_buffering_extra_initial = 0;
p_sys->i_buffering_extra_stream = 0;
p_sys->i_buffering_extra_system = 0;
p_sys->i_preroll_end = -1;
}
static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
......@@ -795,6 +718,77 @@ static void EsOutProgramsChangeRate( es_out_t *out )
input_clock_ChangeRate( p_sys->pgrm[i]->p_clock, p_sys->i_rate );
}
static void EsOutFrameNext( es_out_t *out )
{
es_out_sys_t *p_sys = out->p_sys;
es_out_id_t *p_es_video = NULL;
if( p_sys->b_buffering )
{
msg_Warn( p_sys->p_input, "buffering, ignoring 'frame next'" );
return;
}
assert( p_sys->b_paused );
for( int i = 0; i < p_sys->i_es; i++ )
{
es_out_id_t *p_es = p_sys->es[i];
if( p_es->fmt.i_cat == VIDEO_ES && p_es->p_dec )
{
p_es_video = p_es;
break;
}
}
if( !p_es_video )
{
msg_Warn( p_sys->p_input, "No video track selected, ignoring 'frame next'" );
return;
}
mtime_t i_duration;
input_DecoderFrameNext( p_es_video->p_dec, &i_duration );
msg_Dbg( out->p_sys->p_input, "EsOutFrameNext consummed %d ms", (int)(i_duration/1000) );
if( i_duration <= 0 )
i_duration = 40*1000;
/* FIXME it is not a clean way ? */
if( p_sys->i_buffering_extra_initial <= 0 )
{
mtime_t i_stream_start;
mtime_t i_system_start;
mtime_t i_stream_duration;
mtime_t i_system_duration;
int i_ret;
i_ret = input_clock_GetState( p_sys->p_pgrm->p_clock,
&i_stream_start, &i_system_start,
&i_stream_duration, &i_system_duration );
if( i_ret )
return;
p_sys->i_buffering_extra_initial = 1 + i_stream_duration - p_sys->p_input->i_pts_delay; /* FIXME < 0 ? */
p_sys->i_buffering_extra_system =
p_sys->i_buffering_extra_stream = p_sys->i_buffering_extra_initial;
}
const int i_rate = input_clock_GetRate( p_sys->p_pgrm->p_clock );
p_sys->b_buffering = true;
p_sys->i_buffering_extra_system += i_duration;
p_sys->i_buffering_extra_stream = p_sys->i_buffering_extra_initial +
( p_sys->i_buffering_extra_system - p_sys->i_buffering_extra_initial ) *
INPUT_RATE_DEFAULT / i_rate;
p_sys->i_preroll_end = -1;
}
static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt, const char *psz_language,
bool b_delete )
{
......@@ -1899,6 +1893,8 @@ static void EsOutDel( es_out_t *out, es_out_id_t *es )
if( input_DecoderIsEmpty( es->p_dec ) &&
( !es->p_dec_record || input_DecoderIsEmpty( es->p_dec_record ) ))
break;
/* FIXME there should be a way to have auto deleted es, but there will be
* a problem when another codec of the same type is created (mainly video) */
msleep( 20*1000 );
}
EsUnselect( out, es, es->p_pgrm == p_sys->p_pgrm );
......@@ -2176,7 +2172,7 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
case ES_OUT_RESET_PCR:
msg_Err( p_sys->p_input, "ES_OUT_RESET_PCR called" );
input_EsOutChangePosition( out );
EsOutChangePosition( out );
return VLC_SUCCESS;
case ES_OUT_GET_TS:
......@@ -2331,6 +2327,44 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args )
b = (bool) va_arg( args, int );
return EsOutSetRecord( out, b );
case ES_OUT_SET_PAUSE_STATE:
{
const bool b = (bool)va_arg( args, int );
const mtime_t i_date = (mtime_t) va_arg( args, mtime_t );
EsOutChangePause( out, b, i_date );
return VLC_SUCCESS;
}
case ES_OUT_SET_RATE:
{
const int i_rate = (int)va_arg( args, int );
EsOutChangeRate( out, i_rate );
return VLC_SUCCESS;
}
case ES_OUT_SET_TIME:
{
const mtime_t i_date = (mtime_t)va_arg( args, mtime_t );
assert( i_date == -1 );
EsOutChangePosition( out );
return VLC_SUCCESS;
}
case ES_OUT_SET_FRAME_NEXT:
EsOutFrameNext( out );
return VLC_SUCCESS;
case ES_OUT_LOCK:
vlc_mutex_lock( &p_sys->lock );
return VLC_SUCCESS;
case ES_OUT_UNLOCK:
vlc_mutex_unlock( &p_sys->lock );
return VLC_SUCCESS;
default:
msg_Err( p_sys->p_input, "unknown query in es_out_Control" );
return VLC_EGENERIC;
......
......@@ -47,11 +47,29 @@ enum es_out_query_private_e
/* Check if es_out has still data to play */
ES_OUT_GET_EMPTY, /* arg1=bool* res=cannot fail */
/* */
/* Set delay for a ES category */
ES_OUT_SET_DELAY, /* arg1=es_category_e, res=can fail */
/* */
/* Set record state */
ES_OUT_SET_RECORD_STATE, /* arg1=bool res=can fail */
/* Set pause state */
ES_OUT_SET_PAUSE_STATE, /* arg1=bool arg2=mtime_t res=can fail */
/* Set rate */
ES_OUT_SET_RATE, /* arg1=int i_rate res=can fail */
/* Set a new time */
ES_OUT_SET_TIME, /* arg1=mtime_t res=can fail */
/* Set next frame */
ES_OUT_SET_FRAME_NEXT, /* res=can fail */
/* Lock/Unlock es_out
* XXX es_out is safe without them, but they ensure coherency between
* calls if needed (if es_out is called outside of the main thread) */
ES_OUT_LOCK, /* res=cannot fail */
ES_OUT_UNLOCK, /* res=cannot fail */
};
static inline mtime_t es_out_GetWakeup( es_out_t *p_out )
......@@ -86,15 +104,33 @@ static inline int es_out_SetRecordState( es_out_t *p_out, bool b_record )
{
return es_out_Control( p_out, ES_OUT_SET_RECORD_STATE, b_record );
}
static inline int es_out_SetPauseState( es_out_t *p_out, bool b_paused, mtime_t i_date )
{
return es_out_Control( p_out, ES_OUT_SET_PAUSE_STATE, b_paused, i_date );
}
static inline int es_out_SetRate( es_out_t *p_out, int i_rate )
{
return es_out_Control( p_out, ES_OUT_SET_RATE, i_rate );
}
static inline int es_out_SetTime( es_out_t *p_out, mtime_t i_date )
{
return es_out_Control( p_out, ES_OUT_SET_TIME, i_date );
}
static inline int es_out_SetFrameNext( es_out_t *p_out )
{
return es_out_Control( p_out, ES_OUT_SET_FRAME_NEXT );
}
static inline void es_out_Lock( es_out_t *p_out )
{
int i_ret = es_out_Control( p_out, ES_OUT_LOCK );
assert( !i_ret );
}
static inline void es_out_Unlock( es_out_t *p_out )
{
int i_ret = es_out_Control( p_out, ES_OUT_UNLOCK );
assert( !i_ret );
}
es_out_t *input_EsOutNew( input_thread_t *, int i_rate );
void input_EsOutChangeRate( es_out_t *, int );
void input_EsOutChangePause( es_out_t *, bool b_paused, mtime_t i_date );
void input_EsOutChangePosition( es_out_t * );
void input_EsOutFrameNext( es_out_t * );
void input_EsOutLock( es_out_t * );
void input_EsOutUnlock( es_out_t * );
#endif
......@@ -1511,7 +1511,7 @@ static void ControlPause( input_thread_t *p_input, mtime_t i_control_date )
/* */
if( !i_ret )
input_EsOutChangePause( p_input->p->p_es_out, true, i_control_date );
es_out_SetPauseState( p_input->p->p_es_out, true, i_control_date );
}
static void ControlUnpause( input_thread_t *p_input, mtime_t i_control_date )
{
......@@ -1537,7 +1537,7 @@ static void ControlUnpause( input_thread_t *p_input, mtime_t i_control_date )
/* */
if( !i_ret )
input_EsOutChangePause( p_input->p->p_es_out, false, i_control_date );
es_out_SetPauseState( p_input->p->p_es_out, false, i_control_date );
}
static bool Control( input_thread_t *p_input, int i_type,
......@@ -1549,7 +1549,7 @@ static bool Control( input_thread_t *p_input, int i_type,
if( !p_input )
return b_force_update;
input_EsOutLock( p_input->p->p_es_out );
es_out_Lock( p_input->p->p_es_out );
switch( i_type )
{
......@@ -1584,7 +1584,7 @@ static bool Control( input_thread_t *p_input, int i_type,
if( f_pos < 0.0 ) f_pos = 0.0;
if( f_pos > 1.0 ) f_pos = 1.0;
/* Reset the decoders states and clock sync (before calling the demuxer */
input_EsOutChangePosition( p_input->p->p_es_out );
es_out_SetTime( p_input->p->p_es_out, -1 );
if( demux_Control( p_input->p->input.p_demux, DEMUX_SET_POSITION,
f_pos ) )
{
......@@ -1628,7 +1628,7 @@ static bool Control( input_thread_t *p_input, int i_type,
if( i_time < 0 ) i_time = 0;
/* Reset the decoders states and clock sync (before calling the demuxer */
input_EsOutChangePosition( p_input->p->p_es_out );
es_out_SetTime( p_input->p->p_es_out, -1 );
i_ret = demux_Control( p_input->p->input.p_demux,
DEMUX_SET_TIME, i_time );
......@@ -1787,7 +1787,7 @@ static bool Control( input_thread_t *p_input, int i_type,
/* FIXME do we need a RESET_PCR when !p_input->p->input.b_rescale_ts ? */
if( p_input->p->input.b_rescale_ts )
input_EsOutChangeRate( p_input->p->p_es_out, i_rate );
es_out_SetRate( p_input->p->p_es_out, i_rate );
b_force_update = true;
}
......@@ -1847,7 +1847,7 @@ static bool Control( input_thread_t *p_input, int i_type,
if( i_title >= 0 && i_title < p_input->p->input.i_title )
{
input_EsOutChangePosition( p_input->p->p_es_out );
es_out_SetTime( p_input->p->p_es_out, -1 );
demux_Control( p_demux, DEMUX_SET_TITLE, i_title );
input_ControlVarTitle( p_input, i_title );
......@@ -1867,7 +1867,7 @@ static bool Control( input_thread_t *p_input, int i_type,
if( i_title >= 0 && i_title < p_input->p->input.i_title )
{
input_EsOutChangePosition( p_input->p->p_es_out );
es_out_SetTime( p_input->p->p_es_out, -1 );
access_Control( p_access, ACCESS_SET_TITLE, i_title );
stream_AccessReset( p_input->p->input.p_stream );
......@@ -1914,7 +1914,7 @@ static bool Control( input_thread_t *p_input, int i_type,
p_input->p->input.title[p_demux->info.i_title]->i_seekpoint )
{
input_EsOutChangePosition( p_input->p->p_es_out );
es_out_SetTime( p_input->p->p_es_out, -1 );
demux_Control( p_demux, DEMUX_SET_SEEKPOINT, i_seekpoint );
}
......@@ -1949,7 +1949,7 @@ static bool Control( input_thread_t *p_input, int i_type,
if( i_seekpoint >= 0 && i_seekpoint <
p_input->p->input.title[p_access->info.i_title]->i_seekpoint )
{
input_EsOutChangePosition( p_input->p->p_es_out );
es_out_SetTime( p_input->p->p_es_out, -1 );
access_Control( p_access, ACCESS_SET_SEEKPOINT,
i_seekpoint );
......@@ -2046,7 +2046,7 @@ static bool Control( input_thread_t *p_input, int i_type,
if( p_input->i_state == PAUSE_S )
{
input_EsOutFrameNext( p_input->p->p_es_out );
es_out_SetFrameNext( p_input->p->p_es_out );
}
else if( p_input->i_state == PLAYING_S )
{
......@@ -2065,7 +2065,7 @@ static bool Control( input_thread_t *p_input, int i_type,
break;
}
input_EsOutUnlock( p_input->p->p_es_out );
es_out_Unlock( p_input->p->p_es_out );
return b_force_update;
}
......
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