Commit 9df1a97b authored by Sam Hocevar's avatar Sam Hocevar

* ./src/video_output/video_output.c: when the video output hasn't received

    a new picture for a while, it redisplays the last displayed one. This will
    be useful for DVD menus, but also solves the "picture becomes black when
    vlc is paused" issue.
parent ae1fb706
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* thread, and destroy a previously oppened video output thread. * thread, and destroy a previously oppened video output thread.
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: video_output.c,v 1.179 2002/05/28 18:34:42 stef Exp $ * $Id: video_output.c,v 1.180 2002/05/29 18:39:14 sam Exp $
* *
* Authors: Vincent Seguin <seguin@via.ecp.fr> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* *
...@@ -484,10 +484,12 @@ static int InitThread( vout_thread_t *p_vout ) ...@@ -484,10 +484,12 @@ static int InitThread( vout_thread_t *p_vout )
static void RunThread( vout_thread_t *p_vout) static void RunThread( vout_thread_t *p_vout)
{ {
int i_index; /* index in heap */ int i_index; /* index in heap */
int i_idle_loops = 0; /* loops without displaying a picture */
mtime_t current_date; /* current date */ mtime_t current_date; /* current date */
mtime_t display_date; /* display date */ mtime_t display_date; /* display date */
picture_t * p_picture; /* picture pointer */ picture_t * p_picture; /* picture pointer */
picture_t * p_last_picture = NULL; /* last picture */
picture_t * p_directbuffer; /* direct buffer to display */ picture_t * p_directbuffer; /* direct buffer to display */
subpicture_t * p_subpic; /* subpicture pointer */ subpicture_t * p_subpic; /* subpicture pointer */
...@@ -530,9 +532,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -530,9 +532,7 @@ static void RunThread( vout_thread_t *p_vout)
*/ */
p_picture = NULL; p_picture = NULL;
for( i_index = 0; for( i_index = 0; i_index < I_RENDERPICTURES; i_index++ )
i_index < I_RENDERPICTURES;
i_index++ )
{ {
if( (PP_RENDERPICTURE[i_index]->i_status == READY_PICTURE) if( (PP_RENDERPICTURE[i_index]->i_status == READY_PICTURE)
&& ( (p_picture == NULL) || && ( (p_picture == NULL) ||
...@@ -545,11 +545,45 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -545,11 +545,45 @@ static void RunThread( vout_thread_t *p_vout)
if( p_picture != NULL ) if( p_picture != NULL )
{ {
/* If we met the last picture, parse again to see whether there is
* a more appropriate one. */
if( p_picture == p_last_picture )
{
for( i_index = 0; i_index < I_RENDERPICTURES; i_index++ )
{
if( (PP_RENDERPICTURE[i_index]->i_status == READY_PICTURE)
&& (PP_RENDERPICTURE[i_index] != p_last_picture)
&& ((p_picture == p_last_picture) ||
(PP_RENDERPICTURE[i_index]->date < display_date)) )
{
p_picture = PP_RENDERPICTURE[i_index];
display_date = p_picture->date;
}
}
}
/* If we found better than the last picture, destroy it */
if( p_last_picture && p_picture != p_last_picture )
{
vlc_mutex_lock( &p_vout->picture_lock );
if( p_last_picture->i_refcount )
{
p_last_picture->i_status = DISPLAYED_PICTURE;
}
else
{
p_last_picture->i_status = DESTROYED_PICTURE;
p_vout->i_heap_size--;
}
vlc_mutex_unlock( &p_vout->picture_lock );
}
/* Compute FPS rate */ /* Compute FPS rate */
p_vout->p_fps_sample[ p_vout->c_fps_samples++ % VOUT_FPS_SAMPLES ] p_vout->p_fps_sample[ p_vout->c_fps_samples++ % VOUT_FPS_SAMPLES ]
= display_date; = display_date;
if( !p_picture->b_force && if( !p_picture->b_force &&
p_picture != p_last_picture &&
display_date < current_date + p_vout->render_time ) display_date < current_date + p_vout->render_time )
{ {
/* Picture is late: it will be destroyed and the thread /* Picture is late: it will be destroyed and the thread
...@@ -575,7 +609,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -575,7 +609,7 @@ static void RunThread( vout_thread_t *p_vout)
} }
#if 0 #if 0
/* Removed because it causes problems for some people --Meuuh */ /* Removed because it causes problems for some people --Meuuh */
else if( display_date > current_date + VOUT_BOGUS_DELAY ) if( display_date > current_date + VOUT_BOGUS_DELAY )
{ {
/* Picture is waaay too early: it will be destroyed */ /* Picture is waaay too early: it will be destroyed */
vlc_mutex_lock( &p_vout->picture_lock ); vlc_mutex_lock( &p_vout->picture_lock );
...@@ -598,7 +632,7 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -598,7 +632,7 @@ static void RunThread( vout_thread_t *p_vout)
continue; continue;
} }
#endif #endif
else if( display_date > current_date + VOUT_DISPLAY_DELAY ) if( display_date > current_date + VOUT_DISPLAY_DELAY )
{ {
/* A picture is ready to be rendered, but its rendering date /* A picture is ready to be rendered, but its rendering date
* is far from the current one so the thread will perform an * is far from the current one so the thread will perform an
...@@ -607,6 +641,25 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -607,6 +641,25 @@ static void RunThread( vout_thread_t *p_vout)
p_picture = NULL; p_picture = NULL;
display_date = 0; display_date = 0;
} }
else if( p_picture == p_last_picture )
{
if( i_idle_loops < 4 )
{
/* We are asked to repeat the previous picture, but we first
* wait for a couple of idle loops */
p_picture = NULL;
display_date = 0;
}
else
{
//intf_WarnMsg( 6, "vout info: duplicating picture" );
}
}
}
if( p_picture == NULL )
{
i_idle_loops++;
} }
/* /*
...@@ -663,18 +716,13 @@ static void RunThread( vout_thread_t *p_vout) ...@@ -663,18 +716,13 @@ static void RunThread( vout_thread_t *p_vout)
/* Display the direct buffer returned by vout_RenderPicture */ /* Display the direct buffer returned by vout_RenderPicture */
p_vout->pf_display( p_vout, p_directbuffer ); p_vout->pf_display( p_vout, p_directbuffer );
/* Remove picture from heap */ /* Reinitialize idle loop count */
vlc_mutex_lock( &p_vout->picture_lock ); i_idle_loops = 0;
if( p_picture->i_refcount )
{ /* Tell the vout this was the last picture and that it does not
p_picture->i_status = DISPLAYED_PICTURE; * need to be forced anymore. */
} p_last_picture = p_picture;
else p_last_picture->b_force = 0;
{
p_picture->i_status = DESTROYED_PICTURE;
p_vout->i_heap_size--;
}
vlc_mutex_unlock( &p_vout->picture_lock );
} }
/* /*
......
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