[vlc-devel] commit: Added "next frame" support. (Laurent Aimar )
git version control
git at videolan.org
Wed Oct 22 22:22:07 CEST 2008
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Wed Oct 22 21:55:06 2008 +0200| [b0782ad7dcfd29f942098e3160ced83a9ade6dc7] | committer: Laurent Aimar
Added "next frame" support.
It will work most of the time.
Subtitle are not correctly handled.
It will be ignored if no video.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b0782ad7dcfd29f942098e3160ced83a9ade6dc7
---
src/input/es_out.c | 120 +++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 105 insertions(+), 15 deletions(-)
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 790269c..986ada5 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -138,11 +138,17 @@ struct es_out_sys_t
/* Rate used for clock */
int i_rate;
+ /* */
+ bool b_paused;
+
/* Current preroll */
- int64_t i_preroll_end;
+ mtime_t i_preroll_end;
/* Used for buffering */
bool b_buffering;
+ mtime_t i_buffering_extra_initial;
+ mtime_t i_buffering_extra_stream;
+ mtime_t i_buffering_extra_system;
/* Record */
sout_instance_t *p_sout_record;
@@ -162,6 +168,7 @@ static void EsUnselect( es_out_t *out, es_out_id_t *es, bool b_update );
static void EsOutDecoderChangeDelay( es_out_t *out, es_out_id_t *p_es );
static void EsOutDecodersChangePause( es_out_t *out, bool b_paused, mtime_t i_date );
static void EsOutProgramChangePause( es_out_t *out, bool b_paused, mtime_t i_date );
+static void EsOutProgramsChangeRate( es_out_t *out );
static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced );
static char *LanguageGetName( const char *psz_code );
static char *LanguageGetCode( const char *psz_lang );
@@ -280,9 +287,14 @@ es_out_t *input_EsOutNew( input_thread_t *p_input, int i_rate )
p_sys->i_audio_delay= 0;
p_sys->i_spu_delay = 0;
+ p_sys->b_paused = false;
+
p_sys->i_rate = i_rate;
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;
p_sys->p_sout_record = NULL;
@@ -385,12 +397,11 @@ mtime_t input_EsOutGetWakeup( es_out_t *out )
void input_EsOutChangeRate( es_out_t *out, int i_rate )
{
es_out_sys_t *p_sys = out->p_sys;
- int i;
p_sys->i_rate = i_rate;
- for( i = 0; i < p_sys->i_pgrm; i++ )
- input_clock_ChangeRate( p_sys->pgrm[i]->p_clock, i_rate );
+ if( !p_sys->b_paused )
+ EsOutProgramsChangeRate( out );
}
int input_EsOutSetRecord( es_out_t *out, bool b_record )
@@ -480,6 +491,8 @@ void input_EsOutSetDelay( es_out_t *out, int i_cat, int64_t i_delay )
}
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 )
{
@@ -488,9 +501,32 @@ void input_EsOutChangePause( es_out_t *out, bool b_paused, mtime_t 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 )
{
@@ -513,6 +549,9 @@ void input_EsOutChangePosition( es_out_t *out )
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;
}
@@ -549,6 +588,14 @@ 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];
@@ -566,15 +613,43 @@ void input_EsOutFrameNext( es_out_t *out )
return;
}
-#if 0
- input_DecoderFrameNext( p_es_video->p_dec );
- if( !p_sys->b_buffering )
+ 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 )
{
- TODO();
+ 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;
}
-#endif
- msg_Err( out->p_sys->p_input, "TODO input_EsOutFrameNext" );
+ 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;
}
/*****************************************************************************
@@ -600,9 +675,14 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
if( p_sys->i_preroll_end >= 0 )
i_preroll_duration = __MAX( p_sys->i_preroll_end - i_stream_start, 0 );
- if( i_stream_duration <= p_sys->p_input->i_pts_delay + i_preroll_duration && !b_forced )
+ const mtime_t i_buffering_duration = p_sys->p_input->i_pts_delay +
+ i_preroll_duration +
+ p_sys->i_buffering_extra_stream;
+
+ if( i_stream_duration <= i_buffering_duration && !b_forced )
{
- msg_Dbg( p_sys->p_input, "Buffering %d%%", (int)(100 * i_stream_duration / ( p_sys->p_input->i_pts_delay + i_preroll_duration )) );
+ msg_Dbg( p_sys->p_input, "Buffering %d%%",
+ (int)(100 * i_stream_duration / i_buffering_duration ) );
return;
}
@@ -611,6 +691,12 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
p_sys->b_buffering = false;
p_sys->i_preroll_end = -1;
+ if( p_sys->i_buffering_extra_initial > 0 )
+ {
+ /* FIXME wrong ? */
+ return;
+ }
+
const mtime_t i_decoder_buffering_start = mdate();
for( int i = 0; i < p_sys->i_es; i++ )
{
@@ -629,7 +715,7 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
const mtime_t i_ts_delay = 10*1000 + /* FIXME CLEANUP thread wake up time*/
mdate();
//msg_Dbg( p_sys->p_input, "==> %lld", i_ts_delay - p_sys->p_input->i_pts_delay );
- input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_clock, i_ts_delay - p_sys->p_input->i_pts_delay - i_preroll_duration );
+ input_clock_ChangeSystemOrigin( p_sys->p_pgrm->p_clock, i_ts_delay - i_buffering_duration );
for( int i = 0; i < p_sys->i_es; i++ )
{
@@ -652,8 +738,6 @@ static void EsOutDecodersChangePause( es_out_t *out, bool b_paused, mtime_t i_da
{
es_out_id_t *es = p_sys->es[i];
- /* Send a dummy block to let decoder know that
- * there is a discontinuity */
if( es->p_dec )
{
input_DecoderChangePause( es->p_dec, b_paused, i_date );
@@ -688,7 +772,13 @@ static void EsOutDecoderChangeDelay( es_out_t *out, es_out_id_t *p_es )
input_DecoderChangeDelay( p_es->p_dec_record, i_delay );
}
}
+static void EsOutProgramsChangeRate( es_out_t *out )
+{
+ es_out_sys_t *p_sys = out->p_sys;
+ for( int i = 0; i < p_sys->i_pgrm; i++ )
+ input_clock_ChangeRate( p_sys->pgrm[i]->p_clock, p_sys->i_rate );
+}
static void EsOutESVarUpdateGeneric( es_out_t *out, int i_id, es_format_t *fmt, const char *psz_language,
bool b_delete )
More information about the vlc-devel
mailing list