mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-28 04:31:06 +00:00
camerabin: crop still image capture frame if necessary
If incoming still image capture frame aspect ratio differs from aspect ratio that application requested, then apply crop to the frame.
This commit is contained in:
parent
2d4469c984
commit
53e6e4b0d5
1 changed files with 56 additions and 6 deletions
|
@ -1313,18 +1313,36 @@ gst_camerabin_set_capsfilter_caps (GstCameraBin * camera, GstCaps * new_caps)
|
|||
gst_camerabin_update_aspect_filter (camera, new_caps);
|
||||
}
|
||||
|
||||
/*
|
||||
* gst_camerabin_adapt_video_resolution:
|
||||
* @camera: camerabin object
|
||||
* @caps: caps describing the next incoming buffer format
|
||||
*
|
||||
* This function adjusts capsfilter and crop elements in order to modify
|
||||
* the incoming buffer to the resolution that application requested.
|
||||
*
|
||||
*/
|
||||
static void
|
||||
gst_camerabin_adapt_video_resolution (GstCameraBin * camera, GstCaps * caps)
|
||||
{
|
||||
GstStructure *st;
|
||||
gint width = 0, height = 0;
|
||||
GstCaps *filter_caps = NULL;
|
||||
gint top, bottom, left, right, crop;
|
||||
gdouble ratio_w, ratio_h;
|
||||
|
||||
g_return_if_fail (camera->width != 0 && camera->height != 0);
|
||||
|
||||
/* Get width and height from caps */
|
||||
st = gst_caps_get_structure (caps, 0);
|
||||
gst_structure_get_int (st, "width", &width);
|
||||
gst_structure_get_int (st, "height", &height);
|
||||
|
||||
if (width == camera->width && height == camera->height) {
|
||||
GST_DEBUG_OBJECT (camera, "no adaptation with resolution needed");
|
||||
return;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (camera,
|
||||
"changing %dx%d -> %dx%d filter to %" GST_PTR_FORMAT,
|
||||
camera->width, camera->height, width, height, camera->src_filter);
|
||||
|
@ -1336,7 +1354,31 @@ gst_camerabin_adapt_video_resolution (GstCameraBin * camera, GstCaps * caps)
|
|||
"height", G_TYPE_INT, height, NULL);
|
||||
g_object_set (G_OBJECT (camera->src_filter), "caps", filter_caps, NULL);
|
||||
gst_caps_unref (filter_caps);
|
||||
/* FIXME: implement cropping according to requested aspect ratio */
|
||||
|
||||
/* Crop if requested aspect ratio differs from incoming frame aspect ratio */
|
||||
|
||||
/* Don't override original crop values in case we have zoom applied */
|
||||
g_object_get (G_OBJECT (camera->src_zoom_crop), "top", &top, "bottom",
|
||||
&bottom, "left", &left, "right", &right, NULL);
|
||||
|
||||
ratio_w = (gdouble) width / camera->width;
|
||||
ratio_h = (gdouble) height / camera->height;
|
||||
|
||||
if (ratio_w < ratio_h) {
|
||||
crop = height - (camera->height * ratio_w);
|
||||
top += crop / 2;
|
||||
bottom += crop / 2;
|
||||
} else {
|
||||
crop = width - (camera->width * ratio_h);
|
||||
left += crop / 2;
|
||||
right += crop / 2;
|
||||
}
|
||||
|
||||
GST_INFO_OBJECT (camera,
|
||||
"updating crop: left:%d, right:%d, top:%d, bottom:%d", left, right, top,
|
||||
bottom);
|
||||
g_object_set (G_OBJECT (camera->src_zoom_crop), "top", top, "bottom", bottom,
|
||||
"left", left, "right", right, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1353,11 +1395,13 @@ img_capture_prepared (gpointer data, GstCaps * caps)
|
|||
GstStructure *st, *new_st;
|
||||
gint i;
|
||||
const gchar *field_name;
|
||||
gboolean adapt = FALSE;
|
||||
|
||||
GST_INFO_OBJECT (camera, "image capture prepared");
|
||||
|
||||
/* It is possible we are about to get something else that we requested */
|
||||
if (!gst_caps_is_equal (camera->image_capture_caps, caps)) {
|
||||
adapt = TRUE;
|
||||
/* If capture preparation has added new fields to requested caps,
|
||||
we need to copy them */
|
||||
st = gst_caps_get_structure (camera->image_capture_caps, 0);
|
||||
|
@ -1378,10 +1422,11 @@ img_capture_prepared (gpointer data, GstCaps * caps)
|
|||
/* Update capsfilters */
|
||||
gst_camerabin_set_capsfilter_caps (camera, camera->image_capture_caps);
|
||||
|
||||
/* If incoming buffer resolution is different from what application
|
||||
requested, then we need to fix this in camerabin */
|
||||
gst_camerabin_adapt_video_resolution (camera, caps);
|
||||
|
||||
if (adapt) {
|
||||
/* If incoming buffer resolution is different from what application
|
||||
requested, then we can fix this in camerabin */
|
||||
gst_camerabin_adapt_video_resolution (camera, caps);
|
||||
}
|
||||
g_object_set (G_OBJECT (camera->src_out_sel), "resend-latest", FALSE,
|
||||
"active-pad", camera->pad_src_img, NULL);
|
||||
gst_camerabin_rewrite_tags (camera);
|
||||
|
@ -2756,8 +2801,13 @@ gst_camerabin_handle_message_func (GstBin * bin, GstMessage * msg)
|
|||
/* Image eos */
|
||||
GST_DEBUG_OBJECT (camera, "got image eos message");
|
||||
|
||||
/* Still image capture buffer handled, restore filter caps */
|
||||
/* HACK: v4l2camsrc changes to view finder resolution automatically
|
||||
after one captured still image */
|
||||
if (camera->image_capture_caps) {
|
||||
GST_DEBUG_OBJECT (camera, "resetting crop in camerabin");
|
||||
g_object_set (camera->src_zoom_crop, "left", 0, "right", 0,
|
||||
"top", 0, "bottom", 0, NULL);
|
||||
/* Still image capture buffer handled, restore filter caps */
|
||||
gst_camerabin_set_capsfilter_caps (camera, camera->view_finder_caps);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue