[vlc-commits] [Git][videolan/vlc][master] 4 commits: display: add fitting modes

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Sun May 29 11:33:52 UTC 2022



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
8e13708a by Rémi Denis-Courmont at 2022-05-29T11:12:33+00:00
display: add fitting modes

So far the video can only be fit within the window. This adds other
modes for fitting to the larger dimension, only to the width or only to
the height. These new modes in effect compute the scale/zoom
differently, potentially causing the video to be cropped.

- - - - -
412fc33c by Rémi Denis-Courmont at 2022-05-29T11:12:33+00:00
display: allow owner to set the fitting mode

(rather than just the fill flag)

- - - - -
401bf874 by Rémi Denis-Courmont at 2022-05-29T11:12:33+00:00
vout: allow owner to set the fitting mode

(rather than just the fill flag)

- - - - -
663af487 by Rémi Denis-Courmont at 2022-05-29T11:12:33+00:00
vout: add --fit option for fitting modes

- - - - -


9 changed files:

- include/vlc_vout_display.h
- modules/hw/mmal/vout.c
- modules/video_output/splitter.c
- src/libvlc-module.c
- src/video_output/display.c
- src/video_output/video_output.c
- src/video_output/vout_internal.h
- src/video_output/vout_intf.c
- src/video_output/vout_wrapper.h


Changes:

=====================================
include/vlc_vout_display.h
=====================================
@@ -77,6 +77,17 @@ typedef struct vlc_video_align {
 } vlc_video_align_t;
 /** @} */
 
+/**
+ * Video automatic scale fitting.
+ */
+enum vlc_video_fitting {
+    VLC_VIDEO_FIT_NONE /**< No automatic scaling (use explicit zoom ratio) */,
+    VLC_VIDEO_FIT_SMALLER /**< Fit inside / to smallest dimension */,
+    VLC_VIDEO_FIT_LARGER /**< Fit outside / to largest dimension */,
+    VLC_VIDEO_FIT_WIDTH /**< Fit to width */,
+    VLC_VIDEO_FIT_HEIGHT /**< Fit to height */,
+};
+
 /**
  * Display placement and zoom configuration.
  */
@@ -86,8 +97,8 @@ struct vout_display_placement {
     vlc_rational_t sar; /**< Requested sample aspect ratio */
 
     vlc_video_align_t align; /**< Alignment within the window */
-    bool autoscale; /**< Automatic scaling/fitting flag */
-    vlc_rational_t zoom; /**< Zoom ratio (if autoscale is disabled) */
+    enum vlc_video_fitting fitting; /**< Scaling/fitting mode */
+    vlc_rational_t zoom; /**< Zoom ratio (if fitting is disabled) */
 };
 
 /**
@@ -95,7 +106,7 @@ struct vout_display_placement {
  *
  * This primarily controls the size of the display area within the video
  * window, as follows:
- * - If \ref vout_display_cfg::display::autoscale is set,
+ * - If \ref vout_display_cfg::display::fitting is not disabled,
  *   the video size is fitted to the display size.
  * - If \ref vout_display_cfg::window "window" size is valid, the video size
  *   is set to the window size,
@@ -134,7 +145,7 @@ enum vout_display_query {
     VOUT_DISPLAY_CHANGE_DISPLAY_SIZE,
 
     /**
-     * Notifies a change of the display fill display flag by the user.
+     * Notifies a change of the display fitting mode by the user.
      *
      * \retval VLC_SUCCESS if the display handled the change
      * \retval VLC_EGENERIC if a \ref vlc_display_operations::reset_pictures


=====================================
modules/hw/mmal/vout.c
=====================================
@@ -520,7 +520,7 @@ place_dest(vout_display_t *vd, const video_format_t * fmt)
 
     dp.width = sys->display_width;
     dp.height = sys->display_height;
-    dp.autoscale = true;
+    dp.fitting = VLC_VIDEO_FIT_SMALLER;
     vout_display_PlacePicture(&place, fmt, &dp);
 
     sys->dest_rect = place_to_mmal_rect(place);


=====================================
modules/video_output/splitter.c
=====================================
@@ -283,7 +283,7 @@ static int vlc_vidsplit_Open(vout_display_t *vd,
                 .height = 0,
                 .sar = { 1, 1 },
                 .align = { 0, 0 } /* TODO */,
-                .autoscale = true,
+                .fitting = VLC_VIDEO_FIT_SMALLER,
                 .zoom = { 1, 1 },
             },
         };


=====================================
src/libvlc-module.c
=====================================
@@ -35,6 +35,7 @@
 #include <vlc_common.h>
 #include <vlc_plugin.h>
 #include <vlc_cpu.h>
+#include <vlc_vout_display.h>
 #include "libvlc.h"
 #include "modules/modules.h"
 
@@ -454,6 +455,18 @@ static const char *const screensaver_texts[] = {
 #define AUTOSCALE_LONGTEXT N_( \
     "Let the video scale to fit a given window or fullscreen.")
 
