[clutter-gst] Add new camera-player example for camera playback.
- From: Lionel Landwerlin <llandwerlin src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter-gst] Add new camera-player example for camera playback.
- Date: Mon, 18 Mar 2013 23:35:54 +0000 (UTC)
commit 9be5b9cccf02bfe813d8b29baf0ec768a96297be
Author: Andre Moreira Magalhaes (andrunko) <andre magalhaes collabora co uk>
Date: Wed Aug 15 15:36:52 2012 -0300
Add new camera-player example for camera playback.
examples/Makefile.am | 9 +-
examples/camera-player.c | 478 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 486 insertions(+), 1 deletions(-)
---
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 4cd466b..6d60512 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,11 +1,18 @@
NULL = #
-noinst_PROGRAMS = video-player video-sink video-sink-navigation
+noinst_PROGRAMS = camera-player video-player video-sink video-sink-navigation
INCLUDES = -I$(top_srcdir) \
$(MAINTAINER_CFLAGS) \
$(NULL)
+camera_player_SOURCES = camera-player.c
+camera_player_CFLAGS = $(CLUTTER_GST_CFLAGS) $(GST_CFLAGS)
+camera_player_LDFLAGS = \
+ $(CLUTTER_GST_LIBS) \
+ $(GST_LIBS) \
+ $(top_builddir)/clutter-gst/libclutter-gst- CLUTTER_GST_MAJORMINOR@.la
+
video_player_SOURCES = video-player.c
video_player_CFLAGS = $(CLUTTER_GST_CFLAGS) $(GST_CFLAGS)
video_player_LDFLAGS = \
diff --git a/examples/camera-player.c b/examples/camera-player.c
new file mode 100644
index 0000000..cc764e7
--- /dev/null
+++ b/examples/camera-player.c
@@ -0,0 +1,478 @@
+/*
+ * Clutter-GStreamer.
+ *
+ * GStreamer integration library for Clutter.
+ *
+ * camera-player.c - A simple camera player.
+ *
+ * Copyright (C) 2007,2008 OpenedHand
+ * Copyright (C) 2012 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+
+#include <clutter/clutter.h>
+#include <clutter-gst/clutter-gst.h>
+
+typedef struct _CameraApp
+{
+ ClutterActor *stage;
+ ClutterActor *camera_actor;
+ const GPtrArray *camera_devices;
+ guint selected_camera_device;
+ gboolean decrease_selected;
+} CameraApp;
+
+static gboolean opt_fullscreen = FALSE;
+
+static GOptionEntry options[] =
+{
+ { "fullscreen",
+ 'f', 0,
+ G_OPTION_ARG_NONE,
+ &opt_fullscreen,
+ "Start the player in fullscreen",
+ NULL },
+
+ { NULL }
+};
+
+static void
+reset_animation (ClutterAnimation *animation,
+ CameraApp *app)
+{
+ if (app->camera_actor)
+ clutter_actor_set_rotation (app->camera_actor, CLUTTER_Y_AXIS, 0.0, 0, 0, 0);
+}
+
+static void
+update_gamma (CameraApp *app)
+{
+ gdouble min, max, cur;
+
+ if (!clutter_gst_camera_actor_supports_gamma_correction (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor)))
+ {
+ g_print ("Cannot update gamma, not supported\n");
+ return;
+ }
+
+ if (!clutter_gst_camera_actor_get_gamma_range (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ &min, &max, NULL))
+ {
+ g_print ("Cannot update gamma, unable to get allowed range\n");
+ return;
+ }
+
+ if (!clutter_gst_camera_actor_get_gamma (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ &cur))
+ {
+ g_print ("Cannot update gamma, unable to get current value\n");
+ return;
+ }
+
+ g_print ("Updating gamma:\n");
+ g_print ("\tmin value: %0.2f\n", min);
+ g_print ("\tmax value: %0.2f\n", max);
+ g_print ("\tcur value: %0.2f\n", cur);
+ if (app->decrease_selected)
+ {
+ cur -= 0.1;
+ if (cur < min)
+ cur = min;
+ }
+ else
+ {
+ cur += 0.1;
+ if (cur > max)
+ cur = max;
+ }
+
+ g_print ("\tnew value: %0.2f\n", cur);
+ clutter_gst_camera_actor_set_gamma (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ cur);
+}
+
+static void
+update_color_balance (CameraApp *app,
+ const gchar *property)
+{
+ gdouble min, max, cur;
+
+ if (!clutter_gst_camera_actor_supports_color_balance (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor)))
+ {
+ g_print ("Cannot update color balance property %s, "
+ "not supported\n",
+ property);
+ return;
+ }
+
+ if (!clutter_gst_camera_actor_get_color_balance_property_range (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ property, &min, &max, NULL))
+ {
+ g_print ("Cannot update color balance property %s, "
+ "unable to get allowed range\n",
+ property);
+ return;
+ }
+
+ if (!clutter_gst_camera_actor_get_color_balance_property (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ property, &cur))
+ {
+ g_print ("Cannot update color balance property %s, "
+ "unable to get current value\n",
+ property);
+ return;
+ }
+
+ g_print ("Updating color balance property %s:\n", property);
+ g_print ("\tmin value: %0.2f\n", min);
+ g_print ("\tmax value: %0.2f\n", max);
+ g_print ("\tcur value: %0.2f\n", cur);
+ if (app->decrease_selected)
+ {
+ cur -= 0.1;
+ if (cur < min)
+ cur = min;
+ }
+ else
+ {
+ cur += 0.1;
+ if (cur > max)
+ cur = max;
+ }
+
+ g_print ("\tnew value: %0.2f\n", cur);
+ clutter_gst_camera_actor_set_color_balance_property (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ property, cur);
+}
+
+static gboolean
+input_cb (ClutterStage *stage,
+ ClutterEvent *event,
+ gpointer user_data)
+{
+ CameraApp *app = (CameraApp*)user_data;
+ gboolean handled = FALSE;
+
+ switch (event->type)
+ {
+ case CLUTTER_KEY_PRESS:
+ {
+ ClutterVertex center = { 0, };
+ ClutterAnimation *animation = NULL;
+
+ switch (clutter_event_get_key_symbol (event))
+ {
+ case CLUTTER_minus:
+ app->decrease_selected = TRUE;
+ break;
+ case CLUTTER_plus:
+ app->decrease_selected = FALSE;
+ break;
+ case CLUTTER_b:
+ update_color_balance (app, "brightness");
+ break;
+ case CLUTTER_c:
+ update_color_balance (app, "contrast");
+ break;
+ case CLUTTER_s:
+ update_color_balance (app, "saturation");
+ break;
+ case CLUTTER_h:
+ update_color_balance (app, "hue");
+ break;
+ case CLUTTER_g:
+ update_gamma (app);
+ break;
+
+ case CLUTTER_d:
+ {
+ ClutterGstCameraDevice *device;
+
+ if (app->camera_devices->len == 1)
+ break;
+
+ app->selected_camera_device++;
+ if (app->selected_camera_device >= app->camera_devices->len)
+ app->selected_camera_device = 0;
+ device = g_ptr_array_index (app->camera_devices, app->selected_camera_device);
+ g_print ("Selecting device %s (node=%s)\n",
+ clutter_gst_camera_device_get_name (device),
+ clutter_gst_camera_device_get_node (device));
+ clutter_gst_camera_actor_set_camera_device (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor), device);
+ break;
+ }
+
+ case CLUTTER_q:
+ case CLUTTER_Escape:
+ clutter_main_quit ();
+ break;
+
+ case CLUTTER_v:
+ {
+ gchar *filename;
+ static guint photos_cnt = 0;
+
+ if (clutter_gst_camera_actor_is_recording_video (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor)))
+ {
+ g_print ("Stopping video recording\n");
+
+ clutter_gst_camera_actor_stop_video_recording (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor));
+ }
+ else if (!clutter_gst_camera_actor_is_ready_for_capture (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor)))
+ g_print ("Unable to record video as the camera is not ready for capture\n");
+ else
+ {
+ g_print ("Recording video!\n");
+
+ filename = g_strdup_printf ("camera-video-%d.ogv", photos_cnt++);
+
+ clutter_gst_camera_actor_start_video_recording (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ filename);
+ g_free (filename);
+ }
+ break;
+ }
+
+ case CLUTTER_p:
+ {
+ gchar *filename;
+ static guint photos_cnt = 0;
+
+ if (clutter_gst_camera_actor_is_recording_video (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor)))
+ g_print ("Unable to take photo as the camera is recording video\n");
+ else if (!clutter_gst_camera_actor_is_ready_for_capture (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor)))
+ g_print ("Unable to take photo as the camera is not ready for capture\n");
+ else
+ {
+ g_print ("Taking picture!\n");
+
+ filename = g_strdup_printf ("camera-photo-%d.jpg", photos_cnt++);
+
+ clutter_gst_camera_actor_take_photo (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor),
+ filename);
+ g_free (filename);
+ }
+ break;
+ }
+
+ case CLUTTER_e:
+ {
+ GstElement *filter;
+ gboolean ret;
+
+ filter = gst_element_factory_make ("dicetv", NULL);
+ if (!filter)
+ {
+ g_print ("ERROR: Unable to create 'dicetv' element, cannot set filter\n");
+ }
+ ret = clutter_gst_camera_actor_set_filter (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor), filter);
+ if (ret)
+ g_print ("Filter set successfully\n");
+ else
+ g_print ("ERROR: Unable to set filter\n");
+
+ break;
+ }
+
+ case CLUTTER_r:
+ clutter_gst_camera_actor_remove_filter (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor));
+ break;
+
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+
+ return handled;
+}
+
+static void
+ready_for_capture (ClutterGstCameraActor *camera_actor,
+ gboolean ready)
+{
+ if (ready)
+ g_print ("Ready for capture!\n");
+}
+
+static void
+photo_saved (ClutterGstCameraActor *camera_actor)
+{
+ g_print ("Photo saved!\n");
+}
+
+static void
+video_saved (ClutterGstCameraActor *camera_actor)
+{
+ g_print ("Video saved!\n");
+}
+
+static void
+size_change (ClutterGstActor *texture,
+ gint base_width,
+ gint base_height,
+ CameraApp *app)
+{
+ ClutterActor *stage = app->stage;
+ gfloat new_x, new_y, new_width, new_height;
+ gfloat stage_width, stage_height;
+ gfloat frame_width, frame_height;
+
+ clutter_actor_get_size (stage, &stage_width, &stage_height);
+
+ /* base_width and base_height are the actual dimensions of the buffers before
+ * taking the pixel aspect ratio into account. We need to get the actual
+ * size of the texture to display */
+ clutter_actor_get_size (CLUTTER_ACTOR (texture), &frame_width, &frame_height);
+
+ new_height = (frame_height * stage_width) / frame_width;
+ if (new_height <= stage_height)
+ {
+ new_width = stage_width;
+
+ new_x = 0;
+ new_y = (stage_height - new_height) / 2;
+ }
+ else
+ {
+ new_width = (frame_width * stage_height) / frame_height;
+ new_height = stage_height;
+
+ new_x = (stage_width - new_width) / 2;
+ new_y = 0;
+ }
+
+ clutter_actor_set_position (CLUTTER_ACTOR (texture), new_x, new_y);
+ clutter_actor_set_size (CLUTTER_ACTOR (texture), new_width, new_height);
+}
+
+int
+main (int argc, char *argv[])
+{
+ CameraApp *app = NULL;
+ ClutterActor *stage;
+ ClutterColor stage_color = { 0x00, 0x00, 0x00, 0x00 };
+ GError *error = NULL;
+ guint i;
+
+ clutter_gst_init_with_args (&argc,
+ &argv,
+ " - A simple camera player",
+ options,
+ NULL,
+ &error);
+
+ if (error)
+ {
+ g_print ("%s\n", error->message);
+ g_error_free (error);
+ return EXIT_FAILURE;
+ }
+
+ stage = clutter_stage_get_default ();
+ clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
+ clutter_actor_set_size (stage, 768, 576);
+ clutter_stage_set_minimum_size (CLUTTER_STAGE (stage), 640, 480);
+ if (opt_fullscreen)
+ clutter_stage_set_fullscreen (CLUTTER_STAGE (stage), TRUE);
+
+ app = g_new0(CameraApp, 1);
+ app->stage = stage;
+ app->camera_actor = clutter_gst_camera_actor_new ();
+
+ if (app->camera_actor == NULL)
+ {
+ g_error ("failed to create camera_actor");
+ return EXIT_FAILURE;
+ }
+
+ app->camera_devices = clutter_gst_camera_actor_get_camera_devices (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor));
+ if (!app->camera_devices)
+ {
+ g_error ("no suitable camera device available");
+ return EXIT_FAILURE;
+ }
+ g_print ("Available camera devices:\n");
+ for (i = 0; i < app->camera_devices->len; ++i)
+ {
+ ClutterGstCameraDevice *device;
+
+ device = g_ptr_array_index (app->camera_devices, i);
+ g_print ("\tdevice %s (node=%s)\n",
+ clutter_gst_camera_device_get_name (device),
+ clutter_gst_camera_device_get_node (device));
+
+ clutter_gst_camera_device_set_capture_resolution (device, 800, 600);
+ }
+ app->selected_camera_device = 0;
+
+ g_signal_connect (app->camera_actor, "ready-for-capture",
+ G_CALLBACK (ready_for_capture),
+ app);
+ g_signal_connect (app->camera_actor, "photo-saved",
+ G_CALLBACK (photo_saved),
+ app);
+ g_signal_connect (app->camera_actor, "video-saved",
+ G_CALLBACK (video_saved),
+ app);
+ /* Handle it ourselves so can scale up for fullscreen better */
+ g_signal_connect_after (app->camera_actor,
+ "size-change",
+ G_CALLBACK (size_change), app);
+
+ /* Add control UI to stage */
+ clutter_container_add (CLUTTER_CONTAINER (stage),
+ app->camera_actor,
+ NULL);
+
+ clutter_stage_hide_cursor (CLUTTER_STAGE (stage));
+
+ /* Hook up other events */
+ g_signal_connect (stage, "event", G_CALLBACK (input_cb), app);
+
+ clutter_gst_camera_actor_set_playing (
+ CLUTTER_GST_CAMERA_ACTOR (app->camera_actor), TRUE);
+
+ clutter_actor_show (stage);
+
+ clutter_main ();
+
+ return EXIT_SUCCESS;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]