mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
x11: add image cropping
Use the cropping metadata to crop the image. Remove deprecated display-region property to set a clipping rectangle.
This commit is contained in:
parent
65d2d56f03
commit
df94f2da81
3 changed files with 33 additions and 41 deletions
|
@ -227,6 +227,7 @@ static gboolean
|
||||||
gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
{
|
{
|
||||||
GstMetaXImage *meta;
|
GstMetaXImage *meta;
|
||||||
|
GstMetaVideoCrop *crop;
|
||||||
GstVideoRectangle src, dst, result;
|
GstVideoRectangle src, dst, result;
|
||||||
gboolean draw_border = FALSE;
|
gboolean draw_border = FALSE;
|
||||||
|
|
||||||
|
@ -267,9 +268,19 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
}
|
}
|
||||||
|
|
||||||
meta = gst_buffer_get_meta_ximage (ximage);
|
meta = gst_buffer_get_meta_ximage (ximage);
|
||||||
|
crop = gst_buffer_get_meta_video_crop (ximage);
|
||||||
|
|
||||||
src.w = meta->width;
|
if (crop) {
|
||||||
src.h = meta->height;
|
src.x = crop->x;
|
||||||
|
src.y = crop->y;
|
||||||
|
src.w = crop->width;
|
||||||
|
src.h = crop->height;
|
||||||
|
} else {
|
||||||
|
src.x = 0;
|
||||||
|
src.y = 0;
|
||||||
|
src.w = meta->width;
|
||||||
|
src.h = meta->height;
|
||||||
|
}
|
||||||
dst.w = ximagesink->xwindow->width;
|
dst.w = ximagesink->xwindow->width;
|
||||||
dst.h = ximagesink->xwindow->height;
|
dst.h = ximagesink->xwindow->height;
|
||||||
|
|
||||||
|
@ -289,7 +300,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
||||||
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
||||||
XShmPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
XShmPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
||||||
ximagesink->xwindow->gc, meta->ximage, 0, 0, result.x, result.y,
|
ximagesink->xwindow->gc, meta->ximage, src.x, src.y, result.x, result.y,
|
||||||
result.w, result.h, FALSE);
|
result.w, result.h, FALSE);
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_XSHM */
|
#endif /* HAVE_XSHM */
|
||||||
|
@ -299,7 +310,7 @@ gst_ximagesink_ximage_put (GstXImageSink * ximagesink, GstBuffer * ximage)
|
||||||
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
ximage, 0, 0, result.x, result.y, result.w, result.h,
|
||||||
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
ximagesink->xwindow->width, ximagesink->xwindow->height);
|
||||||
XPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
XPutImage (ximagesink->xcontext->disp, ximagesink->xwindow->win,
|
||||||
ximagesink->xwindow->gc, meta->ximage, 0, 0, result.x, result.y,
|
ximagesink->xwindow->gc, meta->ximage, src.x, src.y, result.x, result.y,
|
||||||
result.w, result.h);
|
result.w, result.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,8 +271,10 @@ static gboolean
|
||||||
gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
||||||
{
|
{
|
||||||
GstMetaXvImage *meta;
|
GstMetaXvImage *meta;
|
||||||
|
GstMetaVideoCrop *crop;
|
||||||
GstVideoRectangle result;
|
GstVideoRectangle result;
|
||||||
gboolean draw_border = FALSE;
|
gboolean draw_border = FALSE;
|
||||||
|
GstVideoRectangle src, dst;
|
||||||
|
|
||||||
/* We take the flow_lock. If expose is in there we don't want to run
|
/* We take the flow_lock. If expose is in there we don't want to run
|
||||||
concurrently from the data flow thread */
|
concurrently from the data flow thread */
|
||||||
|
@ -312,13 +314,21 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
||||||
|
|
||||||
meta = gst_buffer_get_meta_xvimage (xvimage);
|
meta = gst_buffer_get_meta_xvimage (xvimage);
|
||||||
|
|
||||||
if (xvimagesink->keep_aspect) {
|
crop = gst_buffer_get_meta_video_crop (xvimage);
|
||||||
GstVideoRectangle src, dst;
|
|
||||||
|
|
||||||
/* We use the calculated geometry from _setcaps as a source to respect
|
if (crop) {
|
||||||
source and screen pixel aspect ratios. */
|
src.x = crop->x;
|
||||||
src.w = GST_VIDEO_SINK_WIDTH (xvimagesink);
|
src.y = crop->y;
|
||||||
src.h = GST_VIDEO_SINK_HEIGHT (xvimagesink);
|
src.w = crop->width;
|
||||||
|
src.h = crop->height;
|
||||||
|
} else {
|
||||||
|
src.x = 0;
|
||||||
|
src.y = 0;
|
||||||
|
src.w = meta->width;
|
||||||
|
src.h = meta->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xvimagesink->keep_aspect) {
|
||||||
dst.w = xvimagesink->render_rect.w;
|
dst.w = xvimagesink->render_rect.w;
|
||||||
dst.h = xvimagesink->render_rect.h;
|
dst.h = xvimagesink->render_rect.h;
|
||||||
|
|
||||||
|
@ -347,8 +357,7 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
||||||
xvimagesink->xcontext->xv_port_id,
|
xvimagesink->xcontext->xv_port_id,
|
||||||
xvimagesink->xwindow->win,
|
xvimagesink->xwindow->win,
|
||||||
xvimagesink->xwindow->gc, meta->xvimage,
|
xvimagesink->xwindow->gc, meta->xvimage,
|
||||||
xvimagesink->disp_x, xvimagesink->disp_y,
|
src.x, src.y, src.w, src.h,
|
||||||
xvimagesink->disp_width, xvimagesink->disp_height,
|
|
||||||
result.x, result.y, result.w, result.h, FALSE);
|
result.x, result.y, result.w, result.h, FALSE);
|
||||||
} else
|
} else
|
||||||
#endif /* HAVE_XSHM */
|
#endif /* HAVE_XSHM */
|
||||||
|
@ -357,9 +366,7 @@ gst_xvimagesink_xvimage_put (GstXvImageSink * xvimagesink, GstBuffer * xvimage)
|
||||||
xvimagesink->xcontext->xv_port_id,
|
xvimagesink->xcontext->xv_port_id,
|
||||||
xvimagesink->xwindow->win,
|
xvimagesink->xwindow->win,
|
||||||
xvimagesink->xwindow->gc, meta->xvimage,
|
xvimagesink->xwindow->gc, meta->xvimage,
|
||||||
xvimagesink->disp_x, xvimagesink->disp_y,
|
src.x, src.y, src.w, src.h, result.x, result.y, result.w, result.h);
|
||||||
xvimagesink->disp_width, xvimagesink->disp_height,
|
|
||||||
result.x, result.y, result.w, result.h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XSync (xvimagesink->xcontext->disp, FALSE);
|
XSync (xvimagesink->xcontext->disp, FALSE);
|
||||||
|
@ -1535,11 +1542,8 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
GstBufferPool *newpool, *oldpool;
|
GstBufferPool *newpool, *oldpool;
|
||||||
GstVideoInfo info;
|
GstVideoInfo info;
|
||||||
guint32 im_format = 0;
|
guint32 im_format = 0;
|
||||||
gint disp_x, disp_y;
|
|
||||||
gint disp_width, disp_height;
|
|
||||||
gint video_par_n, video_par_d; /* video's PAR */
|
gint video_par_n, video_par_d; /* video's PAR */
|
||||||
gint display_par_n, display_par_d; /* display's PAR */
|
gint display_par_n, display_par_d; /* display's PAR */
|
||||||
const GValue *caps_disp_reg;
|
|
||||||
guint num, den;
|
guint num, den;
|
||||||
gint size;
|
gint size;
|
||||||
|
|
||||||
|
@ -1586,29 +1590,10 @@ gst_xvimagesink_setcaps (GstBaseSink * bsink, GstCaps * caps)
|
||||||
display_par_d = 1;
|
display_par_d = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the display region */
|
|
||||||
caps_disp_reg = gst_structure_get_value (structure, "display-region");
|
|
||||||
if (caps_disp_reg) {
|
|
||||||
disp_x = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 0));
|
|
||||||
disp_y = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 1));
|
|
||||||
disp_width = g_value_get_int (gst_value_array_get_value (caps_disp_reg, 2));
|
|
||||||
disp_height =
|
|
||||||
g_value_get_int (gst_value_array_get_value (caps_disp_reg, 3));
|
|
||||||
} else {
|
|
||||||
disp_x = disp_y = 0;
|
|
||||||
disp_width = info.width;
|
|
||||||
disp_height = info.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_video_calculate_display_ratio (&num, &den, info.width,
|
if (!gst_video_calculate_display_ratio (&num, &den, info.width,
|
||||||
info.height, video_par_n, video_par_d, display_par_n, display_par_d))
|
info.height, video_par_n, video_par_d, display_par_n, display_par_d))
|
||||||
goto no_disp_ratio;
|
goto no_disp_ratio;
|
||||||
|
|
||||||
xvimagesink->disp_x = disp_x;
|
|
||||||
xvimagesink->disp_y = disp_y;
|
|
||||||
xvimagesink->disp_width = disp_width;
|
|
||||||
xvimagesink->disp_height = disp_height;
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (xvimagesink,
|
GST_DEBUG_OBJECT (xvimagesink,
|
||||||
"video width/height: %dx%d, calculated display ratio: %d/%d",
|
"video width/height: %dx%d, calculated display ratio: %d/%d",
|
||||||
info.width, info.height, num, den);
|
info.width, info.height, num, den);
|
||||||
|
|
|
@ -247,10 +247,6 @@ struct _GstXvImageSink
|
||||||
/* size of incoming video, used as the size for XvImage */
|
/* size of incoming video, used as the size for XvImage */
|
||||||
guint video_width, video_height;
|
guint video_width, video_height;
|
||||||
|
|
||||||
/* display sizes, used for clipping the image */
|
|
||||||
gint disp_x, disp_y;
|
|
||||||
gint disp_width, disp_height;
|
|
||||||
|
|
||||||
/* port attributes */
|
/* port attributes */
|
||||||
gboolean autopaint_colorkey;
|
gboolean autopaint_colorkey;
|
||||||
gint colorkey;
|
gint colorkey;
|
||||||
|
|
Loading…
Reference in a new issue