]> git.sesse.net Git - vlc/blobdiff - src/video_output/video_output.c
Try to close ticket '#1775' (Qt intf startup size is too big)
[vlc] / src / video_output / video_output.c
index e0837c6bb4d8bc8da3a2e5aeafb37d3035b80ffc..a68d7fdae4338add0776621b350859b84f7d9bbf 100644 (file)
  * Local prototypes
  *****************************************************************************/
 static int      InitThread        ( vout_thread_t * );
-static void     RunThread         ( vout_thread_t * );
+static void*    RunThread         ( vlc_object_t *  );
 static void     ErrorThread       ( vout_thread_t * );
 static void     CleanThread       ( vout_thread_t * );
 static void     EndThread         ( vout_thread_t * );
 
 static void     AspectRatio       ( int, int *, int * );
-static int      BinaryLog         ( uint32_t );
-static void     MaskToShift       ( int *, int *, uint32_t );
+
+static void VideoFormatImportRgb( video_format_t *, const picture_heap_t * );
+static void PictureHeapFixRgb( picture_heap_t * );
 
 static void     vout_Destructor   ( vlc_object_t * p_this );
 
@@ -179,7 +180,7 @@ vout_thread_t *__vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
             p_vout->b_filter_change )
         {
             /* We are not interested in this format, close this vout */
-            vlc_object_release( p_vout );
+            vout_CloseAndRelease( p_vout );
             vlc_object_release( p_vout );
             p_vout = NULL;
         }
@@ -366,8 +367,9 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
     }
 
     /* Create the vout thread */
-    config_ChainCreate( &psz_name, &p_cfg, psz_parser );
+    char* psz_tmp = config_ChainCreate( &psz_name, &p_cfg, psz_parser );
     free( psz_parser );
+    free( psz_tmp );
     p_vout->p_cfg = p_cfg;
     p_vout->p_module = module_Need( p_vout,
         ( p_vout->psz_filter_chain && *p_vout->psz_filter_chain ) ?
@@ -463,6 +465,7 @@ void vout_Close( vout_thread_t *p_vout )
     vlc_object_kill( p_vout );
     vlc_thread_join( p_vout );
     module_Unneed( p_vout, p_vout->p_module );
+    p_vout->p_module = NULL;
 }
 
 /* */
@@ -470,6 +473,9 @@ static void vout_Destructor( vlc_object_t * p_this )
 {
     vout_thread_t *p_vout = (vout_thread_t *)p_this;
 
+    /* Make sure the vout was stopped first */
+    assert( !p_vout->p_module );
+
     /* Destroy the locks */
     vlc_mutex_destroy( &p_vout->picture_lock );
     vlc_mutex_destroy( &p_vout->change_lock );
@@ -506,6 +512,7 @@ static void vout_Destructor( vlc_object_t * p_this )
  *****************************************************************************/
 static int ChromaCreate( vout_thread_t *p_vout );
 static void ChromaDestroy( vout_thread_t *p_vout );
+static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture );
 
 static int InitThread( vout_thread_t *p_vout )
 {
@@ -595,20 +602,13 @@ static int InitThread( vout_thread_t *p_vout )
              i_aspect_x, i_aspect_y,
              p_vout->fmt_out.i_sar_num, p_vout->fmt_out.i_sar_den );
 
+    /* FIXME removed the need of both fmt_* and heap infos */
     /* Calculate shifts from system-updated masks */
-    MaskToShift( &p_vout->render.i_lrshift, &p_vout->output.i_rrshift,
-                 p_vout->render.i_rmask );
-    MaskToShift( &p_vout->render.i_lgshift, &p_vout->output.i_rgshift,
-                 p_vout->render.i_gmask );
-    MaskToShift( &p_vout->render.i_lbshift, &p_vout->output.i_rbshift,
-                 p_vout->render.i_bmask );
-
-    MaskToShift( &p_vout->output.i_lrshift, &p_vout->output.i_rrshift,
-                 p_vout->output.i_rmask );
-    MaskToShift( &p_vout->output.i_lgshift, &p_vout->output.i_rgshift,
-                 p_vout->output.i_gmask );
-    MaskToShift( &p_vout->output.i_lbshift, &p_vout->output.i_rbshift,
-                 p_vout->output.i_bmask );
+    PictureHeapFixRgb( &p_vout->render );
+    VideoFormatImportRgb( &p_vout->fmt_render, &p_vout->render );
+
+    PictureHeapFixRgb( &p_vout->output );
+    VideoFormatImportRgb( &p_vout->fmt_out, &p_vout->output );
 
     /* Check whether we managed to create direct buffers similar to
      * the render buffers, ie same size and chroma */
