]> git.sesse.net Git - vlc/blobdiff - src/video_output/video_output.c
Nettoyage.
[vlc] / src / video_output / video_output.c
index 374aba1ee10dfc6f982e4d7b3975319d1eac5178..cf6685a64813d4f989a8921687cf2b8dc6d2ec69 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
-#ifdef VIDEO_X11
-#include <X11/Xlib.h>                           /* for video_sys.h in X11 mode */
-#endif
-
 #include "common.h"
 #include "config.h"
 #include "mtime.h"
@@ -37,10 +33,11 @@ static int      InitThread              ( vout_thread_t *p_vout );
 static void     RunThread               ( vout_thread_t *p_vout );
 static void     ErrorThread             ( vout_thread_t *p_vout );
 static void     EndThread               ( vout_thread_t *p_vout );
-static void     RenderPicture           ( vout_thread_t *p_vout, picture_t *p_pic );
-static void     RenderPictureInfo       ( vout_thread_t *p_vout, picture_t *p_pic );
-static int      RenderIdle              ( vout_thread_t *p_vout );
-static int      RenderInfo              ( vout_thread_t *p_vout );
+static void     RenderBlank             ( vout_thread_t *p_vout );
+static int      RenderPicture           ( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank );
+static int      RenderPictureInfo       ( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank );
+static int      RenderIdle              ( vout_thread_t *p_vout, boolean_t b_blank );
+static int      RenderInfo              ( vout_thread_t *p_vout, boolean_t b_balnk );
 static int      Manage                  ( vout_thread_t *p_vout );
 
 /*******************************************************************************
@@ -51,12 +48,8 @@ static int      Manage                  ( vout_thread_t *p_vout );
  * If pi_status is NULL, then the function will block until the thread is ready.
  * If not, it will be updated using one of the THREAD_* constants.
  *******************************************************************************/
