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:
Wim Taymans 2011-06-23 12:55:13 +02:00
parent 65d2d56f03
commit df94f2da81
3 changed files with 33 additions and 41 deletions

View file

@ -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);
} }

View file

@ -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);

View file

@ -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;