Moved vout helpers out of decoder.c.
authorLaurent Aimar <fenrir@videolan.org>
Tue, 14 Oct 2008 20:36:10 +0000 (22:36 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Wed, 15 Oct 2008 19:29:36 +0000 (21:29 +0200)
src/input/decoder.c
src/video_output/video_output.c
src/video_output/vout_internal.h
src/video_output/vout_pictures.c

index 7573cff..f79c67a 100644 (file)
@@ -1160,47 +1160,6 @@ static void DecoderGetCc( decoder_t *p_dec, decoder_t *p_dec_cc )
     }
     vlc_mutex_unlock( &p_owner->lock );
 }
-static void VoutDisplayedPicture( vout_thread_t *p_vout, picture_t *p_pic )
-{
-    vlc_mutex_lock( &p_vout->picture_lock );
-
-    if( p_pic->i_status == READY_PICTURE )
-    {
-        /* Grr cannot destroy ready picture by myself so be sure vout won't like it */
-        p_pic->date = 1;
-    }
-    else if( p_pic->i_refcount > 0 )
-    {
-        p_pic->i_status = DISPLAYED_PICTURE;
-    }
-    else
-    {
-        p_pic->i_status = DESTROYED_PICTURE;
-        picture_CleanupQuant( p_pic );
-        p_vout->i_heap_size--;
-    }
-
-    vlc_mutex_unlock( &p_vout->picture_lock );
-}
-static void VoutFlushPicture( vout_thread_t *p_vout, mtime_t i_max_date )
-{
-    int i;
-    vlc_mutex_lock( &p_vout->picture_lock );
-    for( i = 0; i < p_vout->render.i_pictures; i++ )
-    {
-        picture_t *p_pic = p_vout->render.pp_picture[i];
-
-        if( p_pic->i_status == READY_PICTURE ||
-            p_pic->i_status == DISPLAYED_PICTURE )
-        {
-            /* We cannot change picture status if it is in READY_PICTURE state,
-             * Just make sure they won't be displayed */
-            if( p_pic->date > i_max_date )
-                p_pic->date = i_max_date;
-        }
-    }
-    vlc_mutex_unlock( &p_vout->picture_lock );
-}
 
 static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
                               int *pi_played_sum, int *pi_lost_sum )
@@ -1212,7 +1171,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
     {
         msg_Warn( p_vout, "non-dated video buffer received" );
         *pi_lost_sum += 1;
-        VoutDisplayedPicture( p_vout, p_picture );
+        vout_DropPicture( p_vout, p_picture );
         return;
     }
 
@@ -1297,7 +1256,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
             if( i_rate != p_owner->i_last_rate  )
             {
                 /* Be sure to not display old picture after our own */
-                VoutFlushPicture( p_vout, p_picture->date );
+                vout_Flush( p_vout, p_picture->date );
                 p_owner->i_last_rate = i_rate;
             }
 
@@ -1317,7 +1276,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
                           p_picture->date - mdate() );
             }
             *pi_lost_sum += 1;
-            VoutDisplayedPicture( p_vout, p_picture );
+            vout_DropPicture( p_vout, p_picture );
         }
         int i_tmp_display;
         int i_tmp_lost;
@@ -1353,7 +1312,7 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
         if( p_dec->b_die )
         {
             /* It prevent freezing VLC in case of broken decoder */
-            VoutDisplayedPicture( p_vout, p_pic );
+            vout_DropPicture( p_vout, p_pic );
             if( p_block )
                 block_Release( p_block );
             break;
@@ -1363,7 +1322,7 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
 
         if( p_pic->date < p_owner->i_preroll_end )
         {
-            VoutDisplayedPicture( p_vout, p_pic );
+            vout_DropPicture( p_vout, p_pic );
             continue;
         }
 
@@ -1371,7 +1330,7 @@ static void DecoderDecodeVideo( decoder_t *p_dec, block_t *p_block )
         {
             msg_Dbg( p_dec, "End of video preroll" );
             if( p_vout )
-                VoutFlushPicture( p_vout, 1 );
+                vout_Flush( p_vout, 1 );
             /* */
             p_owner->i_preroll_end = -1;
         }
@@ -1513,7 +1472,7 @@ static void DecoderFlushBuffering( decoder_t *p_dec )
         p_owner->buffer.i_count--;
 
         if( p_owner->p_vout )
-            VoutDisplayedPicture( p_owner->p_vout, p_picture );
+            vout_DropPicture( p_owner->p_vout, p_picture );
 
         if( !p_owner->buffer.p_picture )
             p_owner->buffer.pp_picture_next = &p_owner->buffer.p_picture;
@@ -1655,7 +1614,7 @@ static void DecoderProcessVideo( decoder_t *p_dec, block_t *p_block, bool b_flus
     }
 
     if( b_flush && p_owner->p_vout )
-        VoutFlushPicture( p_owner->p_vout, 1 );
+        vout_Flush( p_owner->p_vout, 1 );
 }
 
 /* This function process a audio block
@@ -2106,7 +2065,6 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
     for( ;; )
     {
         picture_t *p_picture;
-        int i_pic, i_ready_pic;
 
         if( p_dec->b_die || p_dec->b_error )
             return NULL;
@@ -2130,47 +2088,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
         DecoderSignalBuffering( p_dec, true );
 
         /* Check the decoder doesn't leak pictures */
