rpicamsrc: add test-color-balance example
authorPhilippe Normand <philn@igalia.com>
Tue, 5 May 2015 17:03:43 +0000 (19:03 +0200)
committerTim-Philipp Müller <tim@centricular.com>
Fri, 10 Jul 2020 15:45:02 +0000 (16:45 +0100)
This small test will display a live video preview of the rpicam with
the balance controls being updated once a second. The controls to
update can be disabled in the source by setting the CONTROL_* macros
values to 0.

tests/examples/rpicamsrc/test_color_balance.c [new file with mode: 0644]

diff --git a/tests/examples/rpicamsrc/test_color_balance.c b/tests/examples/rpicamsrc/test_color_balance.c
new file mode 100644 (file)
index 0000000..b5bac08
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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/colorbalance.h>
+
+#define CONTROL_SATURATION 1
+#define CONTROL_BRIGHTNESS 1
+#define CONTROL_CONTRAST 1
+
+#define PIPELINE "rpicamsrc name=src preview=0 fullscreen=0 ! h264parse ! omxh264dec ! glimagesink sync=0"
+
+#define declare_value(name, value)      \
+    static gint current_##name = value; \
+    static gboolean incrementing_##name = TRUE;
+
+#if CONTROL_SATURATION
+declare_value(SATURATION, 50);
+#endif
+#if CONTROL_BRIGHTNESS
+declare_value(BRIGHTNESS, 50);
+#endif
+#if CONTROL_CONTRAST
+declare_value(CONTRAST, 0);
+#endif
+
+#define update(name, channel, current_value)              \
+    if (!g_strcmp0(channel->label, #name)) {              \
+        if (current_value >= channel->max_value)          \
+            incrementing_##name = FALSE;                  \
+        else if (current_value <= channel->min_value)     \
+            incrementing_##name = TRUE;                   \
+        current_##name += incrementing_##name ? 10 : -10; \
+        g_print("new " #name ": %d\n", current_##name);   \
+        return current_##name;                            \
+    }
+
+gint compute_value(GstColorBalanceChannel* channel, gint current_value)
+{
+#if CONTROL_SATURATION
+    update(SATURATION, channel, current_value);
+#endif
+#if CONTROL_BRIGHTNESS
+    update(BRIGHTNESS, channel, current_value);
+#endif
+#if CONTROL_CONTRAST
+    update(CONTRAST, channel, current_value);
+#endif
+    return current_value;
+}
+
+static gboolean process(gpointer data)
+{
+    GstColorBalance* balance = (GstColorBalance*) data;
+    const GList* controls;
+    GstColorBalanceChannel* channel;
+    const GList* item;
+    gint index, new_value, current_value;
+
+    controls = gst_color_balance_list_channels(balance);
+
+    if (controls == NULL) {
+        g_printerr("There is no list of colorbalance controls\n");
+        return G_SOURCE_REMOVE;
+    }
+
+    for (item = controls, index = 0; item != NULL;
+         item = item->next, ++index) {
+        channel = item->data;
+        current_value = gst_color_balance_get_value(balance, channel);
+        new_value = compute_value(channel, current_value);
+        gst_color_balance_set_value(balance, channel, new_value);
+    }
+
+    return G_SOURCE_CONTINUE;
+}
+
+int main(int argc, char** argv)
+{
+    GMainLoop* loop;
+    GstElement* pipeline;
+    GError* error = NULL;
+    GstElement* src;
+    GstColorBalance* balance;
+
+    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;
+    }
+
+    balance = GST_COLOR_BALANCE(src);
+    g_timeout_add_seconds(1, process, balance);
+    g_main_loop_run(loop);
+
+    gst_object_unref(src);
+    gst_element_set_state(pipeline, GST_STATE_NULL);
+    return 0;
+}