Imported Upstream version 0.10.23
[profile/ivi/gst-plugins-bad.git] / tests / examples / camerabin2 / gst-camera2.c
1 /*
2  * GStreamer
3  * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 /*
21  * This is a demo application to test the camerabin element.
22  * If you have question don't hesitate in contact me edgard.lima@indt.org.br
23  */
24
25 /*
26  * Includes
27  */
28 #ifdef HAVE_CONFIG_H
29 #  include "config.h"
30 #endif
31
32 #include "gst-camera2.h"
33
34 #include <string.h>
35
36 #include <gst/pbutils/encoding-profile.h>
37 #include <gst/gst.h>
38 #include <gst/interfaces/xoverlay.h>
39 #include <gtk/gtk.h>
40 #include <gdk/gdkx.h>
41 #include <gdk/gdkkeysyms.h>
42
43 #define UI_FILE CAMERA_APPS_UIDIR G_DIR_SEPARATOR_S "gst-camera2.ui"
44
45 static GstElement *camera;
46 static GtkBuilder *builder;
47 static GtkWidget *ui_main_window;
48
49 typedef struct
50 {
51   const gchar *name;
52   GstEncodingProfile *(*create_profile) ();
53 } GstCameraVideoFormat;
54
55 static GstEncodingProfile *
56 create_ogg_profile (void)
57 {
58   GstEncodingContainerProfile *container;
59
60   container = gst_encoding_container_profile_new ("ogg", NULL,
61       gst_caps_new_simple ("application/ogg", NULL), NULL);
62
63   gst_encoding_container_profile_add_profile (container, (GstEncodingProfile *)
64       gst_encoding_video_profile_new (gst_caps_new_simple ("video/x-theora",
65               NULL), NULL, NULL, 1));
66   gst_encoding_container_profile_add_profile (container, (GstEncodingProfile *)
67       gst_encoding_audio_profile_new (gst_caps_new_simple ("audio/x-vorbis",
68               NULL), NULL, NULL, 1));
69
70   return (GstEncodingProfile *) container;
71 }
72
73 static GstEncodingProfile *
74 create_webm_profile (void)
75 {
76   GstEncodingContainerProfile *container;
77
78   container = gst_encoding_container_profile_new ("webm", NULL,
79       gst_caps_new_simple ("video/webm", NULL), NULL);
80
81   gst_encoding_container_profile_add_profile (container, (GstEncodingProfile *)
82       gst_encoding_video_profile_new (gst_caps_new_simple ("video/x-vp8", NULL),
83           NULL, NULL, 1));
84   gst_encoding_container_profile_add_profile (container, (GstEncodingProfile *)
85       gst_encoding_audio_profile_new (gst_caps_new_simple ("audio/x-vorbis",
86               NULL), NULL, NULL, 1));
87
88   return (GstEncodingProfile *) container;
89 }
90
91 static GstEncodingProfile *
92 create_mp4_profile (void)
93 {
94   GstEncodingContainerProfile *container;
95
96   container = gst_encoding_container_profile_new ("mp4", NULL,
97       gst_caps_new_simple ("video/quicktime", "variant", G_TYPE_STRING, "iso",
98           NULL), NULL);
99
100   gst_encoding_container_profile_add_profile (container, (GstEncodingProfile *)
101       gst_encoding_video_profile_new (gst_caps_new_simple ("video/x-h264",
102               NULL), NULL, NULL, 1));
103   gst_encoding_container_profile_add_profile (container, (GstEncodingProfile *)
104       gst_encoding_audio_profile_new (gst_caps_new_simple ("audio/mpeg",
105               "version", G_TYPE_INT, 4, NULL), NULL, NULL, 1));
106
107   return (GstEncodingProfile *) container;
108 }
109
110 GstCameraVideoFormat formats[] = {
111   {"ogg (theora/vorbis)", create_ogg_profile}
112   ,
113   {"webm (vp8/vorbis)", create_webm_profile}
114   ,
115   {"mp4 (h264+aac)", create_mp4_profile}
116   ,
117   {NULL, NULL}
118 };
119
120 void
121 on_mainWindow_delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
122 {
123   gtk_main_quit ();
124 }
125
126 void
127 on_captureButton_clicked (GtkButton * button, gpointer user_data)
128 {
129   g_signal_emit_by_name (camera, "start-capture", NULL);
130 }
131
132 void
133 on_stopCaptureButton_clicked (GtkButton * button, gpointer user_data)
134 {
135   g_signal_emit_by_name (camera, "stop-capture", NULL);
136 }
137
138 void
139 on_imageRButton_toggled (GtkToggleButton * button, gpointer user_data)
140 {
141   if (gtk_toggle_button_get_active (button)) {
142     g_object_set (camera, "mode", 1, NULL);     /* Image mode */
143   }
144 }
145
146 void
147 on_videoRButton_toggled (GtkToggleButton * button, gpointer user_data)
148 {
149   if (gtk_toggle_button_get_active (button)) {
150     g_object_set (camera, "mode", 2, NULL);     /* Video mode */
151   }
152 }
153
154 void
155 on_viewfinderArea_realize (GtkWidget * widget, gpointer data)
156 {
157 #if GTK_CHECK_VERSION (2, 18, 0)
158   gdk_window_ensure_native (gtk_widget_get_window (widget));
159 #endif
160 }
161
162 void
163 on_formatComboBox_changed (GtkWidget * widget, gpointer data)
164 {
165   GstEncodingProfile *profile = NULL;
166   gint index = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
167
168   if (formats[index].create_profile) {
169     profile = formats[index].create_profile ();
170   }
171
172   g_return_if_fail (profile != NULL);
173   gst_element_set_state (camera, GST_STATE_NULL);
174   g_object_set (camera, "video-profile", profile, NULL);
175   gst_encoding_profile_unref (profile);
176
177   if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (camera,
178           GST_STATE_PLAYING)) {
179     GtkWidget *dialog =
180         gtk_message_dialog_new (GTK_WINDOW (ui_main_window), GTK_DIALOG_MODAL,
181         GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
182         "Could not initialize camerabin2 with the "
183         "selected format. Your system might not have the required plugins installed.\n"
184         "Please select another format.");
185
186     gtk_dialog_run (GTK_DIALOG (dialog));
187
188     gtk_widget_destroy (dialog);
189   }
190 }
191
192 static GstBusSyncReply
193 bus_sync_callback (GstBus * bus, GstMessage * message, gpointer data)
194 {
195   GtkWidget *ui_drawing;
196
197   if (GST_MESSAGE_TYPE (message) != GST_MESSAGE_ELEMENT)
198     return GST_BUS_PASS;
199
200   if (!gst_structure_has_name (message->structure, "prepare-xwindow-id"))
201     return GST_BUS_PASS;
202
203   /* FIXME: make sure to get XID in main thread */
204   ui_drawing = GTK_WIDGET (gtk_builder_get_object (builder, "viewfinderArea"));
205   gst_x_overlay_set_window_handle (GST_X_OVERLAY (message->src),
206 #if GTK_CHECK_VERSION (2, 91, 6)
207       GDK_WINDOW_XID (gtk_widget_get_window (ui_drawing)));
208 #else
209       GDK_WINDOW_XWINDOW (gtk_widget_get_window (ui_drawing)));
210 #endif
211
212   gst_message_unref (message);
213   return GST_BUS_DROP;
214 }
215
216
217 static gboolean
218 bus_callback (GstBus * bus, GstMessage * message, gpointer data)
219 {
220   switch (GST_MESSAGE_TYPE (message)) {
221     case GST_MESSAGE_WARNING:{
222       GError *err;
223       gchar *debug;
224
225       gst_message_parse_warning (message, &err, &debug);
226       g_print ("Warning: %s\n", err->message);
227       g_error_free (err);
228       g_free (debug);
229       break;
230     }
231     case GST_MESSAGE_ERROR:{
232       GError *err = NULL;
233       gchar *debug = NULL;
234
235       gst_message_parse_error (message, &err, &debug);
236       g_print ("Error: %s : %s\n", err->message, debug);
237       g_error_free (err);
238       g_free (debug);
239
240       gtk_main_quit ();
241       break;
242     }
243     case GST_MESSAGE_EOS:
244       /* end-of-stream */
245       g_print ("Eos\n");
246       gtk_main_quit ();
247       break;
248     case GST_MESSAGE_ELEMENT:
249     {
250       //handle_element_message (message);
251       break;
252     }
253     default:
254       /* unhandled message */
255       break;
256   }
257   return TRUE;
258 }
259
260 static gboolean
261 init_gtkwidgets_data (void)
262 {
263 #if GTK_CHECK_VERSION(2,24,0)
264   gint i;
265   GtkComboBoxText *combobox =
266       GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "formatComboBox"));
267
268   /* init formats combobox */
269   i = 0;
270   while (formats[i].name) {
271     gtk_combo_box_text_append_text (combobox, formats[i].name);
272     i++;
273   }
274
275   /* default to the first one -> ogg */
276   gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0);
277   return TRUE;
278 #else
279   g_warning ("This needs a newer version of GTK (2.24 at least)");
280   return FALSE;
281 #endif
282 }
283
284 int
285 main (int argc, char *argv[])
286 {
287   int ret = 0;
288   GError *error = NULL;
289   GstBus *bus;
290
291   gst_init (&argc, &argv);
292   gtk_init (&argc, &argv);
293
294   builder = gtk_builder_new ();
295   if (!gtk_builder_add_from_file (builder, UI_FILE, &error)) {
296     g_warning ("Error: %s", error->message);
297     g_error_free (error);
298     return 1;
299   }
300
301   camera = gst_element_factory_make ("camerabin2", "camera");
302   bus = gst_pipeline_get_bus (GST_PIPELINE (camera));
303   gst_bus_add_watch (bus, bus_callback, NULL);
304   gst_bus_set_sync_handler (bus, bus_sync_callback, NULL);
305   gst_object_unref (bus);
306
307   if (!init_gtkwidgets_data ()) {
308     goto error;
309   }
310
311   ui_main_window = GTK_WIDGET (gtk_builder_get_object (builder, "mainWindow"));
312   gtk_builder_connect_signals (builder, NULL);
313   gtk_widget_show_all (ui_main_window);
314
315   gst_element_set_state (camera, GST_STATE_PLAYING);
316
317   gtk_main ();
318
319 error:
320   gst_element_set_state (camera, GST_STATE_NULL);
321   gst_object_unref (camera);
322   return ret;
323 }