+#define FIT_TEXT N_("Video fitting")
+#define FIT_LONGTEXT N_( \
+    "This selects the dimension according to which the video will be scaled.")
+
+static const int fit_values[] = {
+    VLC_VIDEO_FIT_SMALLER, VLC_VIDEO_FIT_LARGER,
+    VLC_VIDEO_FIT_WIDTH, VLC_VIDEO_FIT_HEIGHT,
+};
+static const char *const fit_descriptions[] = {
+    N_("Smaller"), N_("Larger"), N_("Width"), N_("Height"),
+};
+
 #define CUSTOM_CROP_RATIOS_TEXT N_("Custom crop ratios list")
 #define CUSTOM_CROP_RATIOS_LONGTEXT N_( \
     "Comma separated list of crop ratios which will be added in the " \
@@ -1690,6 +1703,9 @@ vlc_module_begin ()
     add_bool( "autoscale", true, AUTOSCALE_TEXT, AUTOSCALE_LONGTEXT )
         change_safe ()
     add_obsolete_float( "scale" ) /* since 3.0.0 */
+    add_integer("fit", VLC_VIDEO_FIT_SMALLER, FIT_TEXT, FIT_LONGTEXT)
+        change_integer_list(fit_values, fit_descriptions)
+        change_safe()
     add_string( "monitor-par", NULL,
                 MASPECT_RATIO_TEXT, MASPECT_RATIO_LONGTEXT )
     add_string( "custom-aspect-ratios", NULL, CUSTOM_ASPECT_RATIOS_TEXT,


=====================================
src/video_output/display.c
=====================================
@@ -113,7 +113,7 @@ void vout_display_PlacePicture(vout_display_place_t *restrict place,
     video_format_ApplyRotation(&source_rot, source);
     source = &source_rot;
 
-    if (dp->autoscale) {
+    if (dp->fitting != VLC_VIDEO_FIT_NONE) {
         display_width  = dp->width;
         display_height = dp->height;
     } else
@@ -128,8 +128,26 @@ void vout_display_PlacePicture(vout_display_place_t *restrict place,
     const int64_t scaled_width  = (int64_t)width  * display_height * dp->sar.den * source->i_sar_num / (height * source->i_sar_den * dp->sar.num);
 
     if (source->projection_mode == PROJECTION_MODE_RECTANGULAR) {
-        /* We keep the solution that avoid filling outside the display */
-        if (scaled_width <= dp->width) {
+        bool fit_height;
+
+        switch (dp->fitting) {
+            case VLC_VIDEO_FIT_NONE:
+            case VLC_VIDEO_FIT_SMALLER:
+                /* We keep the solution fitting within the display */
+                fit_height = scaled_width <= dp->width;
+                break;
+            case VLC_VIDEO_FIT_LARGER:
+                fit_height = scaled_width >= dp->width;
+                break;
+            case VLC_VIDEO_FIT_WIDTH:
+                fit_height = false;
+                break;
+            case VLC_VIDEO_FIT_HEIGHT:
+                fit_height = true;
+                break;
+        }
+
+        if (fit_height) {
             place->width  = scaled_width;
             place->height = display_height;
         } else {
@@ -527,14 +545,14 @@ void vout_display_SetSize(vout_display_t *vd, unsigned width, unsigned height)
         vout_display_Reset(vd);
 }
 
-void vout_SetDisplayFilled(vout_display_t *vd, bool is_filled)
+void vout_SetDisplayFitting(vout_display_t *vd, enum vlc_video_fitting fit)
 {
     vout_display_priv_t *osys = container_of(vd, vout_display_priv_t, display);
 
-    if (is_filled == osys->cfg.display.autoscale)
+    if (fit == osys->cfg.display.fitting)
         return; /* nothing to do */
 
-    osys->cfg.display.autoscale = is_filled;
+    osys->cfg.display.fitting = fit;
     if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_DISPLAY_FILLED))
         vout_display_Reset(vd);
 }
@@ -546,7 +564,7 @@ void vout_SetDisplayZoom(vout_display_t *vd, unsigned num, unsigned den)
     osys->cfg.display.zoom.num = num;
     osys->cfg.display.zoom.den = den;
 
-    if (osys->cfg.display.autoscale)
+    if (osys->cfg.display.fitting != VLC_VIDEO_FIT_NONE)
         return; /* zoom has no effects */
     if (osys->cfg.display.zoom.num * den == num * osys->cfg.display.zoom.den)
         return; /* zoom has not changed */


=====================================
src/video_output/video_output.c
=====================================
@@ -484,20 +484,20 @@ void vout_ChangeDisplaySize(vout_thread_t *vout,
     vlc_mutex_unlock(&sys->display_lock);
 }
 
-void vout_ChangeDisplayFilled(vout_thread_t *vout, bool is_filled)
+void vout_ChangeDisplayFitting(vout_thread_t *vout, enum vlc_video_fitting fit)
 {
     vout_thread_sys_t *sys = VOUT_THREAD_TO_SYS(vout);
     assert(!sys->dummy);
 
     vlc_mutex_lock(&sys->window_lock);
-    sys->display_cfg.display.autoscale = is_filled;
+    sys->display_cfg.display.fitting = fit;
     /* no window size update here */
 
     vlc_mutex_lock(&sys->display_lock);
     vlc_mutex_unlock(&sys->window_lock);
 
     if (sys->display != NULL)
-        vout_SetDisplayFilled(sys->display, is_filled);
+        vout_SetDisplayFitting(sys->display, fit);
     vlc_mutex_unlock(&sys->display_lock);
 }
 
@@ -663,7 +663,8 @@ static void VoutGetDisplayCfg(vout_thread_sys_t *p_vout, const video_format_t *f
     const int display_height = var_GetInteger(vout, "height");
     cfg->display.width   = display_width > 0  ? display_width  : 0;
     cfg->display.height  = display_height > 0 ? display_height : 0;
-    cfg->display.autoscale = var_GetBool(vout, "autoscale");
+    cfg->display.fitting = var_GetBool(vout, "autoscale")
+        ? var_InheritFit(VLC_OBJECT(vout)) : VLC_VIDEO_FIT_NONE;
     unsigned msar_num, msar_den;
     if (var_InheritURational(vout, &msar_num, &msar_den, "monitor-par") ||
         msar_num <= 0 || msar_den <= 0) {


=====================================
src/video_output/vout_internal.h
=====================================
@@ -153,7 +153,7 @@ void vout_ChangeWindowed(vout_thread_t *);
 void vout_ChangeWindowState(vout_thread_t *, unsigned state);
 void vout_ChangeDisplaySize(vout_thread_t *, unsigned width, unsigned height,
                             void (*ack_cb)(void *), void *opaque);
-void vout_ChangeDisplayFilled(vout_thread_t *, bool is_filled);
+void vout_ChangeDisplayFitting(vout_thread_t *, enum vlc_video_fitting);
 void vout_ChangeZoom(vout_thread_t *, unsigned num, unsigned den);
 void vout_ChangeDisplayAspectRatio(vout_thread_t *, unsigned num, unsigned den);
 void vout_ChangeCrop(vout_thread_t *, const struct vout_crop *);
@@ -171,6 +171,7 @@ void vout_CreateVars( vout_thread_t * );
 void vout_IntfInit( vout_thread_t * );
 void vout_IntfReinit( vout_thread_t * );
 void vout_IntfDeinit(vlc_object_t *);
+enum vlc_video_fitting var_InheritFit(vlc_object_t *);
 
 /* */
 ssize_t vout_RegisterSubpictureChannelInternal( vout_thread_t *,


=====================================
src/video_output/vout_intf.c
=====================================
@@ -151,6 +151,21 @@ static void AddCustomRatios( vout_thread_t *p_vout, const char *psz_var,
     }
 }
 
+enum vlc_video_fitting var_InheritFit(vlc_object_t *obj)
+{
+    int64_t v = var_InheritInteger(obj, "fit");
+    /* Safe variable => paranoid checks */
+    switch (v) {
+        case VLC_VIDEO_FIT_SMALLER:
+        case VLC_VIDEO_FIT_LARGER:
+        case VLC_VIDEO_FIT_WIDTH:
+        case VLC_VIDEO_FIT_HEIGHT:
+            return v;
+        default:
+            return VLC_VIDEO_FIT_SMALLER;
+    }
+}
+
 void vout_CreateVars( vout_thread_t *p_vout )
 {
     vlc_value_t val;
@@ -536,9 +551,11 @@ static int AutoScaleCallback( vlc_object_t *obj, char const *name,
                               vlc_value_t prev, vlc_value_t cur, void *data )
 {
     vout_thread_t *p_vout = (vout_thread_t *)obj;
+    enum vlc_video_fitting fit = cur.b_bool ? var_InheritFit(obj)
+                                            : VLC_VIDEO_FIT_NONE;
 
     (void) name; (void) prev; (void) data;
-    vout_ChangeDisplayFilled(p_vout, cur.b_bool);
+    vout_ChangeDisplayFitting(p_vout, fit);
     return VLC_SUCCESS;
 }
 


=====================================
src/video_output/vout_wrapper.h
=====================================
@@ -34,7 +34,7 @@ bool vout_IsDisplayFiltered(vout_display_t *);
 picture_t * vout_ConvertForDisplay(vout_display_t *, picture_t *);
 void vout_FilterFlush(vout_display_t *);
 
-void vout_SetDisplayFilled(vout_display_t *, bool is_filled);
+void vout_SetDisplayFitting(vout_display_t *, enum vlc_video_fitting);
 void vout_SetDisplayZoom(vout_display_t *, unsigned num, unsigned den);
 void vout_SetDisplayAspect(vout_display_t *, unsigned num, unsigned den);
 void vout_SetDisplayCrop(vout_display_t *, const struct vout_crop *);



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/350ea55ea5125c8873449471ef0ead41d8d41905...663af4870a5c1dccce891310d7d8f52f09049be2

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/350ea55ea5125c8873449471ef0ead41d8d41905...663af4870a5c1dccce891310d7d8f52f09049be2
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list