[vlc-devel] [PATCH 1/2] video_output:display: allow some vout to handle the source aspect ratio/crop before display

Steve Lhomme robux4 at ycbcr.xyz
Mon Aug 20 16:42:50 CEST 2018


Rather than waiting for the next display loop which may itself request another change.
---
 include/vlc_vout_display.h |   1 +
 src/video_output/display.c | 197 +++++++++++++++++++++++--------------
 2 files changed, 122 insertions(+), 76 deletions(-)

diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index bfa7c20997..e0e842fc0e 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -115,6 +115,7 @@ typedef struct {
     bool is_slow;                           /* The picture memory has slow read/write */
     bool has_double_click;                  /* Is double-click generated */
     bool has_pictures_invalid;              /* Will VOUT_DISPLAY_EVENT_PICTURES_INVALID be used */
+    int dynamic_src;                        /* bitmask of VOUT_DISPLAY_CHANGE_SOURCE_xxx supported dynamically */
     const vlc_fourcc_t *subpicture_chromas; /* List of supported chromas for subpicture rendering. */
 } vout_display_info_t;
 
diff --git a/src/video_output/display.c b/src/video_output/display.c
index 46d761f4ef..c544709695 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -639,6 +639,94 @@ static void VoutDisplayCropRatio(int *left, int *top, int *right, int *bottom,
     }
 }
 
