Commit 6d0e1d17 authored by Laurent Aimar's avatar Laurent Aimar

Fixed crop parameters when the decoded video has crop parameters.

Now vout_SetDisplayCrop() takes crop parameters relative to the visible part.
parent 47d9c754
...@@ -86,7 +86,7 @@ VLC_EXPORT(void, vout_SetDisplayFilled, (vout_display_t *, bool is_filled)); ...@@ -86,7 +86,7 @@ VLC_EXPORT(void, vout_SetDisplayFilled, (vout_display_t *, bool is_filled));
VLC_EXPORT(void, vout_SetDisplayZoom, (vout_display_t *, int num, int den)); VLC_EXPORT(void, vout_SetDisplayZoom, (vout_display_t *, int num, int den));
VLC_EXPORT(void, vout_SetWindowState, (vout_display_t *, unsigned state)); VLC_EXPORT(void, vout_SetWindowState, (vout_display_t *, unsigned state));
VLC_EXPORT(void, vout_SetDisplayAspect, (vout_display_t *, unsigned dar_num, unsigned dar_den)); VLC_EXPORT(void, vout_SetDisplayAspect, (vout_display_t *, unsigned dar_num, unsigned dar_den));
VLC_EXPORT(void, vout_SetDisplayCrop, (vout_display_t *, unsigned crop_num, unsigned crop_den, unsigned x, unsigned y, unsigned width, unsigned height)); VLC_EXPORT(void, vout_SetDisplayCrop, (vout_display_t *, unsigned crop_num, unsigned crop_den, unsigned left, unsigned top, int right, int bottom));
VLC_EXPORT(vout_opengl_t *, vout_GetDisplayOpengl, (vout_display_t *)); VLC_EXPORT(vout_opengl_t *, vout_GetDisplayOpengl, (vout_display_t *));
#endif /* VLC_VOUT_WRAPPER_H */ #endif /* VLC_VOUT_WRAPPER_H */
......
...@@ -316,10 +316,10 @@ struct vout_display_owner_sys_t { ...@@ -316,10 +316,10 @@ struct vout_display_owner_sys_t {
bool ch_crop; bool ch_crop;
struct { struct {
unsigned x; int left;
unsigned y; int top;
unsigned width; int right;
unsigned height; int bottom;
unsigned num; unsigned num;
unsigned den; unsigned den;
} crop; } crop;
...@@ -738,8 +738,7 @@ static void VoutDisplayFitWindow(vout_display_t *vd, bool default_size) ...@@ -738,8 +738,7 @@ static void VoutDisplayFitWindow(vout_display_t *vd, bool default_size)
vlc_mutex_unlock(&osys->lock); vlc_mutex_unlock(&osys->lock);
} }
static void VoutDisplayCropRatio(unsigned *x, unsigned *y, static void VoutDisplayCropRatio(int *left, int *top, int *right, int *bottom,
unsigned *width, unsigned *height,
const video_format_t *source, const video_format_t *source,
unsigned num, unsigned den) unsigned num, unsigned den)
{ {
...@@ -747,18 +746,16 @@ static void VoutDisplayCropRatio(unsigned *x, unsigned *y, ...@@ -747,18 +746,16 @@ static void VoutDisplayCropRatio(unsigned *x, unsigned *y,
unsigned scaled_height = (uint64_t)source->i_visible_width * den * source->i_sar_num / num / source->i_sar_den; unsigned scaled_height = (uint64_t)source->i_visible_width * den * source->i_sar_num / num / source->i_sar_den;
if (scaled_width < source->i_visible_width) { if (scaled_width < source->i_visible_width) {
*x = (source->i_visible_width - scaled_width) / 2; *left = (source->i_visible_width - scaled_width) / 2;
*y = 0; *top = 0;
*width = scaled_width; *right = *left + scaled_width;
*height = source->i_visible_height; *bottom = *top + source->i_visible_height;
} else { } else {
*x = 0; *left = 0;
*y = (source->i_visible_height - scaled_height) / 2; *top = (source->i_visible_height - scaled_height) / 2;
*width = source->i_visible_width; *right = *left + source->i_visible_width;
*height = scaled_height; *bottom = *top + scaled_height;
} }
*x += source->i_x_offset;
*y += source->i_y_offset;
} }
void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures) void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
...@@ -992,28 +989,38 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures) ...@@ -992,28 +989,38 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
video_format_t fmt = osys->source; video_format_t fmt = osys->source;
fmt.i_sar_num = source.i_sar_num; fmt.i_sar_num = source.i_sar_num;
fmt.i_sar_den = source.i_sar_den; fmt.i_sar_den = source.i_sar_den;
VoutDisplayCropRatio(&osys->crop.x, &osys->crop.y, VoutDisplayCropRatio(&osys->crop.left, &osys->crop.top,
&osys->crop.width, &osys->crop.height, &osys->crop.right, &osys->crop.bottom,
&fmt, crop_num, crop_den); &fmt, crop_num, crop_den);
} }
const int right_max = osys->source.i_x_offset + osys->source.i_visible_width;
source.i_x_offset = osys->crop.x; const int bottom_max = osys->source.i_y_offset + osys->source.i_visible_height;
source.i_y_offset = osys->crop.y; #define __CLIP(v, a, b) __MAX(__MIN(v, b), a)
source.i_visible_width = osys->crop.width; int left = __CLIP((int)osys->source.i_x_offset + osys->crop.left,
source.i_visible_height = osys->crop.height; 0, right_max - 1);
int top = __CLIP((int)osys->source.i_y_offset + osys->crop.top,
/* */ 0, bottom_max - 1);
const bool is_valid = source.i_x_offset < source.i_width && int right, bottom;
source.i_y_offset < source.i_height && if (osys->crop.right <= 0)
source.i_x_offset + source.i_visible_width <= source.i_width && right = (int)(osys->source.i_x_offset + osys->source.i_visible_width) + osys->crop.right;
source.i_y_offset + source.i_visible_height <= source.i_height && else
source.i_visible_width > 0 && source.i_visible_height > 0; right = (int)osys->source.i_x_offset + osys->crop.right;
right = __CLIP(right, left + 1, right_max);
if (!is_valid || vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_CROP, &source)) { if (osys->crop.bottom <= 0)
if (is_valid) bottom = (int)(osys->source.i_y_offset + osys->source.i_visible_height) + osys->crop.bottom;
msg_Err(vd, "Failed to change source crop TODO implement crop at core"); else
else bottom = (int)osys->source.i_y_offset + osys->crop.bottom;
msg_Err(vd, "Invalid crop requested"); bottom = __CLIP(bottom, top + 1, bottom_max);
source.i_x_offset = left;
source.i_y_offset = top;
source.i_visible_width = right - left;
source.i_visible_height = bottom - top;
#undef __CLIP
video_format_Print(VLC_OBJECT(vd), "SOURCE ", &osys->source);
video_format_Print(VLC_OBJECT(vd), "CROPPED", &source);
if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_SOURCE_CROP, &source)) {
msg_Err(vd, "Failed to change source crop TODO implement crop at core");
source = vd->source; source = vd->source;
crop_num = osys->crop_saved.num; crop_num = osys->crop_saved.num;
...@@ -1025,22 +1032,21 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures) ...@@ -1025,22 +1032,21 @@ void vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
osys->fit_window = 1; osys->fit_window = 1;
} }
vd->source = source; vd->source = source;
osys->crop.x = source.i_x_offset; osys->crop.left = source.i_x_offset - osys->source.i_x_offset;
osys->crop.y = source.i_y_offset; osys->crop.top = source.i_y_offset - osys->source.i_y_offset;
osys->crop.width = source.i_visible_width; /* FIXME for right/bottom we should keep the 'type' border vs window */
osys->crop.height = source.i_visible_height; osys->crop.right = (source.i_x_offset + source.i_visible_width) -
(osys->source.i_x_offset + osys->source.i_visible_width);
osys->crop.bottom = (source.i_y_offset + source.i_visible_height) -
(osys->source.i_y_offset + osys->source.i_visible_height);
osys->crop.num = crop_num; osys->crop.num = crop_num;
osys->crop.den = crop_den; osys->crop.den = crop_den;
osys->ch_crop = false; osys->ch_crop = false;
/* TODO fix when a ratio is used (complicated). */
const unsigned left = osys->crop.x - osys->source.i_x_offset;
const unsigned top = osys->crop.y - osys->source.i_y_offset;
const unsigned right = osys->source.i_visible_width - (osys->crop.width + osys->crop.x);
const unsigned bottom = osys->source.i_visible_height - (osys->crop.height + osys->crop.y);
vout_SendEventSourceCrop(osys->vout, vout_SendEventSourceCrop(osys->vout,
osys->crop.num, osys->crop.den, osys->crop.num, osys->crop.den,
left, top, right, bottom); osys->crop.left, osys->crop.top,
-osys->crop.right, -osys->crop.bottom);
} }
/* */ /* */
...@@ -1150,19 +1156,19 @@ void vout_SetDisplayAspect(vout_display_t *vd, unsigned dar_num, unsigned dar_de ...@@ -1150,19 +1156,19 @@ void vout_SetDisplayAspect(vout_display_t *vd, unsigned dar_num, unsigned dar_de
} }
void vout_SetDisplayCrop(vout_display_t *vd, void vout_SetDisplayCrop(vout_display_t *vd,
unsigned crop_num, unsigned crop_den, unsigned crop_num, unsigned crop_den,
unsigned x, unsigned y, unsigned width, unsigned height) unsigned left, unsigned top, int right, int bottom)
{ {
vout_display_owner_sys_t *osys = vd->owner.sys; vout_display_owner_sys_t *osys = vd->owner.sys;
if (osys->crop.x != x || osys->crop.y != y || if (osys->crop.left != (int)left || osys->crop.top != (int)top ||
osys->crop.width != width || osys->crop.height != height || osys->crop.right != right || osys->crop.bottom != bottom ||
(crop_num > 0 && crop_den > 0 && (crop_num > 0 && crop_den > 0 &&
(crop_num != osys->crop.num || crop_den != osys->crop.den))) { (crop_num != osys->crop.num || crop_den != osys->crop.den))) {
osys->crop.x = x; osys->crop.left = left;
osys->crop.y = y; osys->crop.top = top;
osys->crop.width = width; osys->crop.right = right;
osys->crop.height = height; osys->crop.bottom = bottom;
osys->crop.num = crop_num; osys->crop.num = crop_num;
osys->crop.den = crop_den; osys->crop.den = crop_den;
...@@ -1229,10 +1235,10 @@ static vout_display_t *DisplayNew(vout_thread_t *vout, ...@@ -1229,10 +1235,10 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
osys->event.fifo = NULL; osys->event.fifo = NULL;
osys->source = *source_org; osys->source = *source_org;
osys->crop.x = source_org->i_x_offset; osys->crop.left = 0;
osys->crop.y = source_org->i_y_offset; osys->crop.top = 0;
osys->crop.width = source_org->i_visible_width; osys->crop.right = 0;
osys->crop.height = source_org->i_visible_height; osys->crop.bottom = 0;
osys->crop_saved.num = 0; osys->crop_saved.num = 0;
osys->crop_saved.den = 0; osys->crop_saved.den = 0;
osys->crop.num = 0; osys->crop.num = 0;
...@@ -1278,10 +1284,10 @@ static vout_display_t *DisplayNew(vout_thread_t *vout, ...@@ -1278,10 +1284,10 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
osys->ch_sar = true; osys->ch_sar = true;
if (osys->wm_state != osys->wm_state_initial) if (osys->wm_state != osys->wm_state_initial)
osys->ch_wm_state = true; osys->ch_wm_state = true;
if (osys->crop.x != source.i_x_offset || if (source.i_x_offset != source_org->i_x_offset ||
osys->crop.y != source.i_y_offset || source.i_y_offset != source_org->i_y_offset ||
osys->crop.width != source.i_visible_width || source.i_visible_width != source_org->i_visible_width ||
osys->crop.height != source.i_visible_height) source.i_visible_height != source_org->i_visible_height)
osys->ch_crop = true; osys->ch_crop = true;
return p_display; return p_display;
......
...@@ -511,10 +511,10 @@ void vout_ControlChangeCropWindow(vout_thread_t *vout, ...@@ -511,10 +511,10 @@ void vout_ControlChangeCropWindow(vout_thread_t *vout,
{ {
vout_control_cmd_t cmd; vout_control_cmd_t cmd;
vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_WINDOW); vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_WINDOW);
cmd.u.window.x = x; cmd.u.window.x = __MAX(x, 0);
cmd.u.window.y = y; cmd.u.window.y = __MAX(y, 0);
cmd.u.window.width = width; cmd.u.window.width = __MAX(width, 0);
cmd.u.window.height = height; cmd.u.window.height = __MAX(height, 0);
vout_control_Push(&vout->p->control, &cmd); vout_control_Push(&vout->p->control, &cmd);
} }
...@@ -523,10 +523,10 @@ void vout_ControlChangeCropBorder(vout_thread_t *vout, ...@@ -523,10 +523,10 @@ void vout_ControlChangeCropBorder(vout_thread_t *vout,
{ {
vout_control_cmd_t cmd; vout_control_cmd_t cmd;
vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_BORDER); vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_BORDER);
cmd.u.border.left = left; cmd.u.border.left = __MAX(left, 0);
cmd.u.border.top = top; cmd.u.border.top = __MAX(top, 0);
cmd.u.border.right = right; cmd.u.border.right = __MAX(right, 0);
cmd.u.border.bottom = bottom; cmd.u.border.bottom = __MAX(bottom, 0);
vout_control_Push(&vout->p->control, &cmd); vout_control_Push(&vout->p->control, &cmd);
} }
...@@ -1180,39 +1180,26 @@ static void ThreadChangeAspectRatio(vout_thread_t *vout, ...@@ -1180,39 +1180,26 @@ static void ThreadChangeAspectRatio(vout_thread_t *vout,
static void ThreadExecuteCropWindow(vout_thread_t *vout, static void ThreadExecuteCropWindow(vout_thread_t *vout,
unsigned crop_num, unsigned crop_den,
unsigned x, unsigned y, unsigned x, unsigned y,
unsigned width, unsigned height) unsigned width, unsigned height)
{ {
const video_format_t *source = &vout->p->original; vout_SetDisplayCrop(vout->p->display.vd, 0, 0,
x, y, width, height);
vout_SetDisplayCrop(vout->p->display.vd,
crop_num, crop_den,
source->i_x_offset + x,
source->i_y_offset + y,
width, height);
} }
static void ThreadExecuteCropBorder(vout_thread_t *vout, static void ThreadExecuteCropBorder(vout_thread_t *vout,
unsigned left, unsigned top, unsigned left, unsigned top,
unsigned right, unsigned bottom) unsigned right, unsigned bottom)
{ {
const video_format_t *source = &vout->p->original; msg_Err(vout, "ThreadExecuteCropBorder %d.%d %dx%d", left, top, right, bottom);
ThreadExecuteCropWindow(vout, 0, 0, vout_SetDisplayCrop(vout->p->display.vd, 0, 0,
left, left, top, -(int)right, -(int)bottom);
top,
/* At worst, it becomes < 0 (but unsigned) and will be rejected */
source->i_visible_width - (left + right),
source->i_visible_height - (top + bottom));
} }
static void ThreadExecuteCropRatio(vout_thread_t *vout, static void ThreadExecuteCropRatio(vout_thread_t *vout,
unsigned num, unsigned den) unsigned num, unsigned den)
{ {
const video_format_t *source = &vout->p->original; vout_SetDisplayCrop(vout->p->display.vd, num, den,
ThreadExecuteCropWindow(vout, num, den, 0, 0, 0, 0);
0, 0,
source->i_visible_width,
source->i_visible_height);
} }
static int ThreadStart(vout_thread_t *vout, const vout_display_state_t *state) static int ThreadStart(vout_thread_t *vout, const vout_display_state_t *state)
...@@ -1436,7 +1423,7 @@ static void *Thread(void *object) ...@@ -1436,7 +1423,7 @@ static void *Thread(void *object)
ThreadExecuteCropRatio(vout, cmd.u.pair.a, cmd.u.pair.b); ThreadExecuteCropRatio(vout, cmd.u.pair.a, cmd.u.pair.b);
break; break;
case VOUT_CONTROL_CROP_WINDOW: case VOUT_CONTROL_CROP_WINDOW:
ThreadExecuteCropWindow(vout, 0, 0, ThreadExecuteCropWindow(vout,
cmd.u.window.x, cmd.u.window.y, cmd.u.window.x, cmd.u.window.y,
cmd.u.window.width, cmd.u.window.height); cmd.u.window.width, cmd.u.window.height);
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment