[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