+static void UpdateSourceCrop(vout_display_t *vd)
+{
+    vout_display_owner_sys_t *osys = vd->owner.sys;
+
+    unsigned crop_num = osys->crop.num;
+    unsigned crop_den = osys->crop.den;
+
+    if (crop_num != 0 && crop_den != 0) {
+        video_format_t fmt = osys->source;
+        fmt.i_sar_num = vd->source.i_sar_num;
+        fmt.i_sar_den = vd->source.i_sar_den;
+        VoutDisplayCropRatio(&osys->crop.left,  &osys->crop.top,
+                             &osys->crop.right, &osys->crop.bottom,
+                             &fmt, crop_num, crop_den);
+    }
+
+    const int right_max  = osys->source.i_x_offset + osys->source.i_visible_width;
+    const int bottom_max = osys->source.i_y_offset + osys->source.i_visible_height;
+    int left   = VLC_CLIP((int)osys->source.i_x_offset + osys->crop.left,
+                          0, right_max - 1);
+    int top    = VLC_CLIP((int)osys->source.i_y_offset + osys->crop.top,
+                          0, bottom_max - 1);
+    int right, bottom;
+
+    if (osys->crop.right <= 0)
+        right = (int)(osys->source.i_x_offset + osys->source.i_visible_width) + osys->crop.right;
+    else
+        right = (int)osys->source.i_x_offset + osys->crop.right;
+    right = VLC_CLIP(right, left + 1, right_max);
+    if (osys->crop.bottom <= 0)
+        bottom = (int)(osys->source.i_y_offset + osys->source.i_visible_height) + osys->crop.bottom;
+    else
+        bottom = (int)osys->source.i_y_offset + osys->crop.bottom;
+    bottom = VLC_CLIP(bottom, top + 1, bottom_max);
+
+    vd->source.i_x_offset       = left;
+    vd->source.i_y_offset       = top;
+    vd->source.i_visible_width  = right - left;
+    vd->source.i_visible_height = bottom - top;
+    video_format_Print(VLC_OBJECT(vd), "SOURCE ", &osys->source);
+    video_format_Print(VLC_OBJECT(vd), "CROPPED", &vd->source);
+    vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_CROP);
+    osys->crop.left   = left - osys->source.i_x_offset;
+    osys->crop.top    = top  - osys->source.i_y_offset;
+    /* FIXME for right/bottom we should keep the 'type' border vs window */
+    osys->crop.right  = right -
+                        (osys->source.i_x_offset + osys->source.i_visible_width);
+    osys->crop.bottom = bottom -
+                        (osys->source.i_y_offset + osys->source.i_visible_height);
+    osys->crop.num    = crop_num;
+    osys->crop.den    = crop_den;
+
+    osys->ch_crop = false;
+}
+
+static void UpdateSourceAspect(vout_display_t *vd)
+{
+    vout_display_owner_sys_t *osys = vd->owner.sys;
+
+    if (osys->sar.num > 0 && osys->sar.den > 0) {
+        vd->source.i_sar_num = osys->sar.num;
+        vd->source.i_sar_den = osys->sar.den;
+    } else {
+        vd->source.i_sar_num = osys->source.i_sar_num;
+        vd->source.i_sar_den = osys->source.i_sar_den;
+    }
+
+    vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_ASPECT);
+    osys->sar.num = vd->source.i_sar_num;
+    osys->sar.den = vd->source.i_sar_den;
+
+    /* If a crop ratio is requested, recompute the parameters */
+    if (osys->crop.num != 0 && osys->crop.den != 0)
+        osys->ch_crop = true;
+
+    osys->ch_sar  = false;
+}
+
+static void UpdateSourceMultiview(vout_display_t *vd)
+{
+    vout_display_owner_sys_t *osys = vd->owner.sys;
+
+    vd->source.multiview_mode = osys->source.multiview_mode;
+    vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_MULTIVIEW);
+
+    osys->ch_src_multiview = false;
+}
+
 bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
 {
     vout_display_owner_sys_t *osys = vd->owner.sys;
@@ -685,19 +773,8 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
     bool fit_window = false;
 
     if (osys->ch_sar) {
-        if (osys->sar.num > 0 && osys->sar.den > 0) {
-            vd->source.i_sar_num = osys->sar.num;
-            vd->source.i_sar_den = osys->sar.den;
-        } else {
-            vd->source.i_sar_num = osys->source.i_sar_num;
-            vd->source.i_sar_den = osys->source.i_sar_den;
-        }
-
-        vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_ASPECT);
+        UpdateSourceAspect(vd);
         fit_window = true;
-        osys->sar.num = vd->source.i_sar_num;
-        osys->sar.den = vd->source.i_sar_den;
-        osys->ch_sar  = false;
 
         /* If a crop ratio is requested, recompute the parameters */
         if (osys->crop.num != 0 && osys->crop.den != 0)
@@ -705,63 +782,11 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
     }
 
     if (osys->ch_crop) {
-        unsigned crop_num = osys->crop.num;
-        unsigned crop_den = osys->crop.den;
-
-        if (crop_num != 0 && crop_den != 0) {
-            video_format_t fmt = osys->source;
-            fmt.i_sar_num = vd->source.i_sar_num;
-            fmt.i_sar_den = vd->source.i_sar_den;
-            VoutDisplayCropRatio(&osys->crop.left,  &osys->crop.top,
-                                 &osys->crop.right, &osys->crop.bottom,
-                                 &fmt, crop_num, crop_den);
-        }
-
-        const int right_max  = osys->source.i_x_offset + osys->source.i_visible_width;
-        const int bottom_max = osys->source.i_y_offset + osys->source.i_visible_height;
-        int left   = VLC_CLIP((int)osys->source.i_x_offset + osys->crop.left,
-                              0, right_max - 1);
-        int top    = VLC_CLIP((int)osys->source.i_y_offset + osys->crop.top,
-                              0, bottom_max - 1);
-        int right, bottom;
-
-        if (osys->crop.right <= 0)
-            right = (int)(osys->source.i_x_offset + osys->source.i_visible_width) + osys->crop.right;
-        else
-            right = (int)osys->source.i_x_offset + osys->crop.right;
-        right = VLC_CLIP(right, left + 1, right_max);
-        if (osys->crop.bottom <= 0)
-            bottom = (int)(osys->source.i_y_offset + osys->source.i_visible_height) + osys->crop.bottom;
-        else
-            bottom = (int)osys->source.i_y_offset + osys->crop.bottom;
-        bottom = VLC_CLIP(bottom, top + 1, bottom_max);
-
-        vd->source.i_x_offset       = left;
-        vd->source.i_y_offset       = top;
-        vd->source.i_visible_width  = right - left;
-        vd->source.i_visible_height = bottom - top;
-        video_format_Print(VLC_OBJECT(vd), "SOURCE ", &osys->source);
-        video_format_Print(VLC_OBJECT(vd), "CROPPED", &vd->source);
-        vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_CROP);
+        UpdateSourceCrop(vd);
         fit_window = true;
