Do not filter the same picture multiple times (close #1959).
authorLaurent Aimar <fenrir@videolan.org>
Tue, 2 Sep 2008 22:23:09 +0000 (00:23 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Tue, 2 Sep 2008 23:03:22 +0000 (01:03 +0200)
src/misc/filter_chain.c
src/video_output/video_output.c

index 7395c6b..5d8f2be 100644 (file)
@@ -54,6 +54,7 @@ static int filter_chain_DeleteFilterInternal( filter_chain_t *, filter_t * );
 
 static int UpdateBufferFunctions( filter_chain_t * );
 static picture_t *VideoBufferNew( filter_t * );
+static void VideoBufferDelete( filter_t *, picture_t * );
 
 /**
  * Filter chain initialisation
@@ -362,27 +363,6 @@ picture_t *filter_chain_VideoFilter( filter_chain_t *p_chain, picture_t *p_pic )
         filter_t *p_filter = pp_filter[i];
         picture_t *p_newpic = p_filter->pf_video_filter( p_filter, p_pic );
 
-        /* FIXME Ugly hack to make it work in picture core.
-         * FIXME Remove this code when the picture release API has been
-         * FIXME cleaned up (a git revert of the commit should work) */
-        if( p_chain->p_this->i_object_type == VLC_OBJECT_VOUT )
-        {
-            vout_thread_t *p_vout = (vout_thread_t*)p_chain->p_this;
-            vlc_mutex_lock( &p_vout->picture_lock );
-            if( p_pic->i_refcount )
-            {
-                p_pic->i_status = DISPLAYED_PICTURE;
-            }
-            else
-            {
-                p_pic->i_status = DESTROYED_PICTURE;
-                p_vout->i_heap_size--;
-            }
-            vlc_mutex_unlock( &p_vout->picture_lock );
-
-            if( p_newpic )
-                p_newpic->i_status = READY_PICTURE;
-        }
         if( !p_newpic )
             return NULL;
 
@@ -451,7 +431,7 @@ static int UpdateBufferFunctions( filter_chain_t *p_chain )
                 if( p_chain->pf_buffer_allocation_clear )
                     p_chain->pf_buffer_allocation_clear( p_filter );
                 p_filter->pf_vout_buffer_new = VideoBufferNew;
-                p_filter->pf_vout_buffer_del = NULL;
+                p_filter->pf_vout_buffer_del = VideoBufferDelete;
             }
         }
         if( p_chain->filters.i_count >= 1 )
@@ -460,6 +440,7 @@ static int UpdateBufferFunctions( filter_chain_t *p_chain )
             if( p_filter->pf_vout_buffer_new == VideoBufferNew )
             {
                 p_filter->pf_vout_buffer_new = NULL;
+                p_filter->pf_vout_buffer_del = NULL;
                 if( p_chain->pf_buffer_allocation_init( p_filter,
                         p_chain->p_buffer_allocation_data ) != VLC_SUCCESS )
                     return VLC_EGENERIC;
@@ -480,4 +461,8 @@ static picture_t *VideoBufferNew( filter_t *p_filter )
         msg_Err( p_filter, "Failed to allocate picture\n" );
     return p_picture;
 }
+static void VideoBufferDelete( filter_t *p_filter, picture_t *p_picture )
+{
+    picture_Release( p_picture );
+}
 
index a323948..8e11b08 100644 (file)
@@ -89,22 +89,27 @@ int vout_Snapshot( vout_thread_t *, picture_t * );
 /* Display media title in OSD */
 static void DisplayTitleOnOSD( vout_thread_t *p_vout );
 
+/* */
+static void DropPicture( vout_thread_t *p_vout, picture_t *p_picture );
+
 /*****************************************************************************
  * Video Filter2 functions
  *****************************************************************************/
 static picture_t *video_new_buffer_filter( filter_t *p_filter )
 {
-    picture_t *p_picture;
     vout_thread_t *p_vout = (vout_thread_t*)p_filter->p_owner;
+    picture_t *p_picture = vout_CreatePicture( p_vout, 0, 0, 0 );
 
-    p_picture = vout_CreatePicture( p_vout, 0, 0, 0 );
+    p_picture->i_status = READY_PICTURE;
 
     return p_picture;
 }
 
 static void video_del_buffer_filter( filter_t *p_filter, picture_t *p_pic )
 {
-    vout_DestroyPicture( (vout_thread_t*)p_filter->p_owner, p_pic );
+    vout_thread_t *p_vout = (vout_thread_t*)p_filter->p_owner;
+
+    DropPicture( p_vout, p_pic );
 }
 
 static int video_filter_buffer_allocation_init( filter_t *p_filter, void *p_data )
@@ -518,7 +523,6 @@ 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 )
 {
@@ -744,6 +748,7 @@ static void* RunThread( vlc_object_t *p_this )
         /* Initialize loop variables */
         const mtime_t current_date = mdate();
         picture_t *p_picture = NULL;
+        picture_t *p_filtered_picture;
         mtime_t display_date = 0;
         picture_t *p_directbuffer;
         input_thread_t *p_input;
@@ -874,20 +879,17 @@ static void* RunThread( vlc_object_t *p_this )
         }
 
         if( p_picture == NULL )
-        {
             i_idle_loops++;
-        }
 
+        p_filtered_picture = NULL;
         if( p_picture )
-        {
-            p_picture = filter_chain_VideoFilter( p_vout->p_vf2_chain,
-                                                  p_picture );
-        }
+            p_filtered_picture = filter_chain_VideoFilter( p_vout->p_vf2_chain,
+                                                           p_picture );
 
-        if( p_picture && p_vout->b_snapshot )
+        if( p_filtered_picture && p_vout->b_snapshot )
         {
             p_vout->b_snapshot = false;
-            vout_Snapshot( p_vout, p_picture );
+            vout_Snapshot( p_vout, p_filtered_picture );
         }
 
         /*
@@ -906,12 +908,12 @@ static void* RunThread( vlc_object_t *p_this )
          * Perform rendering
          */
         i_displayed++;
-        p_directbuffer = vout_RenderPicture( p_vout, p_picture, p_subpic );
+        p_directbuffer = vout_RenderPicture( p_vout, p_filtered_picture, p_subpic );
 
         /*
          * Call the plugin-specific rendering method if there is one
          */
-        if( p_picture != NULL && p_directbuffer != NULL && p_vout->pf_render )
+        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 );
@@ -965,20 +967,22 @@ static void* RunThread( vlc_object_t *p_this )
         /*
          * Display the previously rendered picture
          */
-        if( p_picture != NULL && p_directbuffer != NULL )
+        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_last_picture = p_picture;
-            p_last_picture->b_force = 0;
+            p_last_picture->b_force = false;
         }
 
+        /* Drop the filtered picture if created by video filters */
+        if( p_filtered_picture != NULL && p_filtered_picture != p_picture )
+            DropPicture( p_vout, p_filtered_picture );
+
         if( p_picture != NULL )
         {
             /* Reinitialize idle loop count */