-vout_thread_t * vout_CreateThread               ( 
-#ifdef VIDEO_X11
-                                                  char *psz_display, Window root_window, 
-#endif
-                                                  int i_width, int i_height, int *pi_status 
-                                                )
+vout_thread_t * vout_CreateThread               ( char *psz_display, int i_root_window, 
+                                                  int i_width, int i_height, int *pi_status )
 {
     vout_thread_t * p_vout;                               /* thread descriptor */
     int             i_status;                                 /* thread status */
@@ -100,11 +93,7 @@ vout_thread_t * vout_CreateThread               (
    
     /* Create and initialize system-dependant method - this function issues its
      * own error messages */
-    if( vout_SysCreate( p_vout
-#if defined(VIDEO_X11)
-                        , psz_display, root_window 
-#endif
-        ) )
+    if( vout_SysCreate( p_vout, psz_display, i_root_window ) )
     {
       free( p_vout );
       return( NULL );
@@ -116,15 +105,21 @@ vout_thread_t * vout_CreateThread               (
 
 #ifdef STATS
     /* Initialize statistics fields */
-    p_vout->loop_time           = 0;    
+    p_vout->render_time           = 0;    
     p_vout->c_fps_samples       = 0;    
 #endif      
 
+    /* Initialize running properties */
+    p_vout->i_changes           = 0;
+    p_vout->last_picture_date   = 0;
+    p_vout->last_display_date   = 0;
+
     /* Create thread and set locks */
     vlc_mutex_init( &p_vout->picture_lock );
     vlc_mutex_init( &p_vout->subtitle_lock );    
-    if( vlc_thread_create( &p_vout->thread_id, "video output", 
-                          (void *) RunThread, (void *) p_vout) )
+    vlc_mutex_init( &p_vout->change_lock );    
+    vlc_mutex_lock( &p_vout->change_lock );    
+    if( vlc_thread_create( &p_vout->thread_id, "video output", (void *) RunThread, (void *) p_vout) )
     {
         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
        vout_SysDestroy( p_vout );
@@ -615,7 +610,6 @@ static void RunThread( vout_thread_t *p_vout)
                 p_pic =         NULL;                
            }
         }
-
               
         /*
          * Perform rendering, sleep and display rendered picture
@@ -625,13 +619,12 @@ static void RunThread( vout_thread_t *p_vout)
             /* A picture is ready to be displayed : render it */
             if( p_vout->b_active )
             {                    
-                RenderPicture( p_vout, p_pic );
+                b_display = RenderPicture( p_vout, p_pic, 1 );
                 if( p_vout->b_info )
                 {
-                    RenderPictureInfo( p_vout, p_pic );
-                    RenderInfo( p_vout );                    
+                    b_display |= RenderPictureInfo( p_vout, p_pic, b_display );
+                    b_display |= RenderInfo( p_vout, b_display );                    
                 }                    
-                b_display = 1;                    
             }
             else
             {
@@ -646,17 +639,26 @@ static void RunThread( vout_thread_t *p_vout)
         else
         {
             /* No picture. However, an idle screen may be ready to display */
-            b_display = p_vout->b_active && (                   RenderIdle( p_vout ) | 
-                                            ( p_vout->b_info && RenderInfo( p_vout ) ));
+            if( p_vout->b_active )
+            {                
+                b_display = RenderIdle( p_vout, 1 );
+                if( p_vout->b_info )
+                {                    
+                    b_display |= RenderInfo( p_vout, b_display );
+                }        
+            }
+            else
+            {
+                b_display = 0;                
+            }            
         }
 
+        /* Give back change lock */
+        vlc_mutex_unlock( &p_vout->change_lock );        
+
         /* Sleep a while or until a given date */
         if( p_pic )
         {
-#ifdef STATS
-            /* Computes loop time */
-            p_vout->loop_time = mdate() - current_date;            
-#endif
             mwait( pic_date );
         }
         else
@@ -664,8 +666,10 @@ static void RunThread( vout_thread_t *p_vout)
             msleep( VOUT_IDLE_SLEEP );                
         }            
 
-        /* On awakening, send immediately picture to display */
-        if( b_display && p_vout->b_active )
+        /* On awakening, take back lock and send immediately picture to display */
+        vlc_mutex_lock( &p_vout->change_lock );        
+        if( b_display && p_vout->b_active && 
+            !(p_vout->i_changes & VOUT_NODISPLAY_CHANGE) )
         {
             vout_SysDisplay( p_vout );
         }
@@ -748,6 +752,48 @@ static void EndThread( vout_thread_t *p_vout )
     *pi_status = THREAD_OVER;    
 }
 
+/*******************************************************************************
+ * RenderBlank: render a blank screen
+ *******************************************************************************
+ * This function is called by all other rendering functions when they arrive on
+ * a non blanked screen.
+ *******************************************************************************/
+static void RenderBlank( vout_thread_t *p_vout )
+{
+    int  i_index;                                    /* current 32 bits sample */    
+    int  i_width;                                 /* number of 32 bits samples */    
+    u32 *p_pic;                                  /* pointer to 32 bits samples */
+    
+    /* Initialize variables */
+    p_pic =     vout_SysGetPicture( p_vout );
+    i_width =   p_vout->i_bytes_per_line * p_vout->i_height / 128;
+
+    /* Clear beginning of screen by 128 bytes blocks */
+    for( i_index = 0; i_index < i_width; i_index++ )
+    {
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+        *p_pic++ = 0;   *p_pic++ = 0;
+    }
+
+    /* Clear last pixels */
+    //??
+}
+
+
 /*******************************************************************************
  * RenderPicture: render a picture
  *******************************************************************************
@@ -756,8 +802,17 @@ static void EndThread( vout_thread_t *p_vout )
  * rendered picture has been determined as existant, and will only be destroyed
  * by the vout thread later.
  *******************************************************************************/
-static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
+static int RenderPicture( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank )
 {
+    /* Mark last picture date */
+    p_vout->last_picture_date = p_pic->date;    
+
+    /* Blank screen if required */
+    if( b_blank )
+    {
+        RenderBlank( p_vout );
+    }
+
     /* 
      * Prepare scaling 
      */
@@ -769,7 +824,6 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
          * XImages */
 /*        p_vout->i_new_width =   p_pic->i_width;
         p_vout->i_new_height =  p_pic->i_height;*/
-        return;        
 #else
         /* Other drivers: the video output thread can't change its size, so
          * we need to change the aspect ratio */
@@ -815,6 +869,8 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
      * Terminate scaling 
      */
     //??
+
+    return( 1 );    
 }
 
 
@@ -822,16 +878,12 @@ static void RenderPicture( vout_thread_t *p_vout, picture_t *p_pic )
 /*******************************************************************************
  * RenderPictureInfo: print additionnal informations on a picture
  *******************************************************************************
- * This function will add informations such as fps and buffer size on a picture
+ * This function will print informations such as fps and other picture
+ * dependant informations.
  *******************************************************************************/
-static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
+static int RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic, boolean_t b_blank )
 {
     char        psz_buffer[256];                              /* string buffer */
-#ifdef DEBUG
-    int         i_ready_pic = 0;                             /* ready pictures */
-    int         i_reserved_pic = 0;                       /* reserved pictures */
-    int         i_picture;                                    /* picture index */
-#endif
 
 #ifdef STATS
     /* 
@@ -846,37 +898,32 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
     }
 
     /* 
-     * Print statistics in upper left corner 
+     * Print frames count and loop time in upper left corner 
      */
-    sprintf( psz_buffer, "gamma=%.2f   %ld frames", 
-             p_vout->f_gamma, p_vout->c_fps_samples );
+    sprintf( psz_buffer, "%ld frames   render time: %lu us", 
+             p_vout->c_fps_samples, (long unsigned) p_vout->render_time );
     vout_SysPrint( p_vout, 0, 0, -1, -1, psz_buffer );    
 #endif
-    
+
 #ifdef DEBUG
-    /* 
-     * Print heap state in lower left corner  
+    /*
+     * Print picture information in lower right corner
      */
-    for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
-    {
-        switch( p_vout->p_picture[i_picture].i_status )
-        {
-        case RESERVED_PICTURE:
-            i_reserved_pic++;            
-            break;            
-        case READY_PICTURE:
-            i_ready_pic++;            
-            break;            
-        }        
-    }
-    sprintf( psz_buffer, "video heap: %d/%d/%d", i_reserved_pic, i_ready_pic, 
-             VOUT_MAX_PICTURES );
-    vout_SysPrint( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer );    
-#endif
-
-#ifdef DEBUG_VIDEO
-    //??
+    sprintf( psz_buffer, "%s picture (mc=%d) %dx%d (%dx%d%+d%+d ar=%s)",
+             (p_pic->i_type == YUV_420_PICTURE) ? "4:2:0" :
+             ((p_pic->i_type == YUV_422_PICTURE) ? "4:2:2" :
+              ((p_pic->i_type == YUV_444_PICTURE) ? "4:4:4" : "?")),
+             p_pic->i_matrix_coefficients, p_pic->i_width, p_pic->i_height,
+             p_pic->i_display_width, p_pic->i_display_height,
+             p_pic->i_display_horizontal_offset, p_pic->i_display_vertical_offset,
+             (p_pic->i_aspect_ratio == AR_SQUARE_PICTURE) ? "square" :
+             ((p_pic->i_aspect_ratio == AR_3_4_PICTURE) ? "4:3" :
+              ((p_pic->i_aspect_ratio == AR_16_9_PICTURE) ? "16:9" :
+               ((p_pic->i_aspect_ratio == AR_221_1_PICTURE) ? "2.21:1" : "?" ))));    
+    vout_SysPrint( p_vout, p_vout->i_width, p_vout->i_height, 1, 1, psz_buffer );
 #endif
+    
+    return( 0 );    
 }
 
 /*******************************************************************************
@@ -884,31 +931,80 @@ static void RenderPictureInfo( vout_thread_t *p_vout, picture_t *p_pic )
  *******************************************************************************
  * This function will clear the display or print a logo.
  *******************************************************************************/
-static int RenderIdle( vout_thread_t *p_vout )
+static int RenderIdle( vout_thread_t *p_vout, boolean_t b_blank )
 {
-    //??
+    /* Blank screen if required */
+    if( (mdate() - p_vout->last_picture_date > VOUT_IDLE_DELAY) &&
+        (p_vout->last_picture_date > p_vout->last_display_date) &&
+        b_blank )
+    {        
+        RenderBlank( p_vout );
+        p_vout->last_display_date = mdate();        
+        vout_SysPrint( p_vout, p_vout->i_width / 2, p_vout->i_height / 2, 0, 0,
+                       "no stream" );        
+        return( 1 );        
+    }
+
     return( 0 );    
 }
 
 /*******************************************************************************
  * RenderInfo: render additionnal informations
  *******************************************************************************
- * ??
+ * This function render informations which do not depend of the current picture
+ * rendered.
  *******************************************************************************/
-static int RenderInfo( vout_thread_t *p_vout )
+static int RenderInfo( vout_thread_t *p_vout, boolean_t b_blank )
 {
-    //??
+    char        psz_buffer[256];                              /* string buffer */
+#ifdef DEBUG
+    int         i_ready_pic = 0;                             /* ready pictures */
+    int         i_reserved_pic = 0;                       /* reserved pictures */
+    int         i_picture;                                    /* picture index */
+#endif
+
+#ifdef DEBUG
+    /* 
+     * Print thread state in lower left corner  
+     */
+    for( i_picture = 0; i_picture < VOUT_MAX_PICTURES; i_picture++ )
+    {
+        switch( p_vout->p_picture[i_picture].i_status )
+        {
+        case RESERVED_PICTURE:
+            i_reserved_pic++;            
+            break;            
+        case READY_PICTURE:
+            i_ready_pic++;            
+            break;            
+        }        
+    }
+    sprintf( psz_buffer, "%s %dx%d:%d %.2f:%.2f g%+.2f   pic: %d/%d/%d", 
+             p_vout->b_grayscale ? "gray" : "rgb", 
+             p_vout->i_width, p_vout->i_height,
+             p_vout->i_screen_depth, p_vout->f_x_ratio, p_vout->f_y_ratio, p_vout->f_gamma,
+             i_reserved_pic, i_ready_pic,
+             VOUT_MAX_PICTURES );
+    vout_SysPrint( p_vout, 0, p_vout->i_height, -1, 1, psz_buffer );    
+#endif
     return( 0 );    
 }
 
 /*******************************************************************************
  * Manage: manage thread
  *******************************************************************************
- * ??
+ * This function will handle changes in thread configuration.
  *******************************************************************************/
 static int Manage( vout_thread_t *p_vout )
 {
-    //??
+    /* On gamma or grayscale change, rebuild tables */
+    if( p_vout->i_changes & (VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE) )
+    {
+        vout_ResetTables( p_vout );        
+    }    
+
+    /* Clear changes flags which does not need management or have been handled */
+    p_vout->i_changes &= ~(VOUT_INFO_CHANGE | VOUT_GAMMA_CHANGE | VOUT_GRAYSCALE_CHANGE);
 
     /* Detect unauthorized changes */
     if( p_vout->i_changes )