- if( !p_vout->p->b_picture_empty )
- {
- p_vout->p->b_picture_empty = true;
- vlc_cond_signal( &p_vout->p->picture_wait );
- }
- }
-
- display_date = 0;
- if( p_picture )
- {
- display_date = p_picture->date;
-
- /* If we found better than the last picture, destroy it */
- if( p_last && p_picture != p_last )
- {
- vout_UsePictureLocked( p_vout, p_last );
- p_vout->p->p_picture_displayed = p_last = NULL;
- }
-
- /* Compute FPS rate */
- p_vout->p->p_fps_sample[ p_vout->p->c_fps_samples++ % VOUT_FPS_SAMPLES ] = display_date;
-
- if( !p_vout->p->b_paused && display_date > current_date + VOUT_DISPLAY_DELAY )
- {
- /* A picture is ready to be rendered, but its rendering date
- * is far from the current one so the thread will perform an
- * empty loop as if no picture were found. The picture state
- * is unchanged */
- p_picture = NULL;
- display_date = 0;
- }
- else if( p_picture == p_last )
- {
- /* We are asked to repeat the previous picture, but we first
- * wait for a couple of idle loops */
- if( i_idle_loops < 4 )
- {
- p_picture = NULL;
- display_date = 0;
- }
- else
- {
- /* We set the display date to something high, otherwise
- * we'll have lots of problems with late pictures */
- display_date = current_date + p_vout->p->render_time;
- }
- }
- else if( p_vout->p->b_paused && display_date > current_date + VOUT_DISPLAY_DELAY )
- {
- display_date = current_date + VOUT_DISPLAY_DELAY;
- }
-
- if( p_picture )
- {
- if( p_picture->date > 1 )
- {
- p_vout->p->i_picture_displayed_date = p_picture->date;
- if( p_picture != p_last && !p_vout->p->b_picture_displayed )
- {
- p_vout->p->b_picture_displayed = true;
- vlc_cond_signal( &p_vout->p->picture_wait );
- }
- }
- p_vout->p->p_picture_displayed = p_picture;
- }
- }
-
- /* */
- const int i_postproc_type = p_vout->p->i_picture_qtype;
- const int i_postproc_state = (p_vout->p->i_picture_qtype != QTYPE_NONE) - (i_picture_qtype_last != QTYPE_NONE);
-
- const bool b_picture_interlaced = p_vout->p->b_picture_interlaced;
- const int i_picture_interlaced_state = (!!p_vout->p->b_picture_interlaced) - (!!b_picture_interlaced_last);
-
- vlc_mutex_unlock( &p_vout->picture_lock );
-
- if( p_picture == NULL )
- i_idle_loops++;
-
- p_filtered_picture = NULL;
- if( p_picture )
- p_filtered_picture = filter_chain_VideoFilter( p_vout->p->p_vf2_chain,
- p_picture );
-
- const bool b_snapshot = vout_snapshot_IsRequested( &p_vout->p->snapshot );
-
- /*
- * Check for subpictures to display
- */
- mtime_t spu_render_time;
- if( p_vout->p->b_paused )
- spu_render_time = p_vout->p->i_pause_date;
- else if( p_picture )
- spu_render_time = p_picture->date > 1 ? p_picture->date : mdate();
- else
- spu_render_time = 0;
-
- subpicture_t *p_subpic = spu_SortSubpictures( p_vout->p_spu,
- spu_render_time,
- b_snapshot );
- /*
- * Perform rendering
- */
- vout_statistic_Update( &p_vout->p->statistic, 1, 0 );
- p_directbuffer = vout_RenderPicture( p_vout,
- p_filtered_picture, p_subpic,
- spu_render_time );
-
- /*
- * Take a snapshot if requested
- */
- if( p_directbuffer && b_snapshot )
- vout_snapshot_Set( &p_vout->p->snapshot,
- &p_vout->fmt_out, p_directbuffer );
-
- /*
- * Call the plugin-specific rendering method if there is one
- */
- if( p_filtered_picture != NULL && p_directbuffer != NULL && p_vout->pf_render )
- {
- /* Render the direct buffer returned by vout_RenderPicture */
- p_vout->pf_render( p_vout, p_directbuffer );
- }
-
- /*
- * Sleep, wake up
- */
- if( display_date != 0 && p_directbuffer != NULL )
- {
- mtime_t current_render_time = mdate() - current_date;
- /* if render time is very large we don't include it in the mean */
- if( current_render_time < p_vout->p->render_time +
- VOUT_DISPLAY_DELAY )
- {
- /* Store render time using a sliding mean weighting to
- * current value in a 3 to 1 ratio*/
- p_vout->p->render_time *= 3;
- p_vout->p->render_time += current_render_time;
- p_vout->p->render_time >>= 2;
- }
- else
- msg_Dbg( p_vout, "skipped big render time %d > %d", (int) current_render_time,
- (int) (p_vout->p->render_time +VOUT_DISPLAY_DELAY ) ) ;
- }
-
- /* Give back change lock */
- vlc_mutex_unlock( &p_vout->change_lock );
-
- /* Sleep a while or until a given date */
- if( display_date != 0 )
- {
- /* If there are *vout* filters in the chain, better give them the picture
- * in advance */
- if( !p_vout->p->psz_filter_chain || !*p_vout->p->psz_filter_chain )
- {
- mwait( display_date - VOUT_MWAIT_TOLERANCE );
- }
- }
- else
- {
- /* Wait until a frame is being sent or a spurious wakeup (not a problem here) */
- vlc_mutex_lock( &p_vout->picture_lock );
- vlc_cond_timedwait( &p_vout->p->picture_wait, &p_vout->picture_lock, current_date + VOUT_IDLE_SLEEP );
- vlc_mutex_unlock( &p_vout->picture_lock );
- }
-
- /* On awakening, take back lock and send immediately picture
- * to display. */
- /* Note: p_vout->p->b_done could be true here and now */
- vlc_mutex_lock( &p_vout->change_lock );
-
- /*
- * Display the previously rendered picture
- */
- if( p_filtered_picture != NULL && p_directbuffer != NULL )
- {
- /* Display the direct buffer returned by vout_RenderPicture */
- if( p_vout->pf_display )
- p_vout->pf_display( p_vout, p_directbuffer );
-
- /* Tell the vout this was the last picture and that it does not
- * need to be forced anymore. */
- p_picture->b_force = false;
- }
-
- /* Drop the filtered picture if created by video filters */
- if( p_filtered_picture != NULL && p_filtered_picture != p_picture )
- {
- vlc_mutex_lock( &p_vout->picture_lock );
- vout_UsePictureLocked( p_vout, p_filtered_picture );
- vlc_mutex_unlock( &p_vout->picture_lock );
- }
-
- if( p_picture != NULL )
- {
- /* Reinitialize idle loop count */
- i_idle_loops = 0;
- }
-
- /*
- * Check events and manage thread
- */
- if( p_vout->pf_manage && p_vout->pf_manage( p_vout ) )
- {
- /* A fatal error occurred, and the thread must terminate
- * immediately, without displaying anything - setting b_error to 1
- * causes the immediate end of the main while() loop. */
- // FIXME pf_end
- p_vout->b_error = 1;
- break;
- }
-
- while( p_vout->i_changes & VOUT_ON_TOP_CHANGE )
- {
- p_vout->i_changes &= ~VOUT_ON_TOP_CHANGE;
- vlc_mutex_unlock( &p_vout->change_lock );
- vout_Control( p_vout, VOUT_SET_STAY_ON_TOP, p_vout->b_on_top );
- vlc_mutex_lock( &p_vout->change_lock );
- }
-
- if( p_vout->i_changes & VOUT_SIZE_CHANGE )
- {
- /* this must only happen when the vout plugin is incapable of
- * rescaling the picture itself. In this case we need to destroy
- * the current picture buffers and recreate new ones with the right
- * dimensions */
- int i;
-
- p_vout->i_changes &= ~VOUT_SIZE_CHANGE;
-
- assert( !p_vout->p->b_direct );
-
- ChromaDestroy( p_vout );
-
- vlc_mutex_lock( &p_vout->picture_lock );
-
- p_vout->pf_end( p_vout );
-
- p_vout->p->p_picture_displayed = NULL;
- for( i = 0; i < I_OUTPUTPICTURES; i++ )
- p_vout->p_picture[ i ].i_status = FREE_PICTURE;
- vlc_cond_signal( &p_vout->p->picture_wait );
-
- I_OUTPUTPICTURES = 0;
-
- if( p_vout->pf_init( p_vout ) )
- {
- msg_Err( p_vout, "cannot resize display" );
- /* FIXME: pf_end will be called again in CleanThread()? */
- p_vout->b_error = 1;
- }
-
- vlc_mutex_unlock( &p_vout->picture_lock );
-
- /* Need to reinitialise the chroma plugin. Since we might need
- * resizing too and it's not sure that we already had it,
- * recreate the chroma plugin chain from scratch. */
- /* dionoea */
- if( ChromaCreate( p_vout ) )
- {
- msg_Err( p_vout, "WOW THIS SUCKS BIG TIME!!!!!" );
- p_vout->b_error = 1;
- }
- if( p_vout->b_error )
- break;
- }
-
- if( p_vout->i_changes & VOUT_PICTURE_BUFFERS_CHANGE )
- {
- /* This happens when the picture buffers need to be recreated.
- * This is useful on multimonitor displays for instance.
- *
- * Warning: This only works when the vout creates only 1 picture
- * buffer!! */
- p_vout->i_changes &= ~VOUT_PICTURE_BUFFERS_CHANGE;
-
- if( !p_vout->p->b_direct )
- ChromaDestroy( p_vout );
-
- vlc_mutex_lock( &p_vout->picture_lock );