Commit 843a9b24 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

decoder: add input_DecoderChangeRate()

parent 03ef1dfb
...@@ -111,8 +111,9 @@ struct decoder_owner_sys_t ...@@ -111,8 +111,9 @@ struct decoder_owner_sys_t
/* -- Theses variables need locking on read *and* write -- */ /* -- Theses variables need locking on read *and* write -- */
/* Preroll */ /* Preroll */
int64_t i_preroll_end; int64_t i_preroll_end;
/* Pause */ /* Pause & Rate */
mtime_t pause_date; mtime_t pause_date;
float rate;
unsigned frames_countdown; unsigned frames_countdown;
bool paused; bool paused;
...@@ -1186,8 +1187,6 @@ static int DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio, ...@@ -1186,8 +1187,6 @@ static int DecoderPlayAudio( decoder_t *p_dec, block_t *p_audio,
&& i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE && i_rate <= INPUT_RATE_DEFAULT*AOUT_MAX_INPUT_RATE
&& !DecoderTimedWait( p_dec, p_audio->i_pts - AOUT_MAX_PREPARE_TIME ) ) && !DecoderTimedWait( p_dec, p_audio->i_pts - AOUT_MAX_PREPARE_TIME ) )
{ {
aout_DecChangeRate( p_aout, ((float)i_rate) / 1000.f );
int status = aout_DecPlay( p_aout, p_audio ); int status = aout_DecPlay( p_aout, p_audio );
if( status == AOUT_DEC_CHANGED ) if( status == AOUT_DEC_CHANGED )
{ {
...@@ -1536,6 +1535,7 @@ static void *DecoderThread( void *p_data ) ...@@ -1536,6 +1535,7 @@ static void *DecoderThread( void *p_data )
{ {
decoder_t *p_dec = (decoder_t *)p_data; decoder_t *p_dec = (decoder_t *)p_data;
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
float rate = 1.f;
bool paused = false; bool paused = false;
/* The decoder's main loop */ /* The decoder's main loop */
...@@ -1585,6 +1585,21 @@ static void *DecoderThread( void *p_data ) ...@@ -1585,6 +1585,21 @@ static void *DecoderThread( void *p_data )
continue; continue;
} }
if( rate != p_owner->rate )
{
int canc = vlc_savecancel();
rate = p_owner->rate;
vlc_fifo_Unlock( p_owner->p_fifo );
msg_Dbg( p_dec, "changing rate: %f", rate );
if( p_owner->p_aout != NULL )
aout_DecChangeRate( p_owner->p_aout, rate );
vlc_restorecancel( canc );
vlc_fifo_Lock( p_owner->p_fifo );
}
if( p_owner->paused && p_owner->frames_countdown == 0 ) if( p_owner->paused && p_owner->frames_countdown == 0 )
{ /* Wait for resumption from pause */ { /* Wait for resumption from pause */
p_owner->b_idle = true; p_owner->b_idle = true;
...@@ -1684,6 +1699,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent, ...@@ -1684,6 +1699,7 @@ static decoder_t * CreateDecoder( vlc_object_t *p_parent,
p_owner->b_fmt_description = false; p_owner->b_fmt_description = false;
p_owner->p_description = NULL; p_owner->p_description = NULL;
p_owner->rate = 1.f;
p_owner->paused = false; p_owner->paused = false;
p_owner->pause_date = VLC_TS_INVALID; p_owner->pause_date = VLC_TS_INVALID;
p_owner->frames_countdown = 0; p_owner->frames_countdown = 0;
...@@ -2272,6 +2288,16 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date ) ...@@ -2272,6 +2288,16 @@ void input_DecoderChangePause( decoder_t *p_dec, bool b_paused, mtime_t i_date )
vlc_fifo_Unlock( p_owner->p_fifo ); vlc_fifo_Unlock( p_owner->p_fifo );
} }
void input_DecoderChangeRate( decoder_t *dec, float rate )
{
decoder_owner_sys_t *owner = dec->p_owner;
vlc_fifo_Lock( owner->p_fifo );
owner->rate = rate;
vlc_fifo_Signal( owner->p_fifo );
vlc_fifo_Unlock( owner->p_fifo );
}
void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay ) void input_DecoderChangeDelay( decoder_t *p_dec, mtime_t i_delay )
{ {
decoder_owner_sys_t *p_owner = p_dec->p_owner; decoder_owner_sys_t *p_owner = p_dec->p_owner;
......
...@@ -38,6 +38,15 @@ decoder_t *input_DecoderNew( input_thread_t *, es_format_t *, input_clock_t *, ...@@ -38,6 +38,15 @@ decoder_t *input_DecoderNew( input_thread_t *, es_format_t *, input_clock_t *,
*/ */
void input_DecoderChangePause( decoder_t *, bool b_paused, mtime_t i_date ); void input_DecoderChangePause( decoder_t *, bool b_paused, mtime_t i_date );
/**
* Changes the decoder rate.
*
* This function changes rate of the intended playback speed to nominal speed.
* \param dec decoder
* \param rate playback rate (default is 1)
*/
void input_DecoderChangeRate( decoder_t *dec, float rate );
/** /**
* This function changes the delay. * This function changes the delay.
*/ */
......
...@@ -588,9 +588,18 @@ static void EsOutChangePause( es_out_t *out, bool b_paused, mtime_t i_date ) ...@@ -588,9 +588,18 @@ static void EsOutChangePause( es_out_t *out, bool b_paused, mtime_t i_date )
static void EsOutChangeRate( es_out_t *out, int i_rate ) static void EsOutChangeRate( es_out_t *out, int i_rate )
{ {
es_out_sys_t *p_sys = out->p_sys; es_out_sys_t *p_sys = out->p_sys;
float rate = (float)i_rate / (float)INPUT_RATE_DEFAULT;
p_sys->i_rate = i_rate; p_sys->i_rate = i_rate;
EsOutProgramsChangeRate( out ); EsOutProgramsChangeRate( out );
for( int i = 0; i < p_sys->i_es; i++ )
{
es_out_id_t *es = p_sys->es[i];
if( es->p_dec != NULL )
input_DecoderChangeRate( es->p_dec, rate );
}
} }
static void EsOutChangePosition( es_out_t *out ) static void EsOutChangePosition( es_out_t *out )
...@@ -1683,12 +1692,16 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es ) ...@@ -1683,12 +1692,16 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es )
{ {
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;
decoder_t *dec;
p_es->p_dec = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_input_clock, input_priv(p_input)->p_sout ); dec = input_DecoderNew( p_input, &p_es->fmt, p_es->p_pgrm->p_input_clock,
if( p_es->p_dec ) input_priv(p_input)->p_sout );
if( dec != NULL )
{ {
input_DecoderChangeRate( dec, p_sys->i_rate );
if( p_sys->b_buffering ) if( p_sys->b_buffering )
input_DecoderStartWait( p_es->p_dec ); input_DecoderStartWait( dec );
if( !p_es->p_master && p_sys->p_sout_record ) if( !p_es->p_master && p_sys->p_sout_record )
{ {
...@@ -1697,6 +1710,7 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es ) ...@@ -1697,6 +1710,7 @@ static void EsCreateDecoder( es_out_t *out, es_out_id_t *p_es )
input_DecoderStartWait( p_es->p_dec_record ); input_DecoderStartWait( p_es->p_dec_record );
} }
} }
p_es->p_dec = dec;
EsOutDecoderChangeDelay( out, p_es ); EsOutDecoderChangeDelay( out, p_es );
} }
......
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