@@ -691,8 +691,9 @@ static int InitThread( vout_thread_t *p_vout )
  * terminated. It handles the pictures arriving in the video heap and the
  * display device events.
  *****************************************************************************/
-static void RunThread( vout_thread_t *p_vout)
+static void* RunThread( vlc_object_t *p_this )
 {
+    vout_thread_t *p_vout = (vout_thread_t *)p_this;
     int             i_index;                                /* index in heap */
     int             i_idle_loops = 0;  /* loops without displaying a picture */
     mtime_t         current_date;                            /* current date */
@@ -728,7 +729,7 @@ static void RunThread( vout_thread_t *p_vout)
     {
         EndThread( p_vout );
         vlc_mutex_unlock( &p_vout->change_lock );
-        return;
+        return NULL;
     }
 
     vlc_object_lock( p_vout );
@@ -740,7 +741,7 @@ static void RunThread( vout_thread_t *p_vout)
      * Main loop - it is not executed if an error occurred during
      * initialization
      */
-    while( (vlc_object_alive( p_vout )) && (!p_vout->b_error) )
+    while( vlc_object_alive( p_vout ) && !p_vout->b_error )
     {
         /* Initialize loop variables */
         p_picture = NULL;
@@ -748,24 +749,24 @@ static void RunThread( vout_thread_t *p_vout)
         current_date = mdate();
 
         i_loops++;
-            if( !p_input )
-            {
-                p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
-                                           FIND_PARENT );
-            }
-            if( p_input )
-            {
-                vlc_mutex_lock( &p_input->p->counters.counters_lock );
-                stats_UpdateInteger( p_vout, p_input->p->counters.p_lost_pictures,
-                                     i_lost , NULL);
-                stats_UpdateInteger( p_vout,
-                                     p_input->p->counters.p_displayed_pictures,
-                                     i_displayed , NULL);
-                i_displayed = i_lost = 0;
-                vlc_mutex_unlock( &p_input->p->counters.counters_lock );
-                vlc_object_release( p_input );
-                p_input = NULL;
-            }
+        if( !p_input )
+        {
+            p_input = vlc_object_find( p_vout, VLC_OBJECT_INPUT,
+                                       FIND_PARENT );
+        }
+        if( p_input )
+        {
+            vlc_mutex_lock( &p_input->p->counters.counters_lock );
+            stats_UpdateInteger( p_vout, p_input->p->counters.p_lost_pictures,
+                                 i_lost , NULL);
+            stats_UpdateInteger( p_vout,
+                                 p_input->p->counters.p_displayed_pictures,
+                                 i_displayed , NULL);
+            i_displayed = i_lost = 0;
+            vlc_mutex_unlock( &p_input->p->counters.counters_lock );
+            vlc_object_release( p_input );
+            p_input = NULL;
+        }
 #if 0
         p_vout->c_loops++;
         if( !(p_vout->c_loops % VOUT_STATS_NB_LOOPS) )
@@ -812,17 +813,7 @@ static void RunThread( vout_thread_t *p_vout)
             /* 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 );
+                DropPicture( p_vout, p_last_picture );
                 p_last_picture = NULL;
             }
 
@@ -837,24 +828,10 @@ static void RunThread( vout_thread_t *p_vout)
             {
                 /* Picture is late: it will be destroyed and the thread
                  * will directly choose the next picture */
-                vlc_mutex_lock( &p_vout->picture_lock );
-                if( p_picture->i_refcount )
-                {
-                    /* Pretend we displayed the picture, but don't destroy
-                     * it since the decoder might still need it. */
-                    p_picture->i_status = DISPLAYED_PICTURE;
-                }
-                else
-                {
-                    /* Destroy the picture without displaying it */
-                    p_picture->i_status = DESTROYED_PICTURE;
-                    p_vout->i_heap_size--;
-                }
+                DropPicture( p_vout, p_picture );
+                i_lost++;
                 msg_Warn( p_vout, "late picture skipped (%"PRId64")",
                                   current_date - display_date );
-                i_lost++;
-                vlc_mutex_unlock( &p_vout->picture_lock );
-
                 continue;
             }
 
@@ -862,25 +839,11 @@ static void RunThread( vout_thread_t *p_vout)
                 current_date + p_vout->i_pts_delay + VOUT_BOGUS_DELAY )
             {
                 /* Picture is waaay too early: it will be destroyed */
-                vlc_mutex_lock( &p_vout->picture_lock );
-                if( p_picture->i_refcount )
-                {
-                    /* Pretend we displayed the picture, but don't destroy
-                     * it since the decoder might still need it. */
-                    p_picture->i_status = DISPLAYED_PICTURE;
-                }
-                else
-                {
-                    /* Destroy the picture without displaying it */
-                    p_picture->i_status = DESTROYED_PICTURE;
-                    p_vout->i_heap_size--;
-                }
+                DropPicture( p_vout, p_picture );
                 i_lost++;
                 msg_Warn( p_vout, "vout warning: early picture skipped "
                           "(%"PRId64")", display_date - current_date
                           - p_vout->i_pts_delay );
-                vlc_mutex_unlock( &p_vout->picture_lock );
-
                 continue;
             }
 
@@ -1152,6 +1115,7 @@ static void RunThread( vout_thread_t *p_vout)
     vlc_mutex_unlock( &p_vout->change_lock );
 
     vlc_object_unlock( p_vout );
+    return NULL;
 }
 
 /*****************************************************************************
@@ -1233,19 +1197,6 @@ static picture_t *ChromaGetPicture( filter_t *p_filter )
     return p_pic;
 }
 
-static void ChromaCopyRgbInfo( es_format_t *p_fmt, picture_heap_t *p_heap )
-{
-    p_fmt->video.i_rmask = p_heap->i_rmask;
-    p_fmt->video.i_gmask = p_heap->i_gmask;
-    p_fmt->video.i_bmask = p_heap->i_bmask;
-    p_fmt->video.i_rrshift = p_heap->i_rrshift;
-    p_fmt->video.i_lrshift = p_heap->i_lrshift;
-    p_fmt->video.i_rgshift = p_heap->i_rgshift;
-    p_fmt->video.i_lgshift = p_heap->i_lgshift;
-    p_fmt->video.i_rbshift = p_heap->i_rbshift;
-    p_fmt->video.i_lbshift = p_heap->i_lbshift;
-}
-
 static int ChromaCreate( vout_thread_t *p_vout )
 {
     static const char typename[] = "chroma";
@@ -1261,8 +1212,8 @@ static int ChromaCreate( vout_thread_t *p_vout )
     /* TODO: Set the fmt_in and fmt_out stuff here */
     p_chroma->fmt_in.video = p_vout->fmt_render;
     p_chroma->fmt_out.video = p_vout->fmt_out;
-    ChromaCopyRgbInfo( &p_chroma->fmt_in, &p_vout->render );
-    ChromaCopyRgbInfo( &p_chroma->fmt_out, &p_vout->output );
+    VideoFormatImportRgb( &p_chroma->fmt_in.video, &p_vout->render );
+    VideoFormatImportRgb( &p_chroma->fmt_out.video, &p_vout->output );
 
     p_chroma->p_module = module_Need( p_chroma, "video filter2", NULL, 0 );
 
@@ -1295,6 +1246,24 @@ static void ChromaDestroy( vout_thread_t *p_vout )
     p_vout->p_chroma = NULL;
 }
 
+static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture )
+{
+    vlc_mutex_lock( &p_vout->picture_lock );
+    if( p_picture->i_refcount )
+    {
+        /* Pretend we displayed the picture, but don't destroy
+         * it since the decoder might still need it. */
+        p_picture->i_status = DISPLAYED_PICTURE;
+    }
+    else
+    {
+        /* Destroy the picture without displaying it */
+        p_picture->i_status = DESTROYED_PICTURE;
+        p_vout->i_heap_size--;
+    }
+    vlc_mutex_unlock( &p_vout->picture_lock );
+}
+
 
 
 /* following functions are local */
@@ -1341,56 +1310,55 @@ static void AspectRatio( int i_aspect, int *i_aspect_x, int *i_aspect_y )
     *i_aspect_y = VOUT_ASPECT_FACTOR / i_pgcd;
 }
 
-/*****************************************************************************
- * BinaryLog: computes the base 2 log of a binary value
- *****************************************************************************
- * This functions is used by MaskToShift, to get a bit index from a binary
- * value.
- *****************************************************************************/
-static int BinaryLog( uint32_t i )
+/**
+ * This function copies all RGB informations from a picture_heap_t into
+ * a video_format_t
+ */
+static void VideoFormatImportRgb( video_format_t *p_fmt, const picture_heap_t *p_heap )
 {
-    int i_log = 0;
-
-    if( i == 0 ) return -31337;
-
-    if( i & 0xffff0000 ) i_log += 16;
-    if( i & 0xff00ff00 ) i_log += 8;
-    if( i & 0xf0f0f0f0 ) i_log += 4;
-    if( i & 0xcccccccc ) i_log += 2;
-    if( i & 0xaaaaaaaa ) i_log += 1;
-
-    return i_log;
+    p_fmt->i_rmask = p_heap->i_rmask;
+    p_fmt->i_gmask = p_heap->i_gmask;
+    p_fmt->i_bmask = p_heap->i_bmask;
+    p_fmt->i_rrshift = p_heap->i_rrshift;
+    p_fmt->i_lrshift = p_heap->i_lrshift;
+    p_fmt->i_rgshift = p_heap->i_rgshift;
+    p_fmt->i_lgshift = p_heap->i_lgshift;
+    p_fmt->i_rbshift = p_heap->i_rbshift;
+    p_fmt->i_lbshift = p_heap->i_lbshift;
 }
 
-/*****************************************************************************
- * MaskToShift: transform a color mask into right and left shifts
- *****************************************************************************
- * This function is used for obtaining color shifts from masks.
- *****************************************************************************/
-static void MaskToShift( int *pi_left, int *pi_right, uint32_t i_mask )
+/**
+ * This funtion copes all RGB informations from a video_format_t into
+ * a picture_heap_t
+ */
+static void VideoFormatExportRgb( const video_format_t *p_fmt, picture_heap_t *p_heap )
 {
-    uint32_t i_low, i_high;            /* lower hand higher bits of the mask */
-
-    if( !i_mask )
-    {
-        *pi_left = *pi_right = 0;
-        return;
-    }
+    p_heap->i_rmask = p_fmt->i_rmask;
+    p_heap->i_gmask = p_fmt->i_gmask;
+    p_heap->i_bmask = p_fmt->i_bmask;
+    p_heap->i_rrshift = p_fmt->i_rrshift;
+    p_heap->i_lrshift = p_fmt->i_lrshift;
+    p_heap->i_rgshift = p_fmt->i_rgshift;
+    p_heap->i_lgshift = p_fmt->i_lgshift;
+    p_heap->i_rbshift = p_fmt->i_rbshift;
+    p_heap->i_lbshift = p_fmt->i_lbshift;
+}
 
-    /* Get bits */
-    i_low = i_high = i_mask;
+/**
+ * This function computes rgb shifts from masks
+ */
+static void PictureHeapFixRgb( picture_heap_t *p_heap )
+{
+    video_format_t fmt;
 
-    i_low &= - (int32_t)i_low;          /* lower bit of the mask */
-    i_high += i_low;                    /* higher bit of the mask */
+    /* */
+    fmt.i_chroma = p_heap->i_chroma;
+    VideoFormatImportRgb( &fmt, p_heap );
 
-    /* Transform bits into an index. Also deal with i_high overflow, which
-     * is faster than changing the BinaryLog code to handle 64 bit integers. */
-    i_low =  BinaryLog (i_low);
-    i_high = i_high ? BinaryLog (i_high) : 32;
+    /* */
+    video_format_FixRgb( &fmt );
 
-    /* Update pointers and return */
-    *pi_left =   i_low;
-    *pi_right = (8 - i_high + i_low);
+    VideoFormatExportRgb( &fmt, p_heap );
 }
 
 /*****************************************************************************
@@ -1404,8 +1372,9 @@ typedef struct suxor_thread_t
 
 } suxor_thread_t;
 
-static void SuxorRestartVideoES( suxor_thread_t *p_this )
+static void* SuxorRestartVideoES( vlc_object_t * p_vlc_t )
 {
+    suxor_thread_t *p_this = (suxor_thread_t *) p_vlc_t;
     /* Now restart current video stream */
     int val = var_GetInteger( p_this->p_input, "video-es" );
     if( val >= 0 )
@@ -1417,6 +1386,7 @@ static void SuxorRestartVideoES( suxor_thread_t *p_this )
     vlc_object_release( p_this->p_input );
 
     vlc_object_release( p_this );
+    return NULL;
 }
 
 /*****************************************************************************
@@ -1544,6 +1514,8 @@ static void DisplayTitleOnOSD( vout_thread_t *p_vout )
     input_thread_t *p_input;
     mtime_t i_now, i_stop;
 
+    if( !config_GetInt( p_vout, "osd" ) ) return;
+
     p_input = (input_thread_t *)vlc_object_find( p_vout,
               VLC_OBJECT_INPUT, FIND_ANYWHERE );
     if( p_input )