rpicamsrc: Basic orientation interface support
authorPhilippe Normand <philn@igalia.com>
Mon, 11 May 2015 09:16:52 +0000 (11:16 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Fri, 10 Jul 2020 15:45:13 +0000 (16:45 +0100)
The (h,v)flip attributes are now supported through this interface.
It should also be possible to support (h,v)center attributes using the
ROI properties.

sys/rpicamsrc/gstrpicamsrc.c
tests/examples/rpicamsrc/test_orientation.c [new file with mode: 0644]

index 0e831e5..8272188 100644 (file)
@@ -188,6 +188,7 @@ static void gst_rpi_cam_src_finalize (GObject *object);
 
 static void gst_rpi_cam_src_colorbalance_init (GstColorBalanceInterface *
     iface);
+static void gst_rpi_cam_src_orientation_init (GstVideoOrientationInterface * iface);
 
 static void gst_rpi_cam_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
@@ -210,7 +211,9 @@ static gboolean gst_rpi_cam_src_send_event (GstElement * element,
 G_DEFINE_TYPE_WITH_CODE (GstRpiCamSrc, gst_rpi_cam_src,
     GST_TYPE_PUSH_SRC,
     G_IMPLEMENT_INTERFACE (GST_TYPE_COLOR_BALANCE,
-        gst_rpi_cam_src_colorbalance_init));
+        gst_rpi_cam_src_colorbalance_init);
+    G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_ORIENTATION,
+        gst_rpi_cam_src_orientation_init));
 
 #define C_ENUM(v) ((gint) v)
 
@@ -583,6 +586,79 @@ gst_rpi_cam_src_colorbalance_init (GstColorBalanceInterface * iface)
   iface->get_balance_type = gst_rpi_cam_src_colorbalance_get_balance_type;
 }
 
+static gboolean
+gst_rpi_cam_src_orientation_get_hflip (GstVideoOrientation * orientation, gboolean * flip)
+{
+  GstRpiCamSrc *src = GST_RPICAMSRC (orientation);
+
+  g_return_val_if_fail (src != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_RPICAMSRC (src), FALSE);
+
+  g_mutex_lock (&src->config_lock);
+  *flip = src->capture_config.camera_parameters.hflip;
+  g_mutex_unlock (&src->config_lock);
+
+  return TRUE;
+}
+
+static gboolean
+gst_rpi_cam_src_orientation_get_vflip (GstVideoOrientation * orientation, gboolean * flip)
+{
+  GstRpiCamSrc *src = GST_RPICAMSRC (orientation);
+
+  g_return_val_if_fail (src != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_RPICAMSRC (src), FALSE);
+
+  g_mutex_lock (&src->config_lock);
+  *flip = src->capture_config.camera_parameters.vflip;
+  g_mutex_unlock (&src->config_lock);
+
+  return TRUE;
+}
+
+static gboolean
+gst_rpi_cam_src_orientation_set_hflip (GstVideoOrientation * orientation, gboolean flip)
+{
+  GstRpiCamSrc *src = GST_RPICAMSRC (orientation);
+
+  g_return_val_if_fail (src != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_RPICAMSRC (src), FALSE);
+
+  g_mutex_lock (&src->config_lock);
+  src->capture_config.camera_parameters.hflip = flip;
+  src->capture_config.change_flags |= PROP_CHANGE_ORIENTATION;
+  g_mutex_unlock (&src->config_lock);
+
+  return TRUE;
+}
+
+static gboolean
+gst_rpi_cam_src_orientation_set_vflip (GstVideoOrientation * orientation, gboolean flip)
+{
+  GstRpiCamSrc *src = GST_RPICAMSRC (orientation);
+
+  g_return_val_if_fail (src != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_RPICAMSRC (src), FALSE);
+
+  g_mutex_lock (&src->config_lock);
+  src->capture_config.camera_parameters.vflip = flip;
+  src->capture_config.change_flags |= PROP_CHANGE_ORIENTATION;
+  g_mutex_unlock (&src->config_lock);
+
+  return TRUE;
+}
+
+static void
+gst_rpi_cam_src_orientation_init (GstVideoOrientationInterface * iface)
+{
+  iface->get_hflip = gst_rpi_cam_src_orientation_get_hflip;
+  iface->set_hflip = gst_rpi_cam_src_orientation_set_hflip;
+  iface->get_vflip = gst_rpi_cam_src_orientation_get_vflip;
+  iface->set_vflip = gst_rpi_cam_src_orientation_set_vflip;
+
+  /* TODO: hcenter / vcenter support */
+}
+
 static void
 gst_rpi_cam_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
diff --git a/tests/examples/rpicamsrc/test_orientation.c b/tests/examples/rpicamsrc/test_orientation.c
new file mode 100644 (file)
index 0000000..7702537
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2015, Igalia S.L
+ *     Author: Philippe Normand <philn@igalia.com>
+ * Licence: LGPL. (See COPYING.LGPL)
+ */
+
+#include <glib.h>
+#include <gst/gst.h>
+#include <gst/video/videoorientation.h>
+
+#define PIPELINE "rpicamsrc name=src preview=0 fullscreen=0 ! h264parse ! omxh264dec ! glimagesink sync=0"
+
+void configure_orientation(GstVideoOrientation* orientation)
+{
+    gboolean flip;
+
+    if (gst_video_orientation_get_hflip(orientation, &flip)) {
+        g_print("current hflip: %s\n", flip ? "enabled" : "disabled");
+
+        if (g_getenv("HFLIP"))
+            gst_video_orientation_set_hflip(orientation, TRUE);
+
+        gst_video_orientation_get_hflip(orientation, &flip);
+        g_print("new hflip: %s\n", flip ? "enabled" : "disabled");
+    }
+
+    if (gst_video_orientation_get_vflip(orientation, &flip)) {
+        g_print("current vflip: %s\n", flip ? "enabled" : "disabled");
+
+        if (g_getenv("VFLIP"))
+            gst_video_orientation_set_vflip(orientation, TRUE);
+
+        gst_video_orientation_get_vflip(orientation, &flip);
+        g_print("new vflip: %s\n", flip ? "enabled" : "disabled");
+    }
+}
+
+int main(int argc, char** argv)
+{
+    GMainLoop* loop;
+    GstElement* pipeline;
+    GError* error = NULL;
+    GstElement* src;
+    GstVideoOrientation* orientation;
+
+    gst_init(&argc, &argv);
+    loop = g_main_loop_new(NULL, FALSE);
+
+    pipeline = gst_parse_launch(PIPELINE, &error);
+    if (error != NULL) {
+        g_printerr("Error parsing '%s': %s", PIPELINE, error->message);
+        g_error_free(error);
+        return -1;
+    }
+
+    gst_element_set_state(pipeline, GST_STATE_PLAYING);
+    src = gst_bin_get_by_name(GST_BIN(pipeline), "src");
+    if (!src) {
+        g_printerr("Source element not found\n");
+        return -2;
+    }
+
+    orientation = GST_VIDEO_ORIENTATION(src);
+    configure_orientation(orientation);
+    g_main_loop_run(loop);
+
+    gst_object_unref(src);
+    gst_element_set_state(pipeline, GST_STATE_NULL);
+    return 0;
+}