]> git.sesse.net Git - vlc/blobdiff - modules/video_filter/crop.c
Use var_InheritString for --decklink-video-connection.
[vlc] / modules / video_filter / crop.c
index e27a77121a288a4ccff52d7152abd1c5c4834e2b..497a46b0a3029eceeed8b748cdd03214024ff425 100644 (file)
@@ -36,8 +36,6 @@
 #include <vlc_vout.h>
 #include <vlc_dialog.h>
 
-#include "filter_common.h"
-
 #define BEST_AUTOCROP 1
 #ifdef BEST_AUTOCROP
     #define RATIO_MAX 15000  // 10*4/3 for a 360
@@ -76,6 +74,8 @@ static int FilterCallback ( vlc_object_t *, char const *,
 #define AUTOCROP_TEXT N_("Automatic cropping")
 #define AUTOCROP_LONGTEXT N_("Automatically detect black borders and crop them.")
 
+#define CROP_HELP N_("Remove borders of the video and replace them by black borders")
+
 #ifdef BEST_AUTOCROP
 #define RATIOMAX_TEXT N_("Ratio max (x 1000)")
 #define RATIOMAX_LONGTEXT N_("Maximum image ratio. The crop plugin will never automatically crop to a higher ratio (ie, to a more \"flat\" image). The value is x1000: 1333 means 4/3.")
@@ -103,13 +103,14 @@ static int FilterCallback ( vlc_object_t *, char const *,
 vlc_module_begin ()
     set_description( N_("Crop video filter") )
     set_shortname( N_("Crop" ))
+    set_help(CROP_HELP)
     set_category( CAT_VIDEO )
     set_subcategory( SUBCAT_VIDEO_VFILTER )
     set_capability( "video filter", 0 )
 
     add_string( "crop-geometry", NULL, NULL, GEOMETRY_TEXT,
                                              GEOMETRY_LONGTEXT, false )
-    add_bool( "autocrop", 0, NULL, AUTOCROP_TEXT,
+    add_bool( "autocrop", false, NULL, AUTOCROP_TEXT,
                                    AUTOCROP_LONGTEXT, false )
 
 #ifdef BEST_AUTOCROP
@@ -145,6 +146,7 @@ vlc_module_end ()
  *****************************************************************************/
 struct vout_sys_t
 {
+    vlc_mutex_t lock;
     vout_thread_t *p_vout;
 
     unsigned int i_x, i_y;
@@ -217,27 +219,27 @@ static int Init( vout_thread_t *p_vout )
     p_vout->fmt_out = p_vout->fmt_in;
 
     /* Shall we use autocrop ? */
-    p_vout->p_sys->b_autocrop = config_GetInt( p_vout, "autocrop" );
+    p_vout->p_sys->b_autocrop = var_InheritBool( p_vout, "autocrop" );
 #ifdef BEST_AUTOCROP
-    p_vout->p_sys->i_ratio_max = config_GetInt( p_vout, "autocrop-ratio-max" );
+    p_vout->p_sys->i_ratio_max =
+        var_InheritInteger( p_vout, "autocrop-ratio-max" );
     p_vout->p_sys->i_threshold =
-                    config_GetInt( p_vout, "autocrop-luminance-threshold" );
+        var_InheritInteger( p_vout, "autocrop-luminance-threshold" );
     p_vout->p_sys->i_skipPercent =
-                    config_GetInt( p_vout, "autocrop-skip-percent" );
+        var_InheritInteger( p_vout, "autocrop-skip-percent" );
     p_vout->p_sys->i_nonBlackPixel =
-                    config_GetInt( p_vout, "autocrop-non-black-pixels" );
-    p_vout->p_sys->i_diff = config_GetInt( p_vout, "autocrop-diff" );
-    p_vout->p_sys->i_time = config_GetInt( p_vout, "autocrop-time" );
-    vlc_value_t val={0};
-    var_Get( p_vout, "ratio-crop", &val );
-    val.psz_string = "0";
-    var_SetString( p_vout, "ratio-crop", val.psz_string);
+        var_InheritInteger( p_vout, "autocrop-non-black-pixels" );
+    p_vout->p_sys->i_diff =
+        var_InheritInteger( p_vout, "autocrop-diff" );
+    p_vout->p_sys->i_time =
+        var_InheritInteger( p_vout, "autocrop-time" );
+    var_SetString( p_vout, "ratio-crop", "0" );
 
     if (p_vout->p_sys->b_autocrop)
         p_vout->p_sys->i_ratio = 0;
     else
     {
-        p_vout->p_sys->i_ratio = config_GetInt( p_vout, "crop-ratio" );
+        p_vout->p_sys->i_ratio = var_InheritInteger( p_vout, "crop-ratio" );
         // ratio < width / height => ratio = 0 (unchange ratio)
         if (p_vout->p_sys->i_ratio < (p_vout->output.i_width * 1000) / p_vout->output.i_height)
             p_vout->p_sys->i_ratio = 0;
@@ -246,7 +248,7 @@ static int Init( vout_thread_t *p_vout )
 
 
     /* Get geometry value from the user */
-    psz_var = config_GetPsz( p_vout, "crop-geometry" );
+    psz_var = var_InheritString( p_vout, "crop-geometry" );
     if( psz_var )
     {
         char *psz_parser, *psz_tmp;
@@ -353,9 +355,9 @@ static int Init( vout_thread_t *p_vout )
                      p_vout->p_sys->i_x, p_vout->p_sys->i_y,
                      p_vout->p_sys->b_autocrop ? "" : "not " );
     /* Set current output image properties */
-    p_vout->p_sys->i_aspect = p_vout->fmt_out.i_aspect
-           * p_vout->fmt_out.i_visible_height / p_vout->p_sys->i_height
-           * p_vout->p_sys->i_width / p_vout->fmt_out.i_visible_width;
+    p_vout->p_sys->i_aspect = (int64_t)VOUT_ASPECT_FACTOR *
+        p_vout->fmt_out.i_sar_num * p_vout->p_sys->i_width /
+        (p_vout->fmt_out.i_sar_den * p_vout->p_sys->i_height);
 
 #ifdef BEST_AUTOCROP
     msg_Info( p_vout, "ratio %d",  p_vout->p_sys->i_aspect / 432);
@@ -364,20 +366,20 @@ static int Init( vout_thread_t *p_vout )
     fmt.i_height = fmt.i_visible_height = p_vout->p_sys->i_height;
     fmt.i_x_offset = fmt.i_y_offset = 0;
     fmt.i_chroma = p_vout->render.i_chroma;
-    fmt.i_aspect = p_vout->p_sys->i_aspect;
-    fmt.i_sar_num = p_vout->p_sys->i_aspect * fmt.i_height / fmt.i_width;
-    fmt.i_sar_den = VOUT_ASPECT_FACTOR;
+    fmt.i_sar_num = p_vout->p_sys->i_aspect * fmt.i_height;
+    fmt.i_sar_den = VOUT_ASPECT_FACTOR * fmt.i_width;
 
     /* Try to open the real video output */
     p_vout->p_sys->p_vout = vout_Create( p_vout, &fmt );
     if( p_vout->p_sys->p_vout == NULL )
     {
         msg_Err( p_vout, "failed to create vout" );
-        dialog_Fatal( p_vout, _("Cropping failed"),
+        dialog_Fatal( p_vout, _("Cropping failed"), "%s",
                         _("VLC could not open the video output module.") );
         return VLC_EGENERIC;
     }
 
+    vlc_mutex_init( &p_vout->p_sys->lock );
 #ifdef BEST_AUTOCROP
     var_AddCallback( p_vout, "ratio-crop", FilterCallback, NULL );
 #endif
@@ -403,6 +405,8 @@ static void End( vout_thread_t *p_vout )
     }
 
     vout_filter_ReleaseDirectBuffers( p_vout );
+    var_DelCallback( p_vout, "ratio-crop", FilterCallback, NULL );
+    vlc_mutex_destroy( &p_sys->lock );
 }
 
 /*****************************************************************************
@@ -435,6 +439,7 @@ static int Manage( vout_thread_t *p_vout )
     memset( &fmt, 0, sizeof(video_format_t) );
 
 #ifdef BEST_AUTOCROP
+    /* XXX: not thread-safe with FilterCallback */
     msg_Dbg( p_vout, "cropping at %ix%i+%i+%i, %sautocropping",
                      p_vout->p_sys->i_width, p_vout->p_sys->i_height,
                      p_vout->p_sys->i_x, p_vout->p_sys->i_y,
@@ -453,7 +458,6 @@ static int Manage( vout_thread_t *p_vout )
     fmt.i_height = fmt.i_visible_height = p_vout->p_sys->i_height;
     fmt.i_x_offset = fmt.i_y_offset = 0;
     fmt.i_chroma = p_vout->render.i_chroma;
-    fmt.i_aspect = p_vout->p_sys->i_aspect;
     fmt.i_sar_num = p_vout->p_sys->i_aspect * fmt.i_height / fmt.i_width;
     fmt.i_sar_den = VOUT_ASPECT_FACTOR;
 
@@ -461,14 +465,16 @@ static int Manage( vout_thread_t *p_vout )
     if( p_vout->p_sys->p_vout == NULL )
     {
         msg_Err( p_vout, "failed to create vout" );
-        dialog_Fatal( p_vout, _("Cropping failed"),
+        dialog_Fatal( p_vout, _("Cropping failed"), "%s",
                         _("VLC could not open the video output module.") );
         return VLC_EGENERIC;
     }
     vout_filter_AddChild( p_vout, p_vout->p_sys->p_vout, MouseEvent );
 
     p_vout->p_sys->b_changed = false;
+    vlc_mutex_lock( &p_vout->p_sys->lock );
     p_vout->p_sys->i_lastchange = 0;
+    vlc_mutex_unlock( &p_vout->p_sys->lock );
 
     return VLC_SUCCESS;
 }
@@ -535,10 +541,10 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic )
     vout_DisplayPicture( p_vout->p_sys->p_vout, p_outpic );
 
     /* The source image may still be in the cache ... parse it! */
+    vlc_mutex_lock( &p_vout->p_sys->lock );
     if( p_vout->p_sys->b_autocrop )
-    {
         UpdateStats( p_vout, p_pic );
-    }
+    vlc_mutex_unlock( &p_vout->p_sys->lock );
 }
 
 #ifdef BEST_AUTOCROP
@@ -823,14 +829,14 @@ static int MouseEvent( vlc_object_t *p_this, char const *psz_var,
     vout_thread_t *p_vout = p_data;
     VLC_UNUSED(p_this); VLC_UNUSED(oldval);
 
+    if( !strcmp( psz_var, "mouse-button-down" ) )
+        return var_SetChecked( p_vout, psz_var, VLC_VAR_INTEGER, newval );
+
     /* Translate the mouse coordinates
      * FIXME missing lock */
-    if( !strcmp( psz_var, "mouse-x" ) )
-        newval.i_int += p_vout->p_sys->i_x;
-    else if( !strcmp( psz_var, "mouse-y" ) )
-        newval.i_int += p_vout->p_sys->i_y;
-
-    return var_Set( p_vout, psz_var, newval );
+    newval.coords.x += p_vout->p_sys->i_x;
+    newval.coords.y += p_vout->p_sys->i_y;
+    return var_SetChecked( p_vout, psz_var, VLC_VAR_COORDS, newval );
 }
 
 #ifdef BEST_AUTOCROP
@@ -846,6 +852,7 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_var,
 
     if( !strcmp( psz_var, "ratio-crop" ) )
     {
+        vlc_mutex_lock( &p_vout->p_sys->lock );
         if ( !strcmp( newval.psz_string, "Auto" ) )
             p_vout->p_sys->i_ratio = 0;
         else
@@ -863,6 +870,7 @@ static int FilterCallback( vlc_object_t *p_this, char const *psz_var,
             if (p_vout->p_sys->i_ratio < p_vout->output.i_aspect / 432)
                 p_vout->p_sys->i_ratio = p_vout->output.i_aspect / 432;
         }
+        vlc_mutex_unlock( &p_vout->p_sys->lock );
      }
     return VLC_SUCCESS;
 }