]> git.sesse.net Git - vlc/blobdiff - modules/video_filter/deinterlace.c
Clone video filter : fix potential memleak.
[vlc] / modules / video_filter / deinterlace.c
index 1e8d55b836a08096910ce031c66a2958ece875a8..4ec8333340263f2b8b58aac34e0be95215aaf830 100644 (file)
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include <errno.h>
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
 #endif
 
-#include <vlc/vlc.h>
-#include <vlc_vout.h>
-#include <vlc_sout.h>
-#include "vlc_filter.h"
+#include <errno.h>
 
 #ifdef HAVE_ALTIVEC_H
 #   include <altivec.h>
 #endif
 
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_vout.h>
+#include <vlc_sout.h>
+#include "vlc_filter.h"
+
 #ifdef CAN_COMPILE_MMXEXT
 #   include "mmx.h"
 #endif
@@ -115,13 +117,14 @@ static int FilterCallback ( vlc_object_t *, char const *,
 
 #define FILTER_CFG_PREFIX "sout-deinterlace-"
 
-static const char *mode_list[] = { "discard", "blend", "mean", "bob", "linear", "x" };
-static const char *mode_list_text[] = { N_("Discard"), N_("Blend"), N_("Mean"),
-                                  N_("Bob"), N_("Linear"), "X" };
+static const char *const mode_list[] = {
+    "discard", "blend", "mean", "bob", "linear", "x" };
+static const char *const mode_list_text[] = {
+    N_("Discard"), N_("Blend"), N_("Mean"), N_("Bob"), N_("Linear"), "X" };
 
 vlc_module_begin();
-    set_description( _("Deinterlacing video filter") );
-    set_shortname( _("Deinterlace" ));
+    set_description( N_("Deinterlacing video filter") );
+    set_shortname( N_("Deinterlace" ));
     set_capability( "video filter", 0 );
     set_category( CAT_VIDEO );
     set_subcategory( SUBCAT_VIDEO_VFILTER );
@@ -143,7 +146,7 @@ vlc_module_begin();
     set_callbacks( OpenFilter, CloseFilter );
 vlc_module_end();
 
-static const char *ppsz_filter_options[] = {
+static const char *const ppsz_filter_options[] = {
     "mode", NULL
 };
 
@@ -190,10 +193,7 @@ static int Create( vlc_object_t *p_this )
     /* Allocate structure */
     p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
     if( p_vout->p_sys == NULL )
-    {
-        msg_Err( p_vout, "out of memory" );
         return VLC_ENOMEM;
-    }
 
     p_vout->pf_init = Init;
     p_vout->pf_end = End;
@@ -206,7 +206,7 @@ static int Create( vlc_object_t *p_this )
     p_vout->p_sys->b_double_rate = false;
     p_vout->p_sys->last_date = 0;
     p_vout->p_sys->p_vout = 0;
-    vlc_mutex_init( p_vout, &p_vout->p_sys->filter_lock );
+    vlc_mutex_init( &p_vout->p_sys->filter_lock );
 
 #if defined(CAN_COMPILE_C_ALTIVEC)
     if( vlc_CPU() & CPU_CAPABILITY_ALTIVEC )
@@ -420,6 +420,11 @@ static void End( vout_thread_t *p_vout )
 {
     int i_index;
 
+    DEL_PARENT_CALLBACKS( SendEventsToChild );
+
+    if( p_vout->p_sys->p_vout )
+        DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+
     /* Free the fake output buffers we allocated */
     for( i_index = I_OUTPUTPICTURES ; i_index ; )
     {
@@ -428,13 +433,7 @@ static void End( vout_thread_t *p_vout )
     }
 
     if( p_vout->p_sys->p_vout )
-    {
-        DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
-        vlc_object_detach( p_vout->p_sys->p_vout );
-        vout_Destroy( p_vout->p_sys->p_vout );
-    }
-
-    DEL_PARENT_CALLBACKS( SendEventsToChild );
+        vout_CloseAndRelease( p_vout->p_sys->p_vout );
 }
 
 /*****************************************************************************
@@ -486,7 +485,7 @@ static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
                                                 0, 0, 0 ) )
               == NULL )
     {
-        if( p_vout->b_die || p_vout->b_error )
+        if( !vlc_object_alive (p_vout) || p_vout->b_error )
         {
             vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
             return;
@@ -503,7 +502,7 @@ static void Render ( vout_thread_t *p_vout, picture_t *p_pic )
                                                  0, 0, 0 ) )
                   == NULL )
         {
-            if( p_vout->b_die || p_vout->b_error )
+            if( !vlc_object_alive (p_vout) || p_vout->b_error )
             {
                 vout_DestroyPicture( p_vout->p_sys->p_vout, pp_outpic[0] );
                 vlc_mutex_unlock( &p_vout->p_sys->filter_lock );
@@ -594,8 +593,7 @@ static void RenderDiscard( vout_thread_t *p_vout,
 
             for( ; p_out < p_out_end ; )
             {
-                p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
+                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                 p_out += p_outpic->p[i_plane].i_pitch;
                 p_in += 2 * p_pic->p[i_plane].i_pitch;
@@ -610,11 +608,9 @@ static void RenderDiscard( vout_thread_t *p_vout,
             {
                 for( ; p_out < p_out_end ; )
                 {
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                     p_out += p_outpic->p[i_plane].i_pitch;
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                     p_out += p_outpic->p[i_plane].i_pitch;
                     p_in += i_increment;
                 }
@@ -623,8 +619,7 @@ static void RenderDiscard( vout_thread_t *p_vout,
             {
                 for( ; p_out < p_out_end ; )
                 {
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                     p_out += p_outpic->p[i_plane].i_pitch;
                     p_in += i_increment;
                 }
@@ -663,8 +658,7 @@ static void RenderBob( vout_thread_t *p_vout,
                 /* For BOTTOM field we need to add the first line */
                 if( i_field == 1 )
                 {
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                     p_in += p_pic->p[i_plane].i_pitch;
                     p_out += p_outpic->p[i_plane].i_pitch;
                 }
@@ -673,28 +667,24 @@ static void RenderBob( vout_thread_t *p_vout,
 
                 for( ; p_out < p_out_end ; )
                 {
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                     p_out += p_outpic->p[i_plane].i_pitch;
 
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                     p_in += 2 * p_pic->p[i_plane].i_pitch;
                     p_out += p_outpic->p[i_plane].i_pitch;
                 }
 
-                p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
+                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                 /* For TOP field we need to add the last line */
                 if( i_field == 0 )
                 {
                     p_in += p_pic->p[i_plane].i_pitch;
                     p_out += p_outpic->p[i_plane].i_pitch;
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                 }
                 break;
 
@@ -702,8 +692,7 @@ static void RenderBob( vout_thread_t *p_vout,
                 /* For BOTTOM field we need to add the first line */
                 if( i_field == 1 )
                 {
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                     p_in += p_pic->p[i_plane].i_pitch;
                     p_out += p_outpic->p[i_plane].i_pitch;
                 }
@@ -714,13 +703,11 @@ static void RenderBob( vout_thread_t *p_vout,
                 {
                     for( ; p_out < p_out_end ; )
                     {
-                        p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                                  p_pic->p[i_plane].i_pitch );
+                        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                         p_out += p_outpic->p[i_plane].i_pitch;
 
-                        p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                                  p_pic->p[i_plane].i_pitch );
+                        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                         p_in += 2 * p_pic->p[i_plane].i_pitch;
                         p_out += p_outpic->p[i_plane].i_pitch;
@@ -730,24 +717,21 @@ static void RenderBob( vout_thread_t *p_vout,
                 {
                     for( ; p_out < p_out_end ; )
                     {
-                        p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                                  p_pic->p[i_plane].i_pitch );
+                        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                         p_out += p_outpic->p[i_plane].i_pitch;
                         p_in += 2 * p_pic->p[i_plane].i_pitch;
                     }
                 }
 
-                p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
+                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
                 /* For TOP field we need to add the last line */
                 if( i_field == 0 )
                 {
                     p_in += p_pic->p[i_plane].i_pitch;
                     p_out += p_outpic->p[i_plane].i_pitch;
-                    p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                              p_pic->p[i_plane].i_pitch );
+                    vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                 }
                 break;
         }
@@ -778,8 +762,7 @@ static void RenderLinear( vout_thread_t *p_vout,
         /* For BOTTOM field we need to add the first line */
         if( i_field == 1 )
         {
-            p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                      p_pic->p[i_plane].i_pitch );
+            vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
             p_in += p_pic->p[i_plane].i_pitch;
             p_out += p_outpic->p[i_plane].i_pitch;
         }
@@ -788,8 +771,7 @@ static void RenderLinear( vout_thread_t *p_vout,
 
         for( ; p_out < p_out_end ; )
         {
-            p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                      p_pic->p[i_plane].i_pitch );
+            vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
             p_out += p_outpic->p[i_plane].i_pitch;
 
@@ -800,16 +782,14 @@ static void RenderLinear( vout_thread_t *p_vout,
             p_out += p_outpic->p[i_plane].i_pitch;
         }
 
-        p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                  p_pic->p[i_plane].i_pitch );
+        vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
 
         /* For TOP field we need to add the last line */
         if( i_field == 0 )
         {
             p_in += p_pic->p[i_plane].i_pitch;
             p_out += p_outpic->p[i_plane].i_pitch;
-            p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                      p_pic->p[i_plane].i_pitch );
+            vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
         }
     }
     EndMerge();
@@ -866,8 +846,7 @@ static void RenderBlend( vout_thread_t *p_vout,
             case VLC_FOURCC('I','Y','U','V'):
             case VLC_FOURCC('Y','V','1','2'):
                 /* First line: simple copy */
-                p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
+                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                 p_out += p_outpic->p[i_plane].i_pitch;
 
                 /* Remaining lines: mean value */
@@ -883,8 +862,7 @@ static void RenderBlend( vout_thread_t *p_vout,
 
             case VLC_FOURCC('I','4','2','2'):
                 /* First line: simple copy */
-                p_vout->p_libvlc->pf_memcpy( p_out, p_in,
-                                          p_pic->p[i_plane].i_pitch );
+                vlc_memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
                 p_out += p_outpic->p[i_plane].i_pitch;
 
                 /* Remaining lines: mean value */
@@ -2082,11 +2060,11 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_cmd,
     }
 
     /* We need to kill the old vout */
-
-    DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
-
-    vlc_object_detach( p_vout->p_sys->p_vout );
-    vout_Destroy( p_vout->p_sys->p_vout );
+    if( p_vout->p_sys->p_vout )
+    {
+        DEL_CALLBACKS( p_vout->p_sys->p_vout, SendEvents );
+        vout_CloseAndRelease( p_vout->p_sys->p_vout );
+    }
 
     /* Try to open a new video output */
     p_vout->p_sys->p_vout = SpawnRealVout( p_vout );
@@ -2128,12 +2106,9 @@ static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
     picture_t *p_pic_dst;
 
     /* Request output picture */
-    p_pic_dst = p_filter->pf_vout_buffer_new( p_filter );
+    p_pic_dst = filter_NewPicture( p_filter );
     if( p_pic_dst == NULL )
-    {
-        msg_Warn( p_filter, "can't get output picture" );
-        return NULL;
-    }
+        return p_pic;
 
     switch( p_vout->p_sys->i_mode )
     {
@@ -2142,7 +2117,7 @@ static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
             RenderDiscard( p_vout, p_pic_dst, p_pic, 0 );
 #endif
             msg_Err( p_vout, "discarding lines is not supported yet" );
-            p_pic_dst->pf_release( p_pic_dst );
+            picture_Release( p_pic_dst );
             return p_pic;
             break;
 
@@ -2159,7 +2134,7 @@ static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
             RenderLinear( p_vout, pp_outpic[1], p_pic, 1 );
 #endif
             msg_Err( p_vout, "doubling the frame rate is not supported yet" );
-            p_pic_dst->pf_release( p_pic_dst );
+            picture_Release( p_pic_dst );
             return p_pic;
             break;
 
@@ -2176,13 +2151,10 @@ static picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
             break;
     }
 
-    p_pic_dst->date = p_pic->date;
-    p_pic_dst->b_force = p_pic->b_force;
-    p_pic_dst->i_nb_fields = p_pic->i_nb_fields;
+    picture_CopyProperties( p_pic_dst, p_pic );
     p_pic_dst->b_progressive = true;
-    p_pic_dst->b_top_field_first = p_pic->b_top_field_first;
 
-    p_pic->pf_release( p_pic );
+    picture_Release( p_pic );
     return p_pic_dst;
 }