summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorLasse Laukkanen <ext-lasse.2.laukkanen@nokia.com>2009-03-09 18:00:45 +0200
committerStefan Kost <ensonic@users.sf.net>2009-06-05 15:51:30 +0300
commit53e6e4b0d5b7e17ac8b1a2d96d39ad38dc41bad7 (patch)
tree30068d84f96ef27ccfaabf0eb16d29baeef1bc72 /gst
parent2d4469c9846c6bf4e57763b051dfaf3fed8d346b (diff)
downloadgst-plugins-bad-53e6e4b0d5b7e17ac8b1a2d96d39ad38dc41bad7.tar.gz
gst-plugins-bad-53e6e4b0d5b7e17ac8b1a2d96d39ad38dc41bad7.tar.bz2
gst-plugins-bad-53e6e4b0d5b7e17ac8b1a2d96d39ad38dc41bad7.zip
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.
Diffstat (limited to 'gst')
-rw-r--r--gst/camerabin/gstcamerabin.c62
1 files changed, 56 insertions, 6 deletions
diff --git a/gst/camerabin/gstcamerabin.c b/gst/camerabin/gstcamerabin.c
index 2ddb34e0..17ca9def 100644
--- a/gst/camerabin/gstcamerabin.c
+++ b/gst/camerabin/gstcamerabin.c
@@ -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);
}