-        for( i_pic = 0, i_ready_pic = 0; i_pic < p_owner->p_vout->render.i_pictures; i_pic++ )
-        {
-            const picture_t *p_pic = p_owner->p_vout->render.pp_picture[i_pic];
-
-            if( p_pic->i_status == READY_PICTURE )
-            {
-                i_ready_pic++;
-                /* If we have at least 2 ready pictures, wait for the vout thread to
-                 * process one */
-                if( i_ready_pic >= 2 )
-                    break;
-
-                continue;
-            }
-
-            if( p_pic->i_status == DISPLAYED_PICTURE )
-            {
-                /* If at least one displayed picture is not referenced
-                 * let vout free it */
-                if( p_pic->i_refcount == 0 )
-                    break;
-            }
-        }
-
-        if( i_pic == p_owner->p_vout->render.i_pictures )
-        {
-            /* Too many pictures are still referenced, there is probably a bug
-             * with the decoder */
-            msg_Err( p_dec, "decoder is leaking pictures, resetting the heap" );
-
-            /* Just free all the pictures */
-            for( i_pic = 0; i_pic < p_owner->p_vout->render.i_pictures; i_pic++ )
-            {
-                picture_t *p_pic = p_owner->p_vout->render.pp_picture[i_pic];
-
-                if( p_pic->i_status == RESERVED_PICTURE )
-                    vout_DestroyPicture( p_owner->p_vout, p_pic );
-                if( p_pic->i_refcount > 0 )
-                    vout_UnlinkPicture( p_owner->p_vout, p_pic );
-            }
-        }
+        vout_FixLeaks( p_owner->p_vout );
 
         msleep( VOUT_OUTMEM_SLEEP );
     }
@@ -2178,7 +2096,7 @@ static picture_t *vout_new_buffer( decoder_t *p_dec )
 
 static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic )
 {
-    VoutDisplayedPicture( p_dec->p_owner->p_vout, p_pic );
+    vout_DropPicture( p_dec->p_owner->p_vout, p_pic );
 }
 
 static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic )
index a646ef1..d0a8dc9 100644 (file)
@@ -375,7 +375,7 @@ vout_thread_t * __vout_Create( vlc_object_t *p_parent, video_format_t *p_fmt )
     p_vout->p->i_par_den = 1;
 
     /* Initialize locks */
-    vlc_mutex_init( &p_vout->picture_lock );
+    vlc_mutex_init_recursive( &p_vout->picture_lock );
     vlc_mutex_init( &p_vout->change_lock );
     vlc_mutex_init( &p_vout->p->vfilter_lock );
 
@@ -628,6 +628,58 @@ void vout_Flush( vout_thread_t *p_vout, mtime_t i_date )
     }
     vlc_mutex_unlock( &p_vout->picture_lock );
 }
+void vout_FixLeaks( vout_thread_t *p_vout )
+{
+    int i_pic, i_ready_pic;
+
+    vlc_mutex_lock( &p_vout->picture_lock );
+
+    for( i_pic = 0, i_ready_pic = 0; i_pic < p_vout->render.i_pictures; i_pic++ )
+    {
+        const picture_t *p_pic = p_vout->render.pp_picture[i_pic];
+
+        if( p_pic->i_status == READY_PICTURE )
+        {
+            i_ready_pic++;
+            /* If we have at least 2 ready pictures, wait for the vout thread to
+             * process one */
+            if( i_ready_pic >= 2 )
+                break;
+
+            continue;
+        }
+
+        if( p_pic->i_status == DISPLAYED_PICTURE )
+        {
+            /* If at least one displayed picture is not referenced
+             * let vout free it */
+            if( p_pic->i_refcount == 0 )
+                break;
+        }
+    }
+    if( i_pic < p_vout->render.i_pictures )
+    {
+        vlc_mutex_unlock( &p_vout->picture_lock );
+        return;
+    }
+
+    /* Too many pictures are still referenced, there is probably a bug
+     * with the decoder */
+    msg_Err( p_vout, "pictures leaked, resetting the heap" );
+
+    /* Just free all the pictures */
+    for( i_pic = 0; i_pic < p_vout->render.i_pictures; i_pic++ )
+    {
+        picture_t *p_pic = p_vout->render.pp_picture[i_pic];
+
+        if( p_pic->i_status == RESERVED_PICTURE )
+            vout_DestroyPicture( p_vout, p_pic );
+        if( p_pic->i_refcount > 0 )
+            vout_UnlinkPicture( p_vout, p_pic );
+    }
+    vlc_mutex_unlock( &p_vout->picture_lock );
+}
+
 /*****************************************************************************
  * InitThread: initialize video output thread
  *****************************************************************************
@@ -659,10 +711,6 @@ static int InitThread( vout_thread_t *p_vout )
 {
     int i, i_aspect_x, i_aspect_y;
 
-#ifdef STATS
-    p_vout->c_loops = 0;
-#endif
-
     /* Initialize output method, it allocates direct buffers for us */
     if( p_vout->pf_init( p_vout ) )
         return VLC_EGENERIC;
