diff options
Diffstat (limited to 'tests/examples/camerabin/gst-camera.c')
-rw-r--r-- | tests/examples/camerabin/gst-camera.c | 1705 |
1 files changed, 0 insertions, 1705 deletions
diff --git a/tests/examples/camerabin/gst-camera.c b/tests/examples/camerabin/gst-camera.c deleted file mode 100644 index 610b32f0..00000000 --- a/tests/examples/camerabin/gst-camera.c +++ /dev/null @@ -1,1705 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2008 Nokia Corporation <multimedia@maemo.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library 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 - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library 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. - */ -/* - * This is a demo application to test the camerabin element. - * If you have question don't hesitate in contact me edgard.lima@indt.org.br - */ - -/* - * Includes - */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gst-camera.h" - -#include <gst/gst.h> -#include <gst/video/videooverlay.h> -#include <gst/video/colorbalance.h> -#include <gst/interfaces/photography.h> -#include <gtk/gtk.h> -#include <gdk/gdkx.h> -#include <gdk/gdkkeysyms.h> - -#include <string.h> - -#include <sys/time.h> -#include <time.h> -#include <glib/gstdio.h> // g_fopen() - -#if !GTK_CHECK_VERSION (2, 17, 7) -static void -gtk_widget_get_allocation (GtkWidget * w, GtkAllocation * a) -{ - *a = w->allocation; -} -#endif - -/* - * enums, typedefs and defines - */ - -#ifdef USE_MP4 -#define VID_FILE_EXT "mp4" -#else -#define VID_FILE_EXT "ogg" -#endif - -#define PREVIEW_TIME_MS (2 * 1000) -#define N_BURST_IMAGES 10 -#define UI_FILE CAMERA_APPS_UIDIR G_DIR_SEPARATOR_S "gst-camera.ui" - -/* Names of default elements */ -#define CAMERA_APP_VIDEOSRC "v4l2src" -#define CAMERA_APP_IMAGE_POSTPROC "dummy" - -#ifdef HAVE_GST_PHOTO_IFACE_H -#define EV_COMP_MAX 3.0 -#define EV_COMP_MIN -3.0 -#define EV_COMP_STEP 0.5 -#endif - -#define DEFAULT_VF_CAPS \ - "video/x-raw-yuv, width = (int) 320, height = (int) 240, framerate = (fraction) 1496/100;" \ - "video/x-raw-yuv, width = (int) 640, height = (int) 480, framerate = (fraction) 1494/100;" \ - "video/x-raw-yuv, width = (int) 800, height = (int) 480, framerate = (fraction) 2503/100;" \ - "video/x-raw-yuv, width = (int) 800, height = (int) 480, framerate = (fraction) 2988/100;" \ - "video/x-raw-yuv, width = (int) 800, height = (int) 480, framerate = (fraction) 1494/100;" \ - "video/x-raw-yuv, width = (int) 720, height = (int) 480, framerate = (fraction) 1494/100" - -#define PREVIEW_CAPS \ - "video/x-raw-rgb, width = (int) 640, height = (int) 480" - -/* states: - (image) <---> (video_stopped) <---> (video_recording) -*/ -typedef enum _tag_CaptureState -{ - CAP_STATE_IMAGE, - CAP_STATE_VIDEO_STOPED, - CAP_STATE_VIDEO_PAUSED, - CAP_STATE_VIDEO_RECORDING, -} CaptureState; - -/* - * Global Vars - */ - -static GtkBuilder *builder = NULL; -static GtkWidget *ui_main_window = NULL; -static GtkWidget *ui_drawing = NULL; -static GtkWidget *ui_drawing_frame = NULL; -static GtkWidget *ui_chk_continous = NULL; -static GtkButton *ui_bnt_shot = NULL; -static GtkButton *ui_bnt_pause = NULL; -static GtkWidget *ui_chk_mute = NULL; -static GtkWidget *ui_vbox_color_controls = NULL; -static GtkWidget *ui_chk_rawmsg = NULL; - -static GtkWidget *ui_rdbntImageCapture = NULL; -static GtkWidget *ui_rdbntVideoCapture = NULL; -static GtkWidget *ui_menuitem_photography = NULL; -static GtkWidget *ui_menuitem_capture = NULL; - -static GtkComboBox *ui_cbbox_resolution = NULL; -static guint ui_cbbox_resolution_count = 0; - -static CaptureState capture_state = CAP_STATE_IMAGE; - -static GstElement *gst_camera_bin = NULL; -static GstElement *gst_videosrc = NULL; - -static GString *filename = NULL; -static guint32 num_pics = 0; -static guint32 num_pics_cont = 0; -static guint32 num_vids = 0; - -static gint max_fr_n = 0; -static gint max_fr_d = 0; -static const gchar *video_post; -static const gchar *image_post; - -static GList *video_caps_list = NULL; - -static guint bus_handler_id = 0; - -#ifdef HAVE_GST_PHOTO_IFACE_H -static gchar *iso_speed_labels[] = { "auto", "100", "200", "400" }; - -static struct -{ - const gchar *label; - gint width; - gint height; -} image_resolution_label_map[] = { - { - "View finder resolution", 0, 0}, { - "VGA", 640, 480}, { - "1,3Mpix (1280x960)", 1280, 960}, { - "3Mpix (2048x1536)", 2048, 1536}, { - "3,7Mpix 16:9 (2592x1456)", 2592, 1456}, { - "5Mpix (2592x1968)", 2592, 1968} -}; -#endif - -/* - * functions prototypes - */ -static gboolean me_gst_setup_pipeline (const gchar * imagepost, - const gchar * videopost); -static void me_gst_cleanup_element (void); - -static gboolean capture_mode_set_state (CaptureState state); -static void capture_mode_config_gui (void); -static gboolean capture_mode_stop (void); - -static void ui_connect_signals (void); -static gboolean ui_create (void); -static void destroy_color_controls (void); -static void create_color_controls (void); -static void init_view_finder_resolution_combobox (void); - -#ifdef HAVE_GST_PHOTO_IFACE_H -static void menuitem_toggle_active (GtkWidget * widget, gpointer data); -static void sub_menu_initialize (GtkWidget * widget, gpointer data); -static void fill_photography_menu (GtkMenuItem * parent_item); -#endif - -/* - * functions implementation - */ - -static void -set_filename (GString * name) -{ - const gchar *datadir; - - if (capture_state == CAP_STATE_IMAGE) { - g_string_printf (name, G_DIR_SEPARATOR_S "test_%04u.jpg", num_pics); - datadir = g_get_user_special_dir (G_USER_DIRECTORY_PICTURES); - } else { - g_string_printf (name, G_DIR_SEPARATOR_S "test_%04u.%s", num_vids, - VID_FILE_EXT); - datadir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS); - } - - if (datadir == NULL) { - gchar *curdir = g_get_current_dir (); - g_string_prepend (name, curdir); - g_free (curdir); - } else { - g_string_prepend (name, datadir); - } - GST_INFO ("capture to %s", name->str); -} - -/* Write raw image buffer to file if found from message */ -static void -handle_element_message (GstMessage * msg) -{ - const GstStructure *st; - const GValue *image; - GstBuffer *buf = NULL; - gchar *filename = NULL; - FILE *f = NULL; - size_t written; - - st = gst_message_get_structure (msg); - if (g_str_equal (gst_structure_get_name (st), "autofocus-done")) { - gtk_button_set_label (ui_bnt_pause, "Focus"); - } else if (gst_structure_has_field_typed (st, "buffer", GST_TYPE_BUFFER)) { - image = gst_structure_get_value (st, "buffer"); - if (image) { - buf = gst_value_get_buffer (image); - if (g_str_equal (gst_structure_get_name (st), "raw-image")) { - filename = g_strdup_printf ("test_%04u.raw", num_pics); - } else if (g_str_equal (gst_structure_get_name (st), "preview-image")) { - filename = g_strdup_printf ("test_%04u_vga.rgb", num_pics); - } else { - /* for future purposes */ - g_print ("unknown buffer received\n"); - return; - } - g_print ("writing buffer to %s\n", filename); - f = g_fopen (filename, "w"); - if (f) { - GstMapInfo map; - - gst_buffer_map (buf, &map, GST_MAP_READ); - written = fwrite (map.data, map.size, 1, f); - gst_buffer_unmap (buf, &map); - if (!written) { - g_print ("errro writing file\n"); - } - fclose (f); - } else { - g_print ("error opening file for raw image writing\n"); - } - g_free (filename); - } - } else if (g_str_equal (gst_structure_get_name (st), "photo-capture-start")) { - g_print ("=== CLICK ===\n"); - } -} - -static GstBusSyncReply -my_bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data) -{ - if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT) - return GST_BUS_PASS; - - if (!gst_message_has_name (message, "prepare-xwindow-id")) - return GST_BUS_PASS; - - /* FIXME: make sure to get XID in main thread */ - gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (message->src), -#if GTK_CHECK_VERSION (2, 91, 6) - GDK_WINDOW_XID (gtk_widget_get_window (ui_drawing))); -#else - GDK_WINDOW_XWINDOW (gtk_widget_get_window (ui_drawing))); -#endif - - gst_message_unref (message); - return GST_BUS_DROP; -} - -static void -print_error_message (GstMessage * msg) -{ - GError *err = NULL; - gchar *dbg = NULL; - - gst_message_parse_error (msg, &err, &dbg); - - g_printerr ("Camerabin won't start up!\nError: %s\nDebug Info: %s\n", - err->message, (dbg) ? dbg : "None"); - - g_error_free (err); - g_free (dbg); -} - -static gboolean -my_bus_callback (GstBus * bus, GstMessage * message, gpointer data) -{ - switch (GST_MESSAGE_TYPE (message)) { - case GST_MESSAGE_WARNING:{ - GError *err; - gchar *debug; - - gst_message_parse_warning (message, &err, &debug); - g_print ("Warning: %s\n", err->message); - g_error_free (err); - g_free (debug); - break; - } - case GST_MESSAGE_ERROR:{ - print_error_message (message); - me_gst_cleanup_element (); - gtk_main_quit (); - break; - } - case GST_MESSAGE_EOS: - /* end-of-stream */ - gtk_main_quit (); - break; - case GST_MESSAGE_STATE_CHANGED:{ - GstState old, new, pending; - - gst_message_parse_state_changed (message, &old, &new, &pending); - - GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-change %s -> %s", - gst_element_state_get_name (old), gst_element_state_get_name (new)); - - /* Create/destroy color controls according videosrc state */ - if (GST_MESSAGE_SRC (message) == GST_OBJECT (gst_videosrc)) { - GST_INFO_OBJECT (GST_MESSAGE_SRC (message), "state-change %s -> %s", - gst_element_state_get_name (old), gst_element_state_get_name (new)); - - if (old == GST_STATE_READY && new == GST_STATE_NULL) { - destroy_color_controls (); - } else if (old == GST_STATE_NULL && new == GST_STATE_READY) { - create_color_controls (); - } - } - - /* we only care about pipeline state change messages */ - if (GST_IS_PIPELINE (GST_MESSAGE_SRC (message))) { - /* dump graph for pipeline state changes */ - gchar *dump_name = g_strdup_printf ("camerabin.%s_%s", - gst_element_state_get_name (old), - gst_element_state_get_name (new)); - GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (GST_MESSAGE_SRC (message)), - GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE | - GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS, dump_name); - g_free (dump_name); - } - break; - } - case GST_MESSAGE_ELEMENT: - { - handle_element_message (message); - break; - } - default: - /* unhandled message */ - break; - } - return TRUE; -} - -static void -me_set_next_cont_file_name (GString * filename) -{ - /* FIXME: better file naming (possible with signal) */ - if (G_UNLIKELY (num_pics_cont == 1)) { - gint i; - for (i = filename->len - 1; i > 0; --i) { - if (filename->str[i] == '.') - break; - } - g_string_insert (filename, i, "_0001"); - } else { - gchar tmp[6]; - gint i; - for (i = filename->len - 1; i > 0; --i) { - if (filename->str[i] == '_') - break; - } - snprintf (tmp, 6, "_%04d", num_pics_cont); - memcpy (filename->str + i, tmp, 5); - } -} - -static gboolean -stop_image_preview (gpointer data) -{ - g_return_val_if_fail (data != NULL, FALSE); - - g_signal_emit_by_name (data, "capture-stop", 0); - - return FALSE; -} - -static gboolean -me_image_capture_done (GstElement * camera, const gchar * fname, - gpointer user_data) -{ - gboolean cont = - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ui_chk_continous)); - GString *filename = g_string_new (fname); - - if (num_pics_cont < N_BURST_IMAGES && cont) { - num_pics_cont++; - me_set_next_cont_file_name (filename); - g_object_set (G_OBJECT (camera), "filename", filename->str, NULL); - g_string_free (filename, TRUE); - } else { - gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_shot), TRUE); - printf ("%u image(s) saved\n", num_pics_cont + 1); - fflush (stdout); - num_pics_cont = 0; - - g_timeout_add (PREVIEW_TIME_MS, (GSourceFunc) stop_image_preview, camera); - - cont = FALSE; - } - return cont; -} - -static gboolean -me_gst_setup_pipeline_create_post_bin (const gchar * post, gboolean video) -{ - GstElement *vpp = NULL; - GstElement *bin, *c1, *c2, *filter; - GstPad *pad; - GstCaps *caps; - - /* this function uses a bin just because it needs ffmpegcolorspace. For - * performance reason one should provide an element without need for color - * convertion */ - - vpp = gst_element_factory_make (post, NULL); - if (NULL == vpp) { - fprintf (stderr, "cannot create \'%s\' element\n", post); - fflush (stderr); - goto done; - } - c1 = gst_element_factory_make ("ffmpegcolorspace", NULL); - c2 = gst_element_factory_make ("ffmpegcolorspace", NULL); - if (NULL == c1 || NULL == c2) { - fprintf (stderr, "cannot create \'ffmpegcolorspace\' element\n"); - fflush (stderr); - goto done; - } - filter = gst_element_factory_make ("capsfilter", NULL); - if (NULL == filter) { - fprintf (stderr, "cannot create \'capsfilter\' element\n"); - fflush (stderr); - goto done; - } - bin = gst_bin_new (video ? "vid_postproc_bin" : "img_postproc_bin"); - if (NULL == bin) { - goto done; - } - - caps = gst_caps_new_simple ("video/x-raw-yuv", - "format", G_TYPE_STRING, "I420", NULL); - g_object_set (G_OBJECT (filter), "caps", caps, NULL); - gst_caps_unref (caps); - - gst_bin_add_many (GST_BIN (bin), c1, vpp, c2, filter, NULL); - if (!gst_element_link_many (c1, vpp, c2, filter, NULL)) { - fprintf (stderr, "cannot link video post proc elements\n"); - fflush (stderr); - goto done; - } - - pad = gst_element_get_static_pad (c1, "sink"); - gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad)); - gst_object_unref (GST_OBJECT (pad)); - - pad = gst_element_get_static_pad (filter, "src"); - gst_element_add_pad (bin, gst_ghost_pad_new ("src", pad)); - gst_object_unref (GST_OBJECT (pad)); - - g_object_set (gst_camera_bin, - (video ? "video-post-processing" : "image-post-processing"), bin, NULL); - return TRUE; -done: - return FALSE; -} - -static void -me_gst_setup_pipeline_create_codecs (void) -{ -#ifdef USE_MP4 - g_object_set (gst_camera_bin, "video-encoder", - gst_element_factory_make ("omx_mpeg4enc", NULL), NULL); - - g_object_set (gst_camera_bin, "audio-encoder", - gst_element_factory_make ("omx_aacenc", NULL), NULL); - - g_object_set (gst_camera_bin, "video-muxer", - gst_element_factory_make ("hantromp4mux", NULL), NULL); -#else - /* using defaults theora, vorbis, ogg */ -#endif -} - -static gboolean -me_gst_setup_pipeline_create_img_post_bin (const gchar * imagepost) -{ - return me_gst_setup_pipeline_create_post_bin (imagepost, FALSE); -} - -static gboolean -me_gst_setup_pipeline_create_vid_post_bin (const gchar * videopost) -{ - return me_gst_setup_pipeline_create_post_bin (videopost, TRUE); -} - -static gboolean -me_gst_setup_pipeline (const gchar * imagepost, const gchar * videopost) -{ - GstBus *bus; - GstCaps *preview_caps; - - set_filename (filename); - - me_gst_cleanup_element (); - - gst_camera_bin = gst_element_factory_make ("camerabin", NULL); - if (NULL == gst_camera_bin) { - goto done; - } - - g_signal_connect (gst_camera_bin, "image-done", - (GCallback) me_image_capture_done, NULL); - - preview_caps = gst_caps_from_string (PREVIEW_CAPS); - - bus = gst_pipeline_get_bus (GST_PIPELINE (gst_camera_bin)); - bus_handler_id = gst_bus_add_watch (bus, my_bus_callback, NULL); - gst_bus_set_sync_handler (bus, my_bus_sync_callback, NULL); - gst_object_unref (bus); - - /* set properties */ - g_object_set (gst_camera_bin, "filename", filename->str, NULL); - g_object_set (gst_camera_bin, "preview-caps", preview_caps, NULL); - g_object_set (gst_camera_bin, "flags", 0xdf, NULL); - gst_caps_unref (preview_caps); - - gst_videosrc = gst_element_factory_make (CAMERA_APP_VIDEOSRC, NULL); - if (gst_videosrc) { - g_object_set (G_OBJECT (gst_camera_bin), "video-source", gst_videosrc, - NULL); - } - - if (imagepost) { - if (!me_gst_setup_pipeline_create_img_post_bin (imagepost)) - goto done; - } else { - /* Use default image postprocessing element */ - GstElement *ipp = - gst_element_factory_make (CAMERA_APP_IMAGE_POSTPROC, NULL); - if (ipp) { - g_object_set (G_OBJECT (gst_camera_bin), "image-post-processing", ipp, - NULL); - } - } - - if (videopost) { - if (!me_gst_setup_pipeline_create_vid_post_bin (videopost)) - goto done; - } - - me_gst_setup_pipeline_create_codecs (); - - if (GST_STATE_CHANGE_FAILURE == - gst_element_set_state (gst_camera_bin, GST_STATE_READY)) { - goto done; - } - - if (!gst_videosrc) { - g_object_get (G_OBJECT (gst_camera_bin), "video-source", &gst_videosrc, - NULL); - } - - init_view_finder_resolution_combobox (); - - gst_element_set_state (gst_camera_bin, GST_STATE_PLAYING); - -#ifdef HAVE_GST_PHOTO_IFACE_H - /* Initialize menus to default settings */ - GtkWidget *sub_menu = - gtk_menu_item_get_submenu (GTK_MENU_ITEM (ui_menuitem_capture)); - gtk_container_foreach (GTK_CONTAINER (sub_menu), sub_menu_initialize, NULL); - sub_menu = - gtk_menu_item_get_submenu (GTK_MENU_ITEM (ui_menuitem_photography)); - gtk_container_foreach (GTK_CONTAINER (sub_menu), sub_menu_initialize, NULL); -#endif - - capture_state = CAP_STATE_IMAGE; - return TRUE; -done: - fprintf (stderr, "error to create pipeline\n"); - fflush (stderr); - me_gst_cleanup_element (); - return FALSE; -} - -static gboolean -me_gst_setup_default_pipeline (gpointer data) -{ - if (!me_gst_setup_pipeline (NULL, NULL)) { - gtk_main_quit (); - } - return FALSE; -} - -static void -me_gst_cleanup_element (void) -{ - if (gst_camera_bin) { - GstBus *bus; - - gst_element_set_state (gst_camera_bin, GST_STATE_NULL); - gst_element_get_state (gst_camera_bin, NULL, NULL, GST_CLOCK_TIME_NONE); - - bus = gst_pipeline_get_bus (GST_PIPELINE (gst_camera_bin)); - gst_bus_set_sync_handler (bus, NULL, NULL); - g_source_remove (bus_handler_id); - - gst_object_unref (gst_camera_bin); - gst_camera_bin = NULL; - - g_list_foreach (video_caps_list, (GFunc) gst_caps_unref, NULL); - g_list_free (video_caps_list); - video_caps_list = NULL; - } -} - -static gboolean -capture_mode_stop (void) -{ - if (capture_state == CAP_STATE_VIDEO_PAUSED - || capture_state == CAP_STATE_VIDEO_RECORDING) { - return capture_mode_set_state (CAP_STATE_VIDEO_STOPED); - } else { - return TRUE; - } -} - -static void -capture_mode_config_gui (void) -{ - switch (capture_state) { - case CAP_STATE_IMAGE: - gtk_button_set_label (ui_bnt_shot, "Shot"); - gtk_button_set_label (ui_bnt_pause, "Focus"); - gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_pause), TRUE); - gtk_widget_show (ui_chk_continous); - gtk_widget_show (ui_chk_rawmsg); - gtk_widget_hide (ui_chk_mute); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ui_rdbntImageCapture), - TRUE); - break; - case CAP_STATE_VIDEO_STOPED: - gtk_button_set_label (ui_bnt_shot, "Rec"); - gtk_button_set_label (ui_bnt_pause, "Pause"); - gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_pause), FALSE); - gtk_widget_show (GTK_WIDGET (ui_bnt_pause)); - gtk_widget_show (ui_chk_mute); - gtk_widget_hide (ui_chk_continous); - gtk_widget_hide (ui_chk_rawmsg); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ui_rdbntVideoCapture), - TRUE); - break; - case CAP_STATE_VIDEO_PAUSED: - gtk_button_set_label (ui_bnt_pause, "Cont"); - break; - case CAP_STATE_VIDEO_RECORDING: - gtk_button_set_label (ui_bnt_shot, "Stop"); - gtk_button_set_label (ui_bnt_pause, "Pause"); - gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_pause), TRUE); - break; - default: - break; - } -} - -static gboolean -capture_mode_set_state (CaptureState state) -{ - if (capture_state == state) - return TRUE; - - switch (capture_state) { - case CAP_STATE_IMAGE: - if (state == CAP_STATE_VIDEO_PAUSED) { - goto done; - } - g_object_set (gst_camera_bin, "mode", 1, NULL); - capture_state = CAP_STATE_VIDEO_STOPED; - if (state == CAP_STATE_VIDEO_RECORDING) - capture_mode_set_state (state); - break; - case CAP_STATE_VIDEO_STOPED: - if (state == CAP_STATE_VIDEO_PAUSED) { - goto done; - } - capture_state = state; - if (state == CAP_STATE_IMAGE) - g_object_set (gst_camera_bin, "mode", 0, NULL); - else { /* state == CAP_STATE_VIDEO_RECORDING */ - g_object_set (gst_camera_bin, "mode", 1, NULL); - g_signal_emit_by_name (gst_camera_bin, "capture-start", 0); - } - break; - case CAP_STATE_VIDEO_PAUSED: - if (state == CAP_STATE_VIDEO_RECORDING) { - g_signal_emit_by_name (gst_camera_bin, "capture-start", 0); - capture_state = CAP_STATE_VIDEO_RECORDING; - } else { - g_signal_emit_by_name (gst_camera_bin, "capture-stop", 0); - capture_state = CAP_STATE_VIDEO_STOPED; - if (state == CAP_STATE_IMAGE) - capture_mode_set_state (state); - } - break; - case CAP_STATE_VIDEO_RECORDING: - if (state == CAP_STATE_VIDEO_PAUSED) { - g_signal_emit_by_name (gst_camera_bin, "capture-pause", 0); - capture_state = CAP_STATE_VIDEO_PAUSED; - } else { - g_signal_emit_by_name (gst_camera_bin, "capture-stop", 0); - capture_state = CAP_STATE_VIDEO_STOPED; - if (state == CAP_STATE_IMAGE) - capture_mode_set_state (state); - } - break; - } - return TRUE; -done: - return FALSE; -} - -void -on_windowMain_delete_event (GtkWidget * widget, GdkEvent * event, gpointer data) -{ - capture_mode_set_state (CAP_STATE_IMAGE); - capture_mode_config_gui (); - me_gst_cleanup_element (); - gtk_main_quit (); -} - -static void -set_metadata (void) -{ - /* for more information about image metadata tags, see: - * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/tests/icles/metadata_editor.c - * and for the mapping: - * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/ext/metadata/metadata_mapping.htm?view=co - */ - - GstTagSetter *setter = GST_TAG_SETTER (gst_camera_bin); - GTimeVal time = { 0, 0 }; - gchar *date_str, *desc_str; - - g_get_current_time (&time); - date_str = g_time_val_to_iso8601 (&time); /* this is UTC */ - desc_str = g_strdup_printf ("picture taken by %s", g_get_real_name ()); - - gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE, - "date-time-original", date_str, - "date-time-modified", date_str, - "creator-tool", "camerabin-demo", - GST_TAG_DESCRIPTION, desc_str, - GST_TAG_TITLE, "My picture", GST_TAG_COPYRIGHT, "LGPL", NULL); - - g_free (date_str); - g_free (desc_str); -} - -void -on_buttonShot_clicked (GtkButton * button, gpointer user_data) -{ - switch (capture_state) { - case CAP_STATE_IMAGE: - { - gtk_widget_set_sensitive (GTK_WIDGET (ui_bnt_shot), FALSE); - set_filename (filename); - num_pics++; - g_object_set (gst_camera_bin, "filename", filename->str, NULL); - - set_metadata (); - g_signal_emit_by_name (gst_camera_bin, "capture-start", 0); - } - break; - case CAP_STATE_VIDEO_STOPED: - set_filename (filename); - num_vids++; - g_object_set (gst_camera_bin, "filename", filename->str, NULL); - capture_mode_set_state (CAP_STATE_VIDEO_RECORDING); - capture_mode_config_gui (); - break; - case CAP_STATE_VIDEO_PAUSED: - /* fall trough */ - case CAP_STATE_VIDEO_RECORDING: - capture_mode_set_state (CAP_STATE_VIDEO_STOPED); - capture_mode_config_gui (); - break; - default: - break; - } -} - -void -on_buttonPause_clicked (GtkButton * button, gpointer user_data) -{ - switch (capture_state) { - case CAP_STATE_IMAGE: - if (g_str_equal (gtk_button_get_label (ui_bnt_pause), "Focus")) { - /* Start autofocus */ - gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), TRUE); - gtk_button_set_label (ui_bnt_pause, "Cancel Focus"); - } else { - /* Cancel autofocus */ - gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), FALSE); - gtk_button_set_label (ui_bnt_pause, "Focus"); - } - break; - case CAP_STATE_VIDEO_STOPED: - break; - case CAP_STATE_VIDEO_PAUSED: - capture_mode_set_state (CAP_STATE_VIDEO_RECORDING); - capture_mode_config_gui (); - break; - case CAP_STATE_VIDEO_RECORDING: - capture_mode_set_state (CAP_STATE_VIDEO_PAUSED); - capture_mode_config_gui (); - break; - default: - break; - } -} - -void -on_drawingareaView_realize (GtkWidget * widget, gpointer data) -{ -#if GTK_CHECK_VERSION (2, 18, 0) - gdk_window_ensure_native (gtk_widget_get_window (widget)); -#endif -} - -gboolean -on_drawingareaView_configure_event (GtkWidget * widget, - GdkEventConfigure * event, gpointer data) -{ - GtkAllocation a; - - gtk_widget_get_allocation (widget, &a); - gdk_window_move_resize (gtk_widget_get_window (widget), - a.x, a.y, a.width, a.height); - gdk_display_sync (gtk_widget_get_display (widget)); - - return TRUE; -} - -void -on_comboboxResolution_changed (GtkComboBox * widget, gpointer user_data) -{ - GstStructure *st; - gint w = 0, h = 0; - GstCaps *video_caps = - g_list_nth_data (video_caps_list, gtk_combo_box_get_active (widget)); - - if (video_caps) { - GstState old; - - gst_element_get_state (gst_camera_bin, &old, NULL, GST_CLOCK_TIME_NONE); - GST_DEBUG ("change resolution in %s", gst_element_state_get_name (old)); - - if (old != GST_STATE_NULL) { - gst_element_set_state (gst_camera_bin, GST_STATE_READY); - /* source need to be NULL, otherwise changing the mode fails with device - * busy: - * - if src goes from NULL->PLAYING it sets new mode anyway - * - if src goes form READY->PLAYIN new mode is activated via reverse caps - * negotiation, but then the device is already streaming - */ - gst_element_set_state (gst_videosrc, GST_STATE_NULL); - } - - st = gst_caps_get_structure (video_caps, 0); - - gst_structure_get_int (st, "width", &w); - gst_structure_get_int (st, "height", &h); - - if (w && h) { - g_object_set (ui_drawing_frame, "ratio", (gfloat) w / (gfloat) h, NULL); - } - - g_object_set (G_OBJECT (gst_camera_bin), "filter-caps", video_caps, NULL); - - if (old != GST_STATE_NULL) { - gst_element_set_state (gst_camera_bin, old); - } - } -} - -void -on_radiobuttonImageCapture_toggled (GtkToggleButton * togglebutton, - gpointer user_data) -{ - if (gtk_toggle_button_get_active (togglebutton)) { - if (capture_state != CAP_STATE_IMAGE) { - capture_mode_set_state (CAP_STATE_IMAGE); - capture_mode_config_gui (); - } - } -} - -void -on_radiobuttonVideoCapture_toggled (GtkToggleButton * togglebutton, - gpointer user_data) -{ - if (gtk_toggle_button_get_active (togglebutton)) { - if (capture_state == CAP_STATE_IMAGE) { - capture_mode_set_state (CAP_STATE_VIDEO_STOPED); - capture_mode_config_gui (); - } - } -} - -static void -on_rbBntVidEff_toggled (GtkToggleButton * togglebutton, const gchar * effect) -{ - if (gtk_toggle_button_get_active (togglebutton)) { - /* lets also use those effects to image */ - video_post = effect; - image_post = effect; - capture_mode_stop (); - - me_gst_cleanup_element (); - if (!me_gst_setup_pipeline (image_post, video_post)) - gtk_main_quit (); - capture_mode_config_gui (); - } -} - -void -on_rbBntVidEffNone_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - on_rbBntVidEff_toggled (togglebutton, NULL); -} - -void -on_rbBntVidEffEdge_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - on_rbBntVidEff_toggled (togglebutton, "edgetv"); -} - -void -on_rbBntVidEffAging_toggled (GtkToggleButton * togglebutton, gpointer user_data) -{ - on_rbBntVidEff_toggled (togglebutton, "agingtv"); -} - -void -on_rbBntVidEffDice_toggled (GtkToggleButton * togglebutton, gpointer user_data) -{ - on_rbBntVidEff_toggled (togglebutton, "dicetv"); -} - -void -on_rbBntVidEffWarp_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - on_rbBntVidEff_toggled (togglebutton, "warptv"); -} - -void -on_rbBntVidEffShagadelic_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - on_rbBntVidEff_toggled (togglebutton, "shagadelictv"); -} - -void -on_rbBntVidEffVertigo_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - on_rbBntVidEff_toggled (togglebutton, "vertigotv"); -} - -void -on_rbBntVidEffRev_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - on_rbBntVidEff_toggled (togglebutton, "revtv"); -} - -void -on_rbBntVidEffQuark_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - on_rbBntVidEff_toggled (togglebutton, "quarktv"); -} - -void -on_chkbntMute_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - g_object_set (gst_camera_bin, "mute", - gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton)), NULL); -} - -void -on_chkbtnRawMsg_toggled (GtkToggleButton * togglebutton, gpointer data) -{ - const gchar *env_var = "CAMSRC_PUBLISH_RAW"; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (togglebutton))) { - g_setenv (env_var, "1", TRUE); - } else { - g_unsetenv (env_var); - } -} - -void -on_hscaleZoom_value_changed (GtkRange * range, gpointer user_data) -{ - gint zoom = gtk_range_get_value (range); - g_object_set (gst_camera_bin, "zoom", zoom, NULL); -} - -void -on_color_control_value_changed (GtkRange * range, gpointer user_data) -{ - GstColorBalance *balance = GST_COLOR_BALANCE (gst_camera_bin); - gint val = gtk_range_get_value (range); - GstColorBalanceChannel *channel = (GstColorBalanceChannel *) user_data; - gst_color_balance_set_value (balance, channel, val); -} - -#ifndef GDK_KEY_F11 -#define GDK_KEY_F11 GDK_F11 -#endif - -gboolean -on_key_released (GtkWidget * widget, GdkEventKey * event, gpointer user_data) -{ - g_return_val_if_fail (event != NULL, FALSE); - - switch (event->keyval) { - case GDK_KEY_F11: -#ifdef HAVE_GST_PHOTO_IFACE_H - gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), FALSE); -#endif - break; - default: - break; - } - - return FALSE; -} - -gboolean -on_key_pressed (GtkWidget * widget, GdkEventKey * event, gpointer user_data) -{ - g_return_val_if_fail (event != NULL, FALSE); - - switch (event->keyval) { - case GDK_KEY_F11: -#ifdef HAVE_GST_PHOTO_IFACE_H - gst_photography_set_autofocus (GST_PHOTOGRAPHY (gst_videosrc), TRUE); -#endif - break; - case 0x0: - on_buttonShot_clicked (NULL, NULL); - break; - default: - break; - } - - return FALSE; -} - -static void -ui_connect_signals (void) -{ - gtk_builder_connect_signals (builder, NULL); - - g_signal_connect (ui_main_window, "key-press-event", - (GCallback) on_key_pressed, NULL); - - g_signal_connect (ui_main_window, "key-release-event", - (GCallback) on_key_released, NULL); -} - -static gchar * -format_value_callback (GtkScale * scale, gdouble value, gpointer user_data) -{ - GstColorBalanceChannel *channel = (GstColorBalanceChannel *) user_data; - - return g_strdup_printf ("%s: %d", channel->label, (gint) value); -} - -static gint -create_menu_items_from_structure (GstStructure * structure) -{ - GtkListStore *store; - const GValue *framerate_list = NULL; - const gchar *structure_name; - GString *item_str = NULL; - guint j, num_items_created = 0, num_framerates = 1; - gint w = 0, h = 0, n = 0, d = 1; - const gchar *format = NULL; - - g_return_val_if_fail (structure != NULL, 0); - - structure_name = gst_structure_get_name (structure); - - /* lets filter yuv only */ - if (0 == strcmp (structure_name, "video/x-raw-yuv")) { - item_str = g_string_new_len ("", 128); - - if (gst_structure_has_field_typed (structure, "format", G_TYPE_STRING)) { - format = gst_structure_get_string (structure, "format"); - } - - if (gst_structure_has_field_typed (structure, "width", GST_TYPE_INT_RANGE)) { - const GValue *wrange = gst_structure_get_value (structure, "width"); - /* If range found, use the maximum */ - w = gst_value_get_int_range_max (wrange); - } else if (gst_structure_has_field_typed (structure, "width", G_TYPE_INT)) { - gst_structure_get_int (structure, "width", &w); - } - - if (gst_structure_has_field_typed (structure, "height", GST_TYPE_INT_RANGE)) { - const GValue *hrange = gst_structure_get_value (structure, "height"); - /* If range found, use the maximum */ - h = gst_value_get_int_range_max (hrange); - } else if (gst_structure_has_field_typed (structure, "height", G_TYPE_INT)) { - gst_structure_get_int (structure, "height", &h); - } - - if (gst_structure_has_field_typed (structure, "framerate", - GST_TYPE_FRACTION)) { - gst_structure_get_fraction (structure, "framerate", &n, &d); - } else if (gst_structure_has_field_typed (structure, "framerate", - GST_TYPE_LIST)) { - framerate_list = gst_structure_get_value (structure, "framerate"); - num_framerates = gst_value_list_get_size (framerate_list); - } else if (gst_structure_has_field_typed (structure, "framerate", - GST_TYPE_FRACTION_RANGE)) { - const GValue *fr = gst_structure_get_value (structure, "framerate"); - const GValue *frmax = gst_value_get_fraction_range_max (fr); - max_fr_n = gst_value_get_fraction_numerator (frmax); - max_fr_d = gst_value_get_fraction_denominator (frmax); - } - - if (max_fr_n || max_fr_d) { - goto range_found; - } - - store = GTK_LIST_STORE (gtk_combo_box_get_model (ui_cbbox_resolution)); - for (j = 0; j < num_framerates; j++) { - GstCaps *video_caps; - GtkTreeIter iter; - - if (framerate_list) { - const GValue *item = gst_value_list_get_value (framerate_list, j); - n = gst_value_get_fraction_numerator (item); - d = gst_value_get_fraction_denominator (item); - } - g_string_assign (item_str, structure_name); - g_string_append_printf (item_str, " (%s)", format); - g_string_append_printf (item_str, ", %dx%d at %d/%d", w, h, n, d); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, item_str->str, -1); - - video_caps = - gst_caps_new_simple (structure_name, "format", G_TYPE_STRING, - format, - "width", G_TYPE_INT, w, "height", G_TYPE_INT, h, - "framerate", GST_TYPE_FRACTION, n, d, NULL); - video_caps_list = g_list_append (video_caps_list, video_caps); - num_items_created++; - } - } - -range_found: - - if (item_str) { - g_string_free (item_str, TRUE); - } - - return num_items_created; -} - -static void -fill_resolution_combo (GstCaps * caps) -{ - guint size, num_items, i; - GstStructure *st; - - max_fr_n = max_fr_d = 0; - - /* Create new items */ - size = gst_caps_get_size (caps); - - for (i = 0; i < size; i++) { - st = gst_caps_get_structure (caps, i); - num_items = create_menu_items_from_structure (st); - ui_cbbox_resolution_count += num_items; - } -} - -static GstCaps * -create_default_caps (void) -{ - GstCaps *default_caps; - - default_caps = gst_caps_from_string (DEFAULT_VF_CAPS); - - return default_caps; -} - -static void -init_view_finder_resolution_combobox (void) -{ - GstCaps *input_caps = NULL, *default_caps = NULL, *intersect = NULL; - - g_object_get (gst_camera_bin, "video-source-caps", &input_caps, NULL); - if (input_caps) { - fill_resolution_combo (input_caps); - } - - /* Fill in default items if supported */ - default_caps = create_default_caps (); - intersect = gst_caps_intersect (default_caps, input_caps); - if (intersect) { - fill_resolution_combo (intersect); - gst_caps_unref (intersect); - } - gst_caps_unref (default_caps); - - if (input_caps) { - gst_caps_unref (input_caps); - } - - /* Set some item active */ - gtk_combo_box_set_active (ui_cbbox_resolution, ui_cbbox_resolution_count - 1); -} - -static void -destroy_color_controls (void) -{ - GList *widgets, *item; - GtkWidget *widget = NULL; - gpointer user_data = NULL; - - widgets = gtk_container_get_children (GTK_CONTAINER (ui_vbox_color_controls)); - for (item = widgets; item; item = g_list_next (item)) { - widget = GTK_WIDGET (item->data); - user_data = g_object_get_data (G_OBJECT (widget), "channel"); - g_signal_handlers_disconnect_by_func (widget, (GFunc) format_value_callback, - user_data); - g_signal_handlers_disconnect_by_func (widget, - (GFunc) on_color_control_value_changed, user_data); - gtk_container_remove (GTK_CONTAINER (ui_vbox_color_controls), widget); - } - g_list_free (widgets); -} - -static void -create_color_controls (void) -{ - GstColorBalance *balance = NULL; - const GList *controls, *item; - GstColorBalanceChannel *channel; - GtkWidget *hscale; - - if (GST_IS_COLOR_BALANCE (gst_camera_bin)) { - balance = GST_COLOR_BALANCE (gst_camera_bin); - } - - if (NULL == balance) { - goto done; - } - - controls = gst_color_balance_list_channels (balance); - for (item = controls; item; item = g_list_next (item)) { - channel = item->data; - - hscale = gtk_hscale_new ((GtkAdjustment *) - gtk_adjustment_new (gst_color_balance_get_value (balance, channel), - channel->min_value, channel->max_value, 1, 10, 10)); - - g_signal_connect (GTK_RANGE (hscale), "value-changed", - (GCallback) on_color_control_value_changed, (gpointer) channel); - g_signal_connect (GTK_SCALE (hscale), "format-value", - (GCallback) format_value_callback, (gpointer) channel); - g_object_set_data (G_OBJECT (hscale), "channel", (gpointer) channel); - - gtk_box_pack_start (GTK_BOX (ui_vbox_color_controls), GTK_WIDGET (hscale), - FALSE, TRUE, 0); - } - - gtk_widget_show_all (ui_vbox_color_controls); -done: - return; -} - -#ifdef HAVE_GST_PHOTO_IFACE_H -static void -menuitem_toggle_active (GtkWidget * widget, gpointer data) -{ - gboolean active; - g_object_get (G_OBJECT (widget), "active", &active, NULL); - if (active) { - gtk_check_menu_item_toggled (GTK_CHECK_MENU_ITEM (widget)); - } -} - -static void -sub_menu_initialize (GtkWidget * widget, gpointer data) -{ - GtkWidget *submenu; - submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (widget)); - gtk_container_foreach (GTK_CONTAINER (submenu), menuitem_toggle_active, NULL); -} - -void -photo_menuitem_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data) -{ - gboolean active = FALSE, ret = FALSE; - GEnumClass *eclass = (GEnumClass *) user_data; - GType etype = G_ENUM_CLASS_TYPE (eclass); - GEnumValue *val; - gint set_value = -1; - - /* Get value using menu item name */ - val = - g_enum_get_value_by_nick (eclass, - gtk_widget_get_name (GTK_WIDGET (menuitem))); - - g_object_get (G_OBJECT (menuitem), "active", &active, NULL); - if (active) { - if (etype == GST_TYPE_WHITE_BALANCE_MODE) { - GstWhiteBalanceMode mode; - ret = - gst_photography_set_white_balance_mode (GST_PHOTOGRAPHY - (gst_videosrc), val->value); - gst_photography_get_white_balance_mode (GST_PHOTOGRAPHY (gst_videosrc), - &mode); - set_value = (gint) mode; - } else if (etype == GST_TYPE_SCENE_MODE) { - GstSceneMode mode; - ret = - gst_photography_set_scene_mode (GST_PHOTOGRAPHY (gst_videosrc), - val->value); - gst_photography_get_scene_mode (GST_PHOTOGRAPHY (gst_videosrc), &mode); - set_value = (gint) mode; - } else if (etype == GST_TYPE_COLOUR_TONE_MODE) { - GstColourToneMode mode; - ret = - gst_photography_set_colour_tone_mode (GST_PHOTOGRAPHY - (gst_videosrc), val->value); - gst_photography_get_colour_tone_mode (GST_PHOTOGRAPHY (gst_videosrc), - &mode); - set_value = (gint) mode; - } else if (etype == GST_TYPE_FLASH_MODE) { - GstFlashMode mode; - ret = - gst_photography_set_flash_mode (GST_PHOTOGRAPHY (gst_videosrc), - val->value); - gst_photography_get_flash_mode (GST_PHOTOGRAPHY (gst_videosrc), &mode); - set_value = (gint) mode; - } - - if (!ret) { - g_print ("%s setting failed\n", val->value_name); - } else if (val->value != set_value) { - g_print ("%s setting failed, got %d\n", val->value_nick, set_value); - } - } -} - -void -photo_iso_speed_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data) -{ - gboolean active; - const gchar *name; - guint val = 0, set_val = G_MAXUINT; - - g_object_get (G_OBJECT (menuitem), "active", &active, NULL); - if (active) { - name = gtk_widget_get_name (GTK_WIDGET (menuitem)); - /* iso auto setting = 0 */ - /* FIXME: check what values other than 0 can be set */ - if (!g_str_equal (name, "auto")) { - sscanf (name, "%d", &val); - } - if (!gst_photography_set_iso_speed (GST_PHOTOGRAPHY (gst_videosrc), val)) { - g_print ("ISO speed (%d) setting failed\n", val); - } else { - gst_photography_get_iso_speed (GST_PHOTOGRAPHY (gst_videosrc), &set_val); - if (val != set_val) { - g_print ("ISO speed (%d) setting failed, got %d\n", val, set_val); - } - } - } -} - -void -photo_ev_comp_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data) -{ - gboolean active; - const gchar *name; - gfloat val = 0.0, set_val = G_MAXFLOAT; - - g_object_get (G_OBJECT (menuitem), "active", &active, NULL); - if (active) { - name = gtk_widget_get_name (GTK_WIDGET (menuitem)); - sscanf (name, "%f", &val); - if (!gst_photography_set_ev_compensation (GST_PHOTOGRAPHY (gst_videosrc), - val)) { - g_print ("EV compensation (%.1f) setting failed\n", val); - } else { - gst_photography_get_ev_compensation (GST_PHOTOGRAPHY (gst_videosrc), - &set_val); - if (val != set_val) { - g_print ("EV compensation (%.1f) setting failed, got %.1f\n", val, - set_val); - } - } - } -} - -static void -photo_add_submenu_from_enum (GtkMenuItem * parent_item, GType enum_type) -{ - GTypeClass *tclass; - GEnumClass *eclass; - GtkWidget *new_item = NULL, *new_submenu = NULL; - guint i; - GEnumValue *val; - GSList *group = NULL; - - g_return_if_fail (parent_item && enum_type && G_TYPE_IS_CLASSED (enum_type)); - - tclass = g_type_class_ref (enum_type); - eclass = G_ENUM_CLASS (tclass); - new_submenu = gtk_menu_new (); - - for (i = 0; i < eclass->n_values; i++) { - val = g_enum_get_value (eclass, i); - new_item = gtk_radio_menu_item_new_with_label (group, val->value_nick); - /* Store enum nick as the menu item name */ - gtk_widget_set_name (new_item, val->value_nick); - group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (new_item)); - g_signal_connect (new_item, "toggled", - (GCallback) photo_menuitem_toggled_cb, eclass); - gtk_menu_shell_append (GTK_MENU_SHELL (new_submenu), new_item); - gtk_widget_show (new_item); - } - - gtk_menu_item_set_submenu (parent_item, new_submenu); - g_type_class_unref (tclass); -} - -static void -add_submenu_from_list (GtkMenuItem * parent_item, GList * labels, - GCallback toggled_cb) -{ - GtkWidget *new_item = NULL, *new_submenu = NULL; - GSList *group = NULL; - GList *l; - - new_submenu = gtk_menu_new (); - - for (l = labels; l != NULL; l = g_list_next (l)) { - const gchar *label = l->data; - new_item = gtk_radio_menu_item_new_with_label (group, label); - if (g_str_equal (label, "0")) { - /* Let's set zero as default */ - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_item), TRUE); - } - gtk_widget_set_name (new_item, label); - group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (new_item)); - g_signal_connect (new_item, "toggled", toggled_cb, NULL); - gtk_menu_shell_append (GTK_MENU_SHELL (new_submenu), new_item); - gtk_widget_show (new_item); - } - - gtk_menu_item_set_submenu (parent_item, new_submenu); -} - -static GtkMenuItem * -add_menuitem (GtkMenu * parent_menu, const gchar * item_name) -{ - GtkWidget *new_item; - - new_item = gtk_menu_item_new_with_label (item_name); - gtk_menu_shell_append (GTK_MENU_SHELL (parent_menu), new_item); - gtk_widget_show (new_item); - - return GTK_MENU_ITEM (new_item); -} - -GList * -create_iso_speed_labels (void) -{ - GList *labels = NULL; - gint i; - for (i = 0; i < G_N_ELEMENTS (iso_speed_labels); i++) { - labels = g_list_append (labels, iso_speed_labels[i]); - } - return labels; -} - -GList * -create_ev_comp_labels (void) -{ - GList *labels = NULL; - gdouble comp; - char buf[G_ASCII_DTOSTR_BUF_SIZE]; - - for (comp = EV_COMP_MIN; comp <= EV_COMP_MAX; comp += EV_COMP_STEP) { - g_ascii_dtostr (buf, sizeof (buf), comp); - labels = g_list_append (labels, g_strdup (buf)); - } - return labels; -} - -static void -fill_photography_menu (GtkMenuItem * parent_item) -{ - GtkWidget *photo_menu = gtk_menu_new (); - GtkMenuItem *item = NULL; - GList *labels = NULL; - - /* Add menu items and create and associate submenus to each item */ - item = add_menuitem (GTK_MENU (photo_menu), "AWB"); - photo_add_submenu_from_enum (item, GST_TYPE_WHITE_BALANCE_MODE); - - item = add_menuitem (GTK_MENU (photo_menu), "Colour Tone"); - photo_add_submenu_from_enum (item, GST_TYPE_COLOUR_TONE_MODE); - - item = add_menuitem (GTK_MENU (photo_menu), "Scene"); - photo_add_submenu_from_enum (item, GST_TYPE_SCENE_MODE); - - item = add_menuitem (GTK_MENU (photo_menu), "Flash"); - photo_add_submenu_from_enum (item, GST_TYPE_FLASH_MODE); - - item = add_menuitem (GTK_MENU (photo_menu), "ISO"); - labels = create_iso_speed_labels (); - add_submenu_from_list (item, labels, (GCallback) photo_iso_speed_toggled_cb); - g_list_free (labels); - - item = add_menuitem (GTK_MENU (photo_menu), "EV comp"); - labels = create_ev_comp_labels (); - add_submenu_from_list (item, labels, (GCallback) photo_ev_comp_toggled_cb); - g_list_free (labels); - - gtk_menu_item_set_submenu (parent_item, photo_menu); -} - -void -capture_image_res_toggled_cb (GtkRadioMenuItem * menuitem, gpointer user_data) -{ - gboolean active; - const gchar *label; - gint i; - - g_object_get (G_OBJECT (menuitem), "active", &active, NULL); - if (active) { - label = gtk_widget_get_name (GTK_WIDGET (menuitem)); - /* Look for width and height corresponding to the label */ - for (i = 0; i < G_N_ELEMENTS (image_resolution_label_map); i++) { - if (g_str_equal (label, image_resolution_label_map[i].label)) { - /* set found values */ - g_signal_emit_by_name (gst_camera_bin, "set-image-resolution", - image_resolution_label_map[i].width, - image_resolution_label_map[i].height, 0); - break; - } - } - } -} - -GList * -create_image_resolution_labels (void) -{ - GList *labels = NULL; - int i; - for (i = 0; i < G_N_ELEMENTS (image_resolution_label_map); i++) { - labels = g_list_append (labels, image_resolution_label_map[i].label); - } - return labels; -} - -static void -fill_capture_menu (GtkMenuItem * parent_item) -{ - GtkWidget *capture_menu = gtk_menu_new (); - GtkMenuItem *item = NULL; - GList *labels = NULL; - - /* Add menu items and create and associate submenus to each item */ - item = add_menuitem (GTK_MENU (capture_menu), "Image resolution"); - - labels = create_image_resolution_labels (); - add_submenu_from_list (item, labels, - (GCallback) capture_image_res_toggled_cb); - g_list_free (labels); - - gtk_menu_item_set_submenu (parent_item, capture_menu); -} -#endif /* HAVE_GST_PHOTO_IFACE_H */ - -static gboolean -ui_create (void) -{ - GError *error = NULL; - - builder = gtk_builder_new (); - if (!gtk_builder_add_from_file (builder, UI_FILE, &error)) { - g_warning ("Couldn't load builder file: %s", error->message); - g_error_free (error); - goto done; - } - - ui_main_window = GTK_WIDGET (gtk_builder_get_object (builder, "windowMain")); - ui_drawing = GTK_WIDGET (gtk_builder_get_object (builder, "drawingareaView")); - ui_drawing_frame = - GTK_WIDGET (gtk_builder_get_object (builder, "drawingareaFrame")); - ui_chk_continous = - GTK_WIDGET (gtk_builder_get_object (builder, "chkbntContinous")); - ui_chk_rawmsg = GTK_WIDGET (gtk_builder_get_object (builder, "chkbtnRawMsg")); - ui_bnt_shot = GTK_BUTTON (gtk_builder_get_object (builder, "buttonShot")); - ui_bnt_pause = GTK_BUTTON (gtk_builder_get_object (builder, "buttonPause")); - ui_cbbox_resolution = - GTK_COMBO_BOX (gtk_builder_get_object (builder, "comboboxResolution")); - ui_chk_mute = GTK_WIDGET (gtk_builder_get_object (builder, "chkbntMute")); - ui_vbox_color_controls = - GTK_WIDGET (gtk_builder_get_object (builder, "vboxColorControls")); - ui_rdbntImageCapture = - GTK_WIDGET (gtk_builder_get_object (builder, "radiobuttonImageCapture")); - ui_rdbntVideoCapture = - GTK_WIDGET (gtk_builder_get_object (builder, "radiobuttonVideoCapture")); - ui_menuitem_photography = - GTK_WIDGET (gtk_builder_get_object (builder, "menuitemPhotography")); - ui_menuitem_capture = - GTK_WIDGET (gtk_builder_get_object (builder, "menuitemCapture")); - -#ifdef HAVE_GST_PHOTO_IFACE_H - if (ui_menuitem_photography) { - fill_photography_menu (GTK_MENU_ITEM (ui_menuitem_photography)); - } - - if (ui_menuitem_capture) { - fill_capture_menu (GTK_MENU_ITEM (ui_menuitem_capture)); - } -#endif - if (!(ui_main_window && ui_drawing && ui_chk_continous && ui_bnt_shot && - ui_bnt_pause && ui_cbbox_resolution && ui_chk_mute && - ui_vbox_color_controls && ui_rdbntImageCapture && - ui_rdbntVideoCapture && ui_chk_rawmsg && ui_menuitem_photography && - ui_menuitem_capture)) { - fprintf (stderr, "Some widgets couldn't be created\n"); - fflush (stderr); - goto done; - } - - gtk_widget_set_double_buffered (ui_drawing, FALSE); - ui_connect_signals (); - gtk_widget_show_all (ui_main_window); - capture_mode_config_gui (); - return TRUE; -done: - return FALSE; -} - -/* - * main - */ - -int -main (int argc, char *argv[]) -{ - int ret = 0; - - gst_init (&argc, &argv); - gtk_init (&argc, &argv); - - filename = g_string_new_len ("", 16); - - /* create UI */ - if (!ui_create ()) { - ret = -1; - goto done; - } - /* create pipeline and run */ - g_idle_add (me_gst_setup_default_pipeline, NULL); - gtk_main (); - -done: - me_gst_cleanup_element (); - g_string_free (filename, TRUE); - return ret; -} |