-        osys->crop.left   = left - osys->source.i_x_offset;
-        osys->crop.top    = top  - osys->source.i_y_offset;
-        /* FIXME for right/bottom we should keep the 'type' border vs window */
-        osys->crop.right  = right -
-                            (osys->source.i_x_offset + osys->source.i_visible_width);
-        osys->crop.bottom = bottom -
-                            (osys->source.i_y_offset + osys->source.i_visible_height);
-        osys->crop.num    = crop_num;
-        osys->crop.den    = crop_den;
         osys->ch_crop = false;
     }
 
-    if (osys->ch_src_multiview) {
-        vd->source.multiview_mode = osys->source.multiview_mode;
-        vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_MULTIVIEW);
-        osys->ch_src_multiview = false;
-    }
-
     if (osys->ch_stereo_mode) {
         vout_display_cfg_t cfg = osys->cfg;
 
@@ -830,6 +855,7 @@ void vout_FilterFlush(vout_display_t *vd)
 void vout_UpdateDisplaySourceProperties(vout_display_t *vd, const video_format_t *source)
 {
     vout_display_owner_sys_t *osys = vd->owner.sys;
+    bool fit_window = false;
 
     if (source->i_sar_num * osys->source.i_sar_den !=
         source->i_sar_den * osys->source.i_sar_num) {
@@ -839,11 +865,20 @@ void vout_UpdateDisplaySourceProperties(vout_display_t *vd, const video_format_t
         vlc_ureduce(&osys->source.i_sar_num, &osys->source.i_sar_den,
                     osys->source.i_sar_num, osys->source.i_sar_den, 0);
 
-        /* FIXME it will override any AR that the user would have forced */
-        osys->ch_sar = true;
-        osys->sar.num = osys->source.i_sar_num;
-        osys->sar.den = osys->source.i_sar_den;
+        if (vd->info.dynamic_src & (1<<VOUT_DISPLAY_CHANGE_SOURCE_ASPECT))
+        {
+            UpdateSourceAspect(vd);
+            fit_window = true;
+        }
+        else
+        {
+            /* FIXME it will override any AR that the user would have forced */
+            osys->ch_sar = true;
+            osys->sar.num = osys->source.i_sar_num;
+            osys->sar.den = osys->source.i_sar_den;
+        }
     }
+
     if (source->i_x_offset       != osys->source.i_x_offset ||
         source->i_y_offset       != osys->source.i_y_offset ||
         source->i_visible_width  != osys->source.i_visible_width ||
@@ -851,14 +886,24 @@ void vout_UpdateDisplaySourceProperties(vout_display_t *vd, const video_format_t
 
         video_format_CopyCrop(&osys->source, source);
 
-        /* Force the vout to reapply the current user crop settings over the new decoder
-         * crop settings. */
-        osys->ch_crop = true;
-    }
-    if (osys->source.multiview_mode != source->multiview_mode) {
-        osys->source.multiview_mode = source->multiview_mode;
-        osys->ch_src_multiview = true;
+        if (vd->info.dynamic_src & (1<<VOUT_DISPLAY_CHANGE_SOURCE_CROP))
+        {
+            UpdateSourceCrop(vd);
+            fit_window = true;
+        }
+        else
+        {
+            osys->ch_crop = true;
+        }
+    } else if (osys->ch_crop &&
+               vd->info.dynamic_src & (1<<VOUT_DISPLAY_CHANGE_SOURCE_CROP))
+    {
+        UpdateSourceCrop(vd);
+        fit_window = true;
     }
+
+    if (fit_window)
+        VoutDisplayFitWindow(vd, false);
 }
 
 void vout_SetDisplaySize(vout_display_t *vd, unsigned width, unsigned height)
-- 
2.17.0



More information about the vlc-devel mailing list