@@ -843,7 +891,7 @@ static void* RunThread( vlc_object_t *p_this )
 
     bool            b_drop_late;
 
-    int canc = vlc_savecancel ();
+    int canc = vlc_savecancel();
 
     /*
      * Initialize thread
@@ -860,7 +908,7 @@ static void* RunThread( vlc_object_t *p_this )
     {
         EndThread( p_vout );
         vlc_mutex_unlock( &p_vout->change_lock );
-        vlc_restorecancel (canc);
+        vlc_restorecancel( canc );
         return NULL;
     }
 
@@ -883,15 +931,6 @@ static void* RunThread( vlc_object_t *p_this )
         picture_t *p_directbuffer;
         int i_index;
 
-#if 0
-        p_vout->c_loops++;
-        if( !(p_vout->c_loops % VOUT_STATS_NB_LOOPS) )
-        {
-            msg_Dbg( p_vout, "picture heap: %d/%d",
-                     I_RENDERPICTURES, p_vout->i_heap_size );
-        }
-#endif
-
         /*
          * Find the picture to display (the one with the earliest date).
          * This operation does not need lock, since only READY_PICTUREs
@@ -1236,7 +1275,7 @@ static void* RunThread( vlc_object_t *p_this )
     vlc_mutex_unlock( &p_vout->change_lock );
 
     vlc_object_unlock( p_vout );
-    vlc_restorecancel (canc);
+    vlc_restorecancel( canc );
     return NULL;
 }
 
index 212e20f..bba9293 100644 (file)
@@ -53,13 +53,6 @@ struct vout_thread_sys_t
     /* Statistics */
     int             i_picture_lost;
     int             i_picture_displayed;
-#if 0
-    count_t         c_loops;
-    count_t         c_pictures, c_late_pictures;
-    mtime_t         display_jitter;    /**< average deviation from the PTS */
-    count_t         c_jitter_samples;  /**< number of samples used
-                                           for the calculation of the jitter  */
-#endif
 
     /* Pause */
     bool            b_paused;
@@ -111,5 +104,18 @@ void vout_GetResetStatistic( vout_thread_t *p_vout, int *pi_displayed, int *pi_l
  */
 void vout_Flush( vout_thread_t *p_vout, mtime_t i_date );
 
+/**
+ * This function will try to detect if pictures are being leaked. If so it
+ * will release them.
+ *
+ * XXX This function is there to workaround bugs in decoder
+ */
+void vout_FixLeaks( vout_thread_t *p_vout );
+
+/**
+ * This functions will drop a picture retreived by vout_CreatePicture.
+ */
+void vout_DropPicture( vout_thread_t *p_vout, picture_t * );
+
 #endif
 
index dbdfa67..17d4dbc 100644 (file)
@@ -268,6 +268,30 @@ void vout_DestroyPicture( vout_thread_t *p_vout, picture_t *p_pic )
     vlc_mutex_unlock( &p_vout->picture_lock );
 }
 
+/* */
+void vout_DropPicture( vout_thread_t *p_vout, picture_t *p_pic  )
+{
+    vlc_mutex_lock( &p_vout->picture_lock );
+
+    if( p_pic->i_status == READY_PICTURE )
+    {
+        /* Grr cannot destroy ready picture by myself so be sure vout won't like it */
+        p_pic->date = 1;
+    }
+    else if( p_pic->i_refcount > 0 )
+    {
+        p_pic->i_status = DISPLAYED_PICTURE;
+    }
+    else
+    {
+        p_pic->i_status = DESTROYED_PICTURE;
+        p_vout->i_heap_size--;
+        picture_CleanupQuant( p_pic );
+    }
+
+    vlc_mutex_unlock( &p_vout->picture_lock );
+}
+
 /**
  * Increment reference counter of a picture
  *