* ext/gst-camerabin/gdigicam-camerabin.c: The 16x9 still picture
[fremantle-gdigicam:gdigicam.git] / ext / gst-camerabin / gdigicam-camerabin.c
1 /*
2  * This file is part of GDigicam
3  *
4  * Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
5  *
6  * Contact: Alexander Bokovoy <alexander.bokovoy@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * version 2.1 as published by the Free Software Foundation.
11  *
12  * This library is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24
25 /**
26  * SECTION:gdigicam-camerabin
27  * @short_description: GDigicam Descriptor for GStreamer camerabin
28  * plugin
29  *
30  * GDigicam Camerabin provides the tools needed to easily create a
31  * complete #GDigicamDescriptor which internally makes use of the
32  * GStreamer camerabin plugin so it can be used straight away in a
33  * #GDigicamManager.
34  **/
35
36 #include <gdk-pixbuf/gdk-pixbuf.h>
37 #include <gst/interfaces/photography.h>
38 #include <gst/video/video.h>
39
40 #include <config.h>
41
42 #include "gdigicam-camerabin.h"
43 #include "gdigicam-manager-private.h"
44 #include "gdigicam-debug.h"
45
46
47 /*****************************************/
48 /* Utiliy macros */
49 /*****************************************/
50
51 #define G_KEY_FILE_PATH CONFIG_DIR "/gdigicam-camerabin.conf"
52
53 #define GST_TAG_DATE_TIME_ORIGINAL          "date-time-original"
54 #define GST_TAG_DATE_TIME_MODIFIED          "date-time-modified"
55 #define GST_TAG_DEVICE_MAKE                 "device-make"
56 #define GST_TAG_DEVICE_MODEL                "device-model"
57 #define GST_TAG_CLASSIFICATION              "classification"
58 #define GST_TAG_GEO_LOCATION_COUNTRY        "geo-location-country"
59 #define GST_TAG_GEO_LOCATION_CITY           "geo-location-city"
60 #define GST_TAG_GEO_LOCATION_SUBLOCATION    "geo-location-sublocation"
61 #define GST_TAG_CAPTURE_ORIENTATION         "capture-orientation"
62
63 /* FIXME: This should be customizable somehow. */
64 #define G_DIGICAM_CAMERABIN_STILL_4X3_HIGH_WIDTH 2576;
65 #define G_DIGICAM_CAMERABIN_STILL_4X3_HIGH_HEIGHT 1936;
66 #define G_DIGICAM_CAMERABIN_STILL_4X3_MEDIUM_WIDTH 2048;
67 #define G_DIGICAM_CAMERABIN_STILL_4X3_MEDIUM_HEIGHT 1536;
68 #define G_DIGICAM_CAMERABIN_STILL_4X3_LOW_WIDTH 1280;
69 #define G_DIGICAM_CAMERABIN_STILL_4X3_LOW_HEIGHT 960;
70
71 #define G_DIGICAM_CAMERABIN_STILL_16X9_HIGH_WIDTH 2560;
72 #define G_DIGICAM_CAMERABIN_STILL_16X9_HIGH_HEIGHT 1440;
73 #define G_DIGICAM_CAMERABIN_STILL_16X9_MEDIUM_WIDTH 2560;
74 #define G_DIGICAM_CAMERABIN_STILL_16X9_MEDIUM_HEIGHT 1440;
75 #define G_DIGICAM_CAMERABIN_STILL_16X9_LOW_WIDTH 2560;
76 #define G_DIGICAM_CAMERABIN_STILL_16X9_LOW_HEIGHT 1440;
77
78
79 #define G_DIGICAM_CAMERABIN_VIDEO_4X3_HIGH_WIDTH 640;
80 #define G_DIGICAM_CAMERABIN_VIDEO_4X3_HIGH_HEIGHT 480;
81 #define G_DIGICAM_CAMERABIN_VIDEO_4X3_MEDIUM_WIDTH 640;
82 #define G_DIGICAM_CAMERABIN_VIDEO_4X3_MEDIUM_HEIGHT 480;
83 #define G_DIGICAM_CAMERABIN_VIDEO_4X3_LOW_WIDTH 320;
84 #define G_DIGICAM_CAMERABIN_VIDEO_4X3_LOW_HEIGHT 240;
85
86 #define G_DIGICAM_CAMERABIN_VIDEO_16X9_HIGH_WIDTH 848;
87 #define G_DIGICAM_CAMERABIN_VIDEO_16X9_HIGH_HEIGHT 480;
88 #define G_DIGICAM_CAMERABIN_VIDEO_16X9_MEDIUM_WIDTH 848;
89 #define G_DIGICAM_CAMERABIN_VIDEO_16X9_MEDIUM_HEIGHT 480;
90 #define G_DIGICAM_CAMERABIN_VIDEO_16X9_LOW_WIDTH 848;
91 #define G_DIGICAM_CAMERABIN_VIDEO_16X9_LOW_HEIGHT 480;
92
93
94 /* Viewfinder resolutions and fps for still picture. */
95 #define G_DIGICAM_CAMERABIN_VIEWFINDER_4X3_WIDTH 640;
96 #define G_DIGICAM_CAMERABIN_VIEWFINDER_4X3_HEIGHT 480;
97 #define G_DIGICAM_CAMERABIN_VIEWFINDER_4X3_FPS 2993;
98
99 #define G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_WIDTH 800;
100 #define G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_HEIGHT 450;
101 #define G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_FPS 2988;
102
103 /* Framerate for video widescreen mode. */
104 #define G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_VIDEO_FPS 2500;
105
106 #define G_DIGICAM_CAMERABIN_PHOTO_CAPTURE_START_MESSAGE "photo-capture-start"
107 #define G_DIGICAM_CAMERABIN_PHOTO_CAPTURE_PICTURE_GOT_MESSAGE "photo-capture-end"
108 #define G_DIGICAM_CAMERABIN_PHOTO_CAPTURE_END_MESSAGE   "image-captured"
109 #define G_DIGICAM_CAMERABIN_PHOTO_PREVIEW_MESSAGE       "preview-image"
110
111 #define G_DIGICAM_CAMERABIN_DEFAULT_COLORKEY 0x000010
112
113 typedef struct _PreviewHelper {
114     GDigicamManager *mgr;
115     GdkPixbuf *preview;
116 } PreviewHelper;
117
118
119 /**************************************************/
120 /* Camerabin operations implementation prototypes */
121 /**************************************************/
122
123 static gboolean _g_digicam_camerabin_set_mode (GDigicamManager *manager,
124                                                gpointer user_data);
125 static gboolean _g_digicam_camerabin_set_flash_mode (GDigicamManager *manager,
126                                                      gpointer user_data);
127 static gboolean _g_digicam_camerabin_set_focus_mode (GDigicamManager *manager,
128                                                      gpointer user_data);
129 static gboolean _g_digicam_camerabin_set_focus_region_pattern (GDigicamManager *manager,
130                                                                gpointer user_data);
131 static gboolean _g_digicam_camerabin_set_exposure_mode (GDigicamManager *manager,
132                                                         gpointer user_data);
133 static gboolean _g_digicam_camerabin_set_exposure_comp (GDigicamManager *manager,
134                                                         gpointer user_data);
135 static gboolean _g_digicam_camerabin_set_iso_sensitivity_mode (GDigicamManager *manager,
136                                                                gpointer user_data);
137 static gboolean _g_digicam_camerabin_set_white_balance_mode (GDigicamManager *manager,
138                                                              gpointer user_data);
139 static gboolean _g_digicam_camerabin_set_quality (GDigicamManager *manager,
140                                                   gpointer user_data);
141 static gboolean _g_digicam_camerabin_set_aspect_ratio_resolution (GDigicamManager *manager,
142                                                                   gpointer user_data);
143 static gboolean _g_digicam_camerabin_set_locks (GDigicamManager *manager,
144                                                 gpointer user_data);
145 static gboolean _g_digicam_camerabin_set_zoom (GDigicamManager *manager,
146                                                gpointer user_data);
147 static gboolean _g_digicam_camerabin_set_audio (GDigicamManager *manager,
148                                                 gpointer user_data);
149 static gboolean _g_digicam_camerabin_set_preview_mode (GDigicamManager *manager,
150                                                        gpointer user_data);
151 static gboolean _g_digicam_camerabin_get_still_picture (GDigicamManager *manager,
152                                                         gpointer user_data);
153 static gboolean _g_digicam_camerabin_start_recording_video (GDigicamManager *manager,
154                                                             gpointer user_data);
155 static gboolean _g_digicam_camerabin_pause_recording_video (GDigicamManager *manager,
156                                                             gpointer user_data);
157 static gboolean _g_digicam_camerabin_finish_recording_video (GDigicamManager *manager,
158                                                              gpointer user_data);
159 static void _g_digicam_camerabin_set_picture_metadata (GstElement *gst_camera_bin,
160                                                        const GDigicamCamerabinMetadata *metadata);
161 static void _g_digicam_camerabin_set_video_metadata (GstElement *gst_camera_bin,
162                                                      const GDigicamCamerabinMetadata *metadata);
163 static gboolean _g_digicam_camerabin_handle_bus_message (GDigicamManager *manager,
164                                                          gpointer user_data);
165 static gboolean _g_digicam_camerabin_handle_sync_bus_message (GDigicamManager *manager,
166                                                               gpointer user_data);
167
168
169 /**************************************************/
170 /* Camerabin utility method prototypes            */
171 /**************************************************/
172
173
174 static void _pixbuf_destroy (guchar *pixels, gpointer data);
175 static GdkPixbuf *_pixbuf_from_buffer (GDigicamManager *manager,
176                                        GstBuffer *buff,
177                                        gboolean has_alpha);
178 static gboolean _emit_preview_signal (gpointer user_data);
179 static gboolean _emit_capture_start_signal (gpointer user_data);
180 static gboolean _emit_capture_end_signal (gpointer user_data);
181 static gboolean _emit_picture_got_signal (gpointer user_data);
182 static GstCaps *_new_preview_caps (gint pre_w, gint pre_h);
183 static void _get_aspect_ratio_and_resolution (GDigicamMode mode,
184                                               GDigicamAspectratio ar,
185                                               GDigicamResolution res,
186                                               gint *vf_w, gint *vf_h,
187                                               gint *res_w, gint *res_h,
188                                               gint *fps_n, gint *fps_d);
189 static void _get_still_aspect_ratio_and_resolution (GDigicamAspectratio ar,
190                                                     GDigicamResolution res,
191                                                     gint *vf_w, gint *vf_h,
192                                                     gint *res_w, gint *res_h,
193                                                     gint *fps_n, gint *fps_d);
194 static void _get_video_aspect_ratio_and_resolution (GDigicamAspectratio ar,
195                                                     GDigicamResolution res,
196                                                     gint *vf_w, gint *vf_h,
197                                                     gint *res_w, gint *res_h,
198                                                     gint *fps_n, gint *fps_d);
199
200
201 /*****************************/
202 /* Public abstract functions */
203 /*****************************/
204
205
206 /**
207  * g_digicam_camerabin_descriptor_new:
208  * @gst_camera_bin: The #GstElement described by this descriptor.
209  *
210  * Creates a #GDigicamDescriptor customized to deal with GStreamer
211  * camerabins.
212  *
213  * Returns: A new #GDigicamDescriptor with the proper functions to
214  * deal with a GStreamer camerabin
215  **/
216 GDigicamDescriptor *
217 g_digicam_camerabin_descriptor_new (const GstElement *gst_camera_bin)
218 {
219     GDigicamDescriptor* descriptor = NULL;
220
221     g_return_val_if_fail (NULL != gst_camera_bin, NULL);
222     g_return_val_if_fail (GST_IS_ELEMENT (gst_camera_bin), NULL);
223
224     descriptor = g_digicam_manager_descriptor_new ();
225     descriptor->name = g_strdup ("GStreamer CameraBin");
226     descriptor->set_mode_func = _g_digicam_camerabin_set_mode;
227     descriptor->set_flash_mode_func = _g_digicam_camerabin_set_flash_mode;
228     descriptor->set_focus_mode_func = _g_digicam_camerabin_set_focus_mode;
229     descriptor->set_focus_region_pattern_func = _g_digicam_camerabin_set_focus_region_pattern;
230     descriptor->set_exposure_mode_func = _g_digicam_camerabin_set_exposure_mode;
231     descriptor->set_exposure_comp_func = _g_digicam_camerabin_set_exposure_comp;
232     descriptor->set_iso_sensitivity_mode_func = _g_digicam_camerabin_set_iso_sensitivity_mode;
233     descriptor->set_white_balance_mode_func = _g_digicam_camerabin_set_white_balance_mode;
234     descriptor->set_metering_mode_func = NULL;
235     descriptor->set_aspect_ratio_func = _g_digicam_camerabin_set_aspect_ratio_resolution;
236     descriptor->set_aspect_ratio_resolution_func = _g_digicam_camerabin_set_aspect_ratio_resolution;
237     descriptor->set_quality_func = _g_digicam_camerabin_set_quality;
238     descriptor->set_resolution_func = _g_digicam_camerabin_set_aspect_ratio_resolution;
239     descriptor->set_locks_func = _g_digicam_camerabin_set_locks;
240     descriptor->set_zoom_func = _g_digicam_camerabin_set_zoom;
241     descriptor->set_audio_func = _g_digicam_camerabin_set_audio;
242     descriptor->set_preview_mode_func = _g_digicam_camerabin_set_preview_mode;
243     descriptor->get_still_picture_func = _g_digicam_camerabin_get_still_picture;
244     descriptor->start_recording_video_func = _g_digicam_camerabin_start_recording_video;
245     descriptor->pause_recording_video_func = _g_digicam_camerabin_pause_recording_video;
246     descriptor->finish_recording_video_func = _g_digicam_camerabin_finish_recording_video;
247     descriptor->handle_bus_message_func = _g_digicam_camerabin_handle_bus_message;
248     descriptor->handle_sync_bus_message_func = _g_digicam_camerabin_handle_sync_bus_message;
249     g_object_get (G_OBJECT (gst_camera_bin), "vfsink", &descriptor->viewfinder_sink, NULL);
250
251     return descriptor;
252 }
253
254
255 /**
256  * g_digicam_camerabin_element_new:
257  * @videosrc: name of a valid video source #GstElement.
258  * @videoenc: name of a valid video encoder #GstElement.
259  * @videomux: name of a valid video muxer #GstElement.
260  * @audiosrc: name of a valid audio source #GstElement.
261  * @audioenc: name of a valid audio encoder #GstElement.
262  * @imageenc: name of a valid image encoder #GstElement.
263  * @imagepp: name of a valid post processing #GstElement.
264  * @ximagesink: name of a valid X image sink #GstElement.
265  * @colorkey: output parameter to retrieve the colorkey.
266  *
267  * Creates a customized CameraBin #GstElement.
268  *
269  * Returns: A new and complete CameraBin #GstElement.
270  **/
271 GstElement *
272 g_digicam_camerabin_element_new (const gchar *videosrc,
273                                  const gchar *videoenc,
274                                  const gchar *videomux,
275                                  const gchar *audiosrc,
276                                  const gchar *audioenc,
277                                  const gchar *imageenc,
278                                  const gchar *imagepp,
279                                  const gchar *ximagesink,
280                                  gint *colorkey)
281 {
282     GstElement *gst_camera_bin = NULL;
283     GstElement *vsrc = NULL;
284     GstElement *venc = NULL;
285     GstElement *vmux = NULL;
286     GstElement *asrc = NULL;
287     GstElement *aenc = NULL;
288     GstElement *ienc = NULL;
289     GstElement *ipp = NULL;
290     GstElement *ximg = NULL;
291     GstPad *pad = NULL;
292     GstCaps *caps = NULL;
293     GstStructure *gst_struct = NULL;
294     gboolean use_config_file = FALSE;
295     gchar *element = NULL;
296     gint quality = 0;
297     gint bitrate = 0;
298     gint aenc_width = 0;
299     gint aenc_depth = 0;
300     gint aenc_rate = 0;
301     gint aenc_channels = 0;
302     GKeyFile *key_file = NULL;
303     gint ximg_colorkey = 0;
304     GstElement *aenc_bin = NULL;
305     GstElement *capsfilter = NULL;
306
307 #ifdef USE_CONFIG_FILE
308     key_file = g_key_file_new ();
309     use_config_file = g_key_file_load_from_file (key_file,
310                                                  G_KEY_FILE_PATH,
311                                                  G_KEY_FILE_NONE,
312                                                  NULL);
313     if (use_config_file) {
314         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
315                          "config file exists.");
316         use_config_file = g_key_file_get_boolean (key_file,
317                                                   "global",
318                                                   "useconfigfile",
319                                                   NULL);
320         if (use_config_file) {
321             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
322                              "config file indicates to use file config.");
323         } else {
324             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
325                              "config file indicates to use application config.");
326         }
327     } else {
328         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
329                          "config file doesn't exist.");
330     }
331 #endif
332
333     /* Create a new instance of Camerabin component */
334     gst_camera_bin = gst_element_factory_make ("camerabin", NULL);
335     if (NULL == gst_camera_bin) {
336         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
337                          "GStreamer bin creation failed!!!");
338         goto cleanup;
339     }
340
341
342     /* --------------------- videosrc --------------------- */
343
344     if (use_config_file) {
345         element = g_key_file_get_string (key_file,
346                                          "videosrc",
347                                          "element",
348                                          NULL);
349         if (NULL != element) {
350             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
351                              "Using %s videosrc from config file.", element);
352             vsrc = gst_element_factory_make (element, NULL);
353             g_free (element);
354         }
355     } else {
356         if (NULL != videosrc) {
357             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
358                              "App specified %s as videosrc. Using it.",
359                              videosrc);
360             vsrc = gst_element_factory_make (videosrc, NULL);
361         } else {
362             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
363                              "Application didn't specify any videosrc.");
364         }
365     }
366
367     if (NULL != vsrc) {
368         g_object_set (G_OBJECT (gst_camera_bin), "videosrc", vsrc, NULL);
369     } else {
370         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
371                          "video source element creation failed!!!");
372     }
373
374
375     /* --------------------- videoenc --------------------- */
376
377     if (use_config_file) {
378         element = g_key_file_get_string (key_file,
379                                          "videoenc",
380                                          "element",
381                                          NULL);
382         if (NULL != element) {
383             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
384                              "Using %s videoenc from config file.", element);
385             venc = gst_element_factory_make (element, NULL);
386             g_free (element);
387         }
388     } else {
389         if (NULL != videoenc) {
390             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
391                              "App specified %s as videoenc. Using it.",
392                              videoenc);
393             venc = gst_element_factory_make (videoenc, NULL);
394         } else {
395             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
396                              "Application didn't specify any videoenc.");
397         }
398     }
399
400     if (NULL != venc) {
401         g_object_set (G_OBJECT (gst_camera_bin), "videoenc", venc, NULL);
402     } else {
403         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
404                          "video encoder element creation failed!!!");
405     }
406
407
408     /* --------------------- videomux --------------------- */
409
410     if (use_config_file) {
411         element = g_key_file_get_string (key_file,
412                                          "videomux",
413                                          "element",
414                                          NULL);
415         if (NULL != element) {
416             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
417                              "Using %s videomux from config file.", element);
418             vmux = gst_element_factory_make (element, NULL);
419             g_free (element);
420         }
421     } else {
422         if (NULL != videomux) {
423             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
424                              "App specified %s as videomux. Using it.",
425                              videomux);
426             vmux = gst_element_factory_make (videomux, NULL);
427         } else {
428             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
429                              "Application didn't specify any videomux.");
430         }
431     }
432
433     if (NULL != vmux) {
434         g_object_set (G_OBJECT (gst_camera_bin), "videomux", vmux, NULL);
435     } else {
436         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
437                          "video mux element creation failed!!!");
438     }
439
440
441     /* --------------------- audiosrc --------------------- */
442
443     if (use_config_file) {
444         element = g_key_file_get_string (key_file,
445                                          "audiosrc",
446                                          "element",
447                                          NULL);
448         if (NULL != element) {
449             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
450                              "Using %s audiosrc from config file.", element);
451             asrc = gst_element_factory_make (element, NULL);
452             g_free (element);
453         }
454     } else {
455         if (NULL != audiosrc) {
456             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
457                              "App specified %s as audiosrc. Using it.", audiosrc);
458             asrc = gst_element_factory_make (audiosrc, NULL);
459         } else {
460             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
461                              "Application didn't specify any audiosrc.");
462         }
463     }
464
465     if (NULL != asrc) {
466         g_object_set (G_OBJECT (gst_camera_bin), "audiosrc", asrc, NULL);
467     } else {
468         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
469                          "audio source element creation failed!!!");
470     }
471
472
473     /* --------------------- audioenc --------------------- */
474
475     if (use_config_file) {
476         element = g_key_file_get_string (key_file,
477                                          "audioenc",
478                                          "element",
479                                          NULL);
480         if (NULL != element) {
481             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
482                              "Using %s audioenc from config file.", element);
483             aenc = gst_element_factory_make (element, NULL);
484
485             /* bitrate parameter */
486             bitrate = g_key_file_get_integer (key_file,
487                                               "audioenc",
488                                               "bitrate",
489                                               NULL);
490             /* caps parameters */
491             aenc_width = g_key_file_get_integer (key_file,
492                                                  "audioenc",
493                                                  "width",
494                                                  NULL);
495             aenc_depth = g_key_file_get_integer (key_file,
496                                                  "audioenc",
497                                                  "depth",
498                                                  NULL);
499             aenc_rate = g_key_file_get_integer (key_file,
500                                                 "audioenc",
501                                                 "rate",
502                                                 NULL);
503             aenc_channels = g_key_file_get_integer (key_file,
504                                                     "audioenc",
505                                                     "channels",
506                                                     NULL);
507
508             g_free (element);
509         }
510     } else {
511         if (NULL != audioenc) {
512             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
513                              "App specified %s as audioenc. Using it.",
514                              audioenc);
515             aenc = gst_element_factory_make (audioenc, NULL);
516             bitrate = 128000;
517             aenc_width = 16;
518             aenc_depth = 16;
519             aenc_rate = 48000;
520             aenc_channels = 1;
521         } else {
522             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
523                              "Application didn't specify any audioenc.");
524         }
525     }
526
527     if (NULL != aenc) {
528         if (0 != bitrate) {
529             g_object_set (G_OBJECT (aenc), "bitrate", bitrate, NULL);
530         }
531
532         caps = gst_caps_new_empty ();
533         gst_struct = gst_structure_empty_new ("audio/x-raw-int");
534
535         if (0 != aenc_width) {
536             gst_structure_set (gst_struct,
537                                "width", G_TYPE_INT, aenc_width,
538                                NULL);
539         }
540
541         if (0 != aenc_depth) {
542             gst_structure_set (gst_struct,
543                                "depth", G_TYPE_INT, aenc_depth,
544                                NULL);
545         }
546
547         if (0 != aenc_rate) {
548             gst_structure_set (gst_struct,
549                                "rate", G_TYPE_INT, aenc_rate,
550                                NULL);
551         }
552
553         if (0 != aenc_channels) {
554             gst_structure_set (gst_struct,
555                                "channels", G_TYPE_INT, aenc_channels,
556                                NULL);
557         }
558
559         gst_caps_merge_structure (caps, gst_struct);
560
561         aenc_bin = gst_bin_new ("aenc_bin");
562         capsfilter = gst_element_factory_make ("capsfilter", NULL);
563         g_object_set (capsfilter,
564                       "caps",
565                       caps,
566                       NULL);
567         gst_caps_unref (caps);
568
569         gst_bin_add_many (GST_BIN (aenc_bin), capsfilter, aenc, NULL);
570         gst_element_link_many (capsfilter, aenc, NULL);
571
572         pad = gst_element_get_static_pad (capsfilter, "sink");
573         gst_element_add_pad (aenc_bin, gst_ghost_pad_new ("sink", pad));
574         gst_object_unref (pad);
575
576         pad = gst_element_get_static_pad (aenc, "src");
577         gst_element_add_pad (aenc_bin, gst_ghost_pad_new ("src", pad));
578         gst_object_unref (pad);
579
580         g_object_set (G_OBJECT (gst_camera_bin), "audioenc", aenc_bin, NULL);
581     } else {
582         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
583                          "audio encoder element creation failed!!!");
584     }
585
586
587     /* --------------------- imageenc --------------------- */
588
589     if (use_config_file) {
590         element = g_key_file_get_string (key_file,
591                                          "imageenc",
592                                          "element",
593                                          NULL);
594         if (NULL != element) {
595             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
596                              "Using %s imageenc from config file.", element);
597             ienc = gst_element_factory_make (element, NULL);
598
599             /*get quality value */
600             quality = g_key_file_get_integer (key_file,
601                                               "imageenc",
602                                               "quality",
603                                               NULL);
604
605             g_free (element);
606         }
607     } else {
608         if (NULL != imageenc) {
609             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
610                              "App specified %s as imageenc. Using it.",
611                              imageenc);
612             ienc = gst_element_factory_make (imageenc, NULL);
613             quality = 85;
614         } else {
615             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
616                              "Application didn't specify any imageenc.");
617         }
618     }
619
620     if (NULL != ienc) {
621         if (0 != quality) {
622             if (NULL != g_object_class_find_property (G_OBJECT_GET_CLASS (ienc),
623                                                       "quality")) {
624                 g_object_set (G_OBJECT (ienc), "quality", quality, NULL);
625             } else {
626                 G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
627                                  "image encoder has not quality capabilities.");
628             }
629         } else {
630             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
631                              "quality not specified for image encoder.");
632         }
633
634         g_object_set (G_OBJECT (gst_camera_bin), "imageenc", ienc, NULL);
635     } else {
636         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
637                          "image encoder element creation failed!!!");
638     }
639
640
641     /* --------------------- imagepp --------------------- */
642
643     if (use_config_file) {
644         element = g_key_file_get_string (key_file,
645                                          "imagepp",
646                                          "element",
647                                          NULL);
648         if (NULL != element) {
649             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
650                              "Using %s imagepp from config file.", element);
651             ipp = gst_element_factory_make (element, NULL);
652             g_free (element);
653         }
654     } else {
655         if (NULL != imagepp) {
656             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
657                              "App specified %s as imagepp. Using it.",
658                              imagepp);
659             ipp = gst_element_factory_make (imagepp, NULL);
660         } else {
661             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
662                              "Application didn't specify any imagepp.");
663         }
664     }
665
666     if (NULL != ipp) {
667         g_object_set (G_OBJECT (gst_camera_bin), "imagepp", ipp, NULL);
668     } else {
669         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
670                          "image post processing element creation failed!!!");
671     }
672
673
674     /* --------------------- vfsink --------------------- */
675
676     if (NULL != colorkey) {
677         *colorkey = 0;
678     }
679
680     if (use_config_file) {
681         element = g_key_file_get_string (key_file,
682                                          "vfsink",
683                                          "element",
684                                          NULL);
685         if (NULL != element) {
686             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
687                              "Using %s vfsink from config file.", element);
688             ximg = gst_element_factory_make (element, NULL);
689             g_free (element);
690         }
691         ximg_colorkey = g_key_file_get_integer (key_file,
692                                                 "vfsink",
693                                                 "colorkey",
694                                                 NULL);
695     } else {
696         if (NULL != ximagesink) {
697             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
698                              "App specified %s as vfsink. Using it.", ximagesink);
699             ximg = gst_element_factory_make (ximagesink, NULL);
700             ximg_colorkey = G_DIGICAM_CAMERABIN_DEFAULT_COLORKEY;
701         } else {
702             G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
703                              "Application didn't specify any vfsink");
704         }
705     }
706
707     if (NULL != ximg) {
708         g_object_set (G_OBJECT (ximg),
709                       "autopaint-colorkey", FALSE,
710                       "force-aspect-ratio", TRUE,
711                       "draw-borders", FALSE,
712                       "colorkey", ximg_colorkey,
713                       NULL);
714
715         g_object_set (G_OBJECT (gst_camera_bin), "vfsink", ximg, NULL);
716
717         /* Get colorkey if requested */
718         if (NULL != colorkey) {
719             g_object_get (G_OBJECT (ximg),
720                           "colorkey", colorkey,
721                           NULL);
722         }
723     } else {
724         G_DIGICAM_DEBUG ("GDigicamCamerabin::g_digicam_camerabin_element_new: "
725                          "image viewfinder sink element creation failed!!!");
726     }
727
728 cleanup:
729
730     if (NULL != key_file) {
731         g_key_file_free (key_file);
732     }
733
734     return gst_camera_bin;
735 }
736
737
738 /****************************************************************/
739 /* Private functions implementing the abstract public functions */
740 /****************************************************************/
741
742
743 /**
744  * _g_digicam_camerabin_set_mode:
745  * @manager: A #GDigicamManager.
746  * @user_data: A #GDigicamCamerabinModeHelper.
747  *
748  * Implementation of "set_mode" GDigicam operation specifically for
749  * the "camerabin" GStreamer bin.
750  *
751  * Returns: #FALSE if invalid input arguments are received or the
752  * operation fails, #TRUE otherwise.
753  **/
754 static gboolean
755 _g_digicam_camerabin_set_mode (GDigicamManager *manager,
756                                gpointer user_data)
757 {
758     GDigicamCamerabinModeHelper *helper = NULL;
759     GError *error = NULL;
760     GstElement *bin = NULL;
761     gboolean result;
762
763     helper = (GDigicamCamerabinModeHelper *) user_data;
764
765     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting operation mode  ...\n");
766
767     TSTAMP (gst-before-mode-changed);
768
769     /* Get "camerabin" Gstreamer bin  */
770     result = g_digicam_manager_get_gstreamer_bin (manager,
771                                                   &bin,
772                                                   &error);
773
774     /* Check errors */
775     if (!result) {
776         if (NULL != error) {
777             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
778         }
779         goto free;
780     }
781
782
783     /* FIXME: Pending of camerabin integration */
784     switch (helper->mode) {
785     case G_DIGICAM_MODE_STILL:
786         g_object_set (bin, "mode", 0, NULL);
787         break;
788     case G_DIGICAM_MODE_VIDEO:
789         g_object_set (bin, "mode", 1, NULL);
790         break;
791     default:
792         g_assert_not_reached ();
793     }
794
795     TSTAMP (gst-after-mode-changed);
796
797     /* free */
798 free:
799     if (NULL != bin) {
800         gst_object_unref (bin);
801     }
802     if (NULL != error) {
803         g_error_free (error);
804     }
805
806     return result;
807 }
808
809
810 /**
811  * _g_digicam_camerabin_set_flash_mode:
812  * @manager: A #GDigicamManager.
813  * @user_data: A #GDigicamCamerabinFlashModeHelper.
814  *
815  * Implementation of "set_flash_mode" GDigicam operation specifically
816  * for the "camerabin" GStreamer bin.
817  *
818  * Returns: #FALSE if invalid input arguments are received or the
819  * operation fails, #TRUE otherwise.
820  **/
821 static gboolean
822 _g_digicam_camerabin_set_flash_mode (GDigicamManager *manager,
823                                      gpointer user_data)
824 {
825     GDigicamCamerabinFlashModeHelper *helper = NULL;
826     GError *error = NULL;
827     GstElement *bin = NULL;
828     GstFlashMode value;
829     gboolean result;
830
831     helper = (GDigicamCamerabinFlashModeHelper *) user_data;
832
833     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting flash mode  ...\n");
834
835     /* Get "camerabin" Gstreamer bin  */
836     result = g_digicam_manager_get_gstreamer_bin (manager,
837                                                   &bin,
838                                                   &error);
839
840
841     /* Check errors */
842     if (!result) {
843         if (NULL != error) {
844             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
845         }
846         goto free;
847     }
848
849     switch (helper->flash_mode) {
850     case G_DIGICAM_FLASHMODE_AUTO:
851         /* FIXME: the AUTO scene mode is unimplemented in camerabin side.*/
852         value = GST_PHOTOGRAPHY_FLASH_MODE_AUTO;
853         break;
854     case G_DIGICAM_FLASHMODE_OFF:
855         value = GST_PHOTOGRAPHY_FLASH_MODE_OFF;
856         break;
857     case G_DIGICAM_FLASHMODE_ON:
858         value = GST_PHOTOGRAPHY_FLASH_MODE_ON;
859         break;
860     case G_DIGICAM_FLASHMODE_REDEYEREDUCTION:
861         value = GST_PHOTOGRAPHY_FLASH_MODE_RED_EYE;
862         break;
863     default:
864         g_assert_not_reached ();
865     }
866
867     /* Establish new flash mode */
868     result = gst_photography_set_flash_mode (GST_PHOTOGRAPHY (bin),
869                                              value);
870
871     /* free */
872 free:
873     if (NULL != bin) {
874         gst_object_unref (bin);
875     }
876     if (NULL != error) {
877         g_error_free (error);
878     }
879
880     return result;
881 }
882
883
884 /**
885  * _g_digicam_camerabin_set_focus_mode:
886  * @manager: A #GDigicamManager.
887  * @user_data: A #GDigicamCamerabinFocusModeHelper.
888  *
889  * Implementation of "set_focus_mode" GDigicam operation specifically
890  * for the "camerabin" GStreamer bin.
891  *
892  * Returns: #FALSE if invalid input arguments are received or the
893  * operation fails, #TRUE otherwise.
894  **/
895 static gboolean
896 _g_digicam_camerabin_set_focus_mode (GDigicamManager *manager,
897                                      gpointer user_data)
898 {
899     GDigicamCamerabinFocusModeHelper *helper = NULL;
900     GstElement *bin = NULL;
901     GError *error = NULL;
902     gboolean result;
903
904     helper = (GDigicamCamerabinFocusModeHelper *) user_data;
905
906     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting focus mode");
907
908     /* Get "camerabin" Gstreamer bin  */
909     result = g_digicam_manager_get_gstreamer_bin (manager,
910                                                   &bin,
911                                                   &error);
912
913     /* Check errors */
914     if (!result) {
915         if (NULL != error) {
916             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
917         }
918         goto free;
919     }
920
921     /* TODO: Specific implementation to set the focus mode */
922
923     /* free */
924 free:
925     if (NULL != bin) {
926         gst_object_unref (bin);
927     }
928     if (NULL != error) {
929         g_error_free (error);
930     }
931
932     return result;
933 }
934
935
936 /**
937  * _g_digicam_camerabin_set_focus_region_pattern:
938  * @manager: A #GDigicamManager.
939  * @user_data: A #GDigicamCamerabinFocusRegionPatternHelper.
940  *
941  * Implementation of "set_focus_region_pattern" GDigicam operation
942  * specifically for the "camerabin" GStreamer bin.
943  *
944  * Returns: #FALSE if invalid input arguments are received or the
945  * operation fails, #TRUE otherwise.
946  **/
947 static gboolean
948 _g_digicam_camerabin_set_focus_region_pattern (GDigicamManager *manager,
949                                                gpointer user_data)
950 {
951     GDigicamCamerabinFocusRegionPatternHelper *helper = NULL;
952     GstElement *bin = NULL;
953     GError *error = NULL;
954     gboolean result;
955
956     helper = (GDigicamCamerabinFocusRegionPatternHelper *) user_data;
957
958     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting focus region pattern");
959
960     /* Get "camerabin" Gstreamer bin  */
961     result = g_digicam_manager_get_gstreamer_bin (manager,
962                                                   &bin,
963                                                   &error);
964
965     /* Check errors */
966     if (!result) {
967         if (NULL != error) {
968             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
969         }
970         goto free;
971     }
972
973     /* TODO: Specific implementation to set the focus region pattern */
974
975     /* free */
976 free:
977     if (NULL != bin) {
978         gst_object_unref (bin);
979     }
980     if (NULL != error) {
981         g_error_free (error);
982     }
983
984     return result;
985 }
986
987
988 /**
989  * _g_digicam_camerabin_set_exposure_mode:
990  * @manager: A #GDigicamManager.
991  * @user_data: A #GDigicamCamerabinExposureModeHelper.
992  *
993  * Implementation of "set_exposure_mode" GDigicam operation
994  * specifically for the "camerabin" GStreamer bin.
995  *
996  * Returns: #FALSE if invalid input arguments are received or the
997  * operation fails, #TRUE otherwise.
998  **/
999 static gboolean
1000 _g_digicam_camerabin_set_exposure_mode (GDigicamManager *manager,
1001                                         gpointer user_data)
1002 {
1003     GDigicamCamerabinExposureModeHelper *helper = NULL;
1004     GstElement *bin = NULL;
1005     GstSceneMode value;
1006     GDigicamFocusmode focus_mode;
1007     gboolean macro_enabled;
1008     GError *error = NULL;
1009     gboolean result;
1010     GDigicamMode mode;
1011
1012     helper = (GDigicamCamerabinExposureModeHelper *) user_data;
1013
1014     TSTAMP (gst-scene-mode);
1015
1016     /* Get "camerabin" Gstreamer bin  */
1017     result = g_digicam_manager_get_gstreamer_bin (manager,
1018                                                   &bin,
1019                                                   &error);
1020
1021     /* Check errors */
1022     if (!result) {
1023         if (NULL != error) {
1024             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1025         }
1026         goto free;
1027     }
1028
1029     result = g_digicam_manager_get_mode (manager,
1030                                          &mode,
1031                                          &error);
1032
1033     /* Check errors */
1034     if (!result) {
1035         if (NULL != error) {
1036             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1037         }
1038         goto free;
1039     }
1040
1041     if (mode == G_DIGICAM_MODE_VIDEO) {
1042         if (helper->exposure_mode == G_DIGICAM_EXPOSUREMODE_NIGHT) {
1043             value = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
1044         } else {
1045             value = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
1046         }
1047     } else {
1048         switch (helper->exposure_mode) {
1049         case G_DIGICAM_EXPOSUREMODE_AUTO:
1050             if (NULL != error) {
1051                 g_error_free (error);
1052                 error = NULL;
1053             }
1054
1055             result = g_digicam_manager_get_focus_mode (manager,
1056                                                        &focus_mode,
1057                                                        &macro_enabled,
1058                                                        &error);
1059
1060             /* Check errors */
1061             if (!result) {
1062                 if (NULL != error) {
1063                     G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1064                 }
1065                 goto free;
1066             }
1067
1068             if (macro_enabled) {
1069                 value = GST_PHOTOGRAPHY_SCENE_MODE_CLOSEUP;
1070             } else {
1071                 value = GST_PHOTOGRAPHY_SCENE_MODE_AUTO;
1072             }
1073             break;
1074         case G_DIGICAM_EXPOSUREMODE_LANDSCAPE:
1075             value = GST_PHOTOGRAPHY_SCENE_MODE_LANDSCAPE;
1076             break;
1077         case G_DIGICAM_EXPOSUREMODE_NIGHT:
1078             value = GST_PHOTOGRAPHY_SCENE_MODE_NIGHT;
1079             break;
1080         case G_DIGICAM_EXPOSUREMODE_PORTRAIT:
1081             value = GST_PHOTOGRAPHY_SCENE_MODE_PORTRAIT;
1082             break;
1083         case G_DIGICAM_EXPOSUREMODE_SPORTS:
1084             value = GST_PHOTOGRAPHY_SCENE_MODE_SPORT;
1085             break;
1086         default:
1087             g_assert_not_reached ();
1088         }
1089     }
1090
1091     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new scene mode to %i\n",
1092                      value);
1093
1094     TSTAMP (gst-before-scenemode);
1095
1096     result = gst_photography_set_scene_mode (GST_PHOTOGRAPHY (bin),
1097                                              value);
1098
1099     TSTAMP (gst-after-scenemode);
1100
1101     /* free */
1102 free:
1103     if (NULL != bin) {
1104         gst_object_unref (bin);
1105     }
1106     if (NULL != error) {
1107         g_error_free (error);
1108     }
1109
1110     return result;
1111 }
1112
1113
1114 /**
1115  * _g_digicam_camerabin_set_exposure_comp:
1116  * @manager: A #GDigicamManager.
1117  * @user_data: A #GDigicamCamerabinExposureCompHelper.
1118  *
1119  * Implementation of "set_exposure_comp" GDigicam operation
1120  * specifically for the "camerabin" GStreamer bin.
1121  *
1122  * Returns: #FALSE if invalid input arguments are received or the
1123  * operation fails, #TRUE otherwise.
1124  **/
1125 static gboolean
1126 _g_digicam_camerabin_set_exposure_comp (GDigicamManager *manager,
1127                                         gpointer user_data)
1128 {
1129     GDigicamCamerabinExposureCompHelper *helper = NULL;
1130     GstElement *bin = NULL;
1131     GError *error = NULL;
1132     gboolean result;
1133
1134     helper = (GDigicamCamerabinExposureCompHelper *) user_data;
1135
1136     /* Get "camerabin" Gstreamer bin  */
1137     result = g_digicam_manager_get_gstreamer_bin (manager,
1138                                                   &bin,
1139                                                   &error);
1140
1141     /* Check errors */
1142     if (!result) {
1143         if (NULL != error) {
1144             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1145         }
1146         goto free;
1147     }
1148
1149     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new exposure value to %f\n",
1150                      helper->exposure_comp);
1151
1152     result = gst_photography_set_ev_compensation (GST_PHOTOGRAPHY (bin),
1153                                                   helper->exposure_comp);
1154
1155     /* free */
1156 free:
1157     if (NULL != bin) {
1158         gst_object_unref (bin);
1159     }
1160     if (NULL != error) {
1161         g_error_free (error);
1162     }
1163
1164     return result;
1165 }
1166
1167
1168 /**
1169  * _g_digicam_camerabin_set_iso_sensitivity_mode:
1170  * @manager: A #GDigicamManager.
1171  * @user_data: A #GDigicamCamerabinIsoSensitivityHelper.
1172  *
1173  * Implementation of "set_iso_sensitivity" GDigicam operation
1174  * specifically for the "camerabin" GStreamer bin.
1175  *
1176  * Returns: #FALSE if invalid input arguments are received or the
1177  * operation fails, #TRUE otherwise.
1178  **/
1179 static gboolean
1180 _g_digicam_camerabin_set_iso_sensitivity_mode (GDigicamManager *manager,
1181                                                gpointer user_data)
1182 {
1183     GDigicamCamerabinIsoSensitivityHelper *helper = NULL;
1184     GstElement *bin = NULL;
1185     GError *error = NULL;
1186     gboolean result;
1187
1188     helper = (GDigicamCamerabinIsoSensitivityHelper *) user_data;
1189
1190     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new iso value to %i\n",
1191                      helper->iso_value);
1192
1193     /* Get "camerabin" Gstreamer bin  */
1194     result = g_digicam_manager_get_gstreamer_bin (manager,
1195                                                   &bin,
1196                                                   &error);
1197
1198     /* Check errors */
1199     if (!result) {
1200         if (NULL != error) {
1201             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1202         }
1203         goto free;
1204     }
1205
1206     /* Establish new iso value */
1207     /* FIXME: what about the auto iso value ? */
1208     result = gst_photography_set_iso_speed (GST_PHOTOGRAPHY (bin),
1209                                             helper->iso_value);
1210     /* free */
1211 free:
1212     if (NULL != bin) {
1213         gst_object_unref (bin);
1214     }
1215     if (NULL != error) {
1216         g_error_free (error);
1217     }
1218
1219     return result;
1220 }
1221
1222
1223 /**
1224  * _g_digicam_camerabin_set_white_balance_mode:
1225  * @manager: A #GDigicamManager.
1226  * @user_data: A #GDigicamCamerabinWhitebalanceModeHelper.
1227  *
1228  * Implementation of "set_white_balance_mode" GDigicam operation
1229  * specifically for the "camerabin" GStreamer bin.
1230  *
1231  * Returns: #FALSE if invalid input arguments are received or the
1232  * operation fails, #TRUE otherwise.
1233  **/
1234 static gboolean
1235 _g_digicam_camerabin_set_white_balance_mode (GDigicamManager *manager,
1236                                              gpointer user_data)
1237 {
1238     GDigicamCamerabinWhitebalanceModeHelper *helper = NULL;
1239     GstElement *bin = NULL;
1240     GError *error = NULL;
1241     GstWhiteBalanceMode value;
1242     gboolean result;
1243
1244     helper = (GDigicamCamerabinWhitebalanceModeHelper *) user_data;
1245
1246     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new white balance "
1247                      "value to %i\n",
1248                      helper->wb_mode);
1249
1250     /* Get "camerabin" Gstreamer bin  */
1251     result = g_digicam_manager_get_gstreamer_bin (manager,
1252                                                   &bin,
1253                                                   &error);
1254
1255     /* Check errors */
1256     if (!result) {
1257         if (NULL != error) {
1258             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1259         }
1260         goto free;
1261     }
1262
1263     /* Mapping values */
1264     switch (helper->wb_mode) {
1265     case G_DIGICAM_WHITEBALANCEMODE_AUTO:
1266         value = GST_PHOTOGRAPHY_WB_MODE_AUTO;
1267         break;
1268     case G_DIGICAM_WHITEBALANCEMODE_SUNLIGHT:
1269         value = GST_PHOTOGRAPHY_WB_MODE_DAYLIGHT;
1270         break;
1271     case G_DIGICAM_WHITEBALANCEMODE_CLOUDY:
1272         value = GST_PHOTOGRAPHY_WB_MODE_CLOUDY;
1273         break;
1274     case G_DIGICAM_WHITEBALANCEMODE_TUNGSTEN:
1275         value = GST_PHOTOGRAPHY_WB_MODE_TUNGSTEN;
1276         break;
1277     case G_DIGICAM_WHITEBALANCEMODE_FLUORESCENT:
1278         value = GST_PHOTOGRAPHY_WB_MODE_FLUORESCENT;
1279         break;
1280     case G_DIGICAM_WHITEBALANCEMODE_FLASH:
1281         value = GST_PHOTOGRAPHY_WB_MODE_SUNSET;
1282         break;
1283     default:
1284         g_assert_not_reached ();
1285     }
1286
1287
1288     /* Establish new white balance value  */
1289     result = gst_photography_set_white_balance_mode (GST_PHOTOGRAPHY (bin),
1290                                                      value);
1291
1292     /* free */
1293 free:
1294     if (NULL != bin) {
1295         gst_object_unref (bin);
1296     }
1297     if (NULL != error) {
1298         g_error_free (error);
1299     }
1300
1301     return result;
1302 }
1303
1304
1305 /**
1306  * _g_digicam_camerabin_set_quality:
1307  * @manager: A #GDigicamManager.
1308  * @user_data: A #GDigicamCamerabinQualityHelper.
1309  *
1310  * Implementation of "set_quality" GDigicam operation specifically for
1311  * the "camerabin" GStreamer bin.
1312  *
1313  * Returns: #FALSE if invalid input arguments are received or the
1314  * operation fails, #TRUE otherwise.
1315  **/
1316 static gboolean
1317 _g_digicam_camerabin_set_quality (GDigicamManager *manager,
1318                                   gpointer user_data)
1319 {
1320     GstElement *bin = NULL;
1321     GDigicamCamerabinQualityHelper *helper = NULL;
1322     GError *error = NULL;
1323     gboolean result;
1324
1325     helper = (GDigicamCamerabinQualityHelper *) user_data;
1326
1327     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new quality \n");
1328
1329     /* Get "camerabin" Gstreamer bin  */
1330     result = g_digicam_manager_get_gstreamer_bin (manager,
1331                                                   &bin,
1332                                                   &error);
1333
1334     /* Check errors */
1335     if (!result) {
1336         if (NULL != error) {
1337             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1338         }
1339         goto free;
1340     }
1341
1342     /* FIXME: once camera bin has support for quality, use proper API. */
1343     /* Establish new quality value  */
1344 /*     result = gst_photography_set_quality (GST_PHOTOGRAPHY (bin), */
1345 /*                                           value); */
1346
1347     /* free */
1348 free:
1349     if (NULL != bin) {
1350         gst_object_unref (bin);
1351     }
1352     if (NULL != error) {
1353         g_error_free (error);
1354     }
1355
1356     return result;
1357 }
1358
1359
1360 /**
1361  * _g_digicam_camerabin_set_aspect_ratio_resolution:
1362  * @manager: A #GDigicamManager.
1363  * @user_data: A #GDigicamCamerabinAspectRatioResolutionHelper.
1364  *
1365  * Implementation of "set_resolution" and "set_aspect_ratio" GDigicam
1366  * operations specifically for the "camerabin" GStreamer bin.
1367  *
1368  * Returns: #FALSE if invalid input arguments are received or the
1369  * operation fails, #TRUE otherwise.
1370  **/
1371 static gboolean
1372 _g_digicam_camerabin_set_aspect_ratio_resolution (GDigicamManager *manager,
1373                                                   gpointer user_data)
1374 {
1375     GDigicamCamerabinAspectRatioResolutionHelper *helper = NULL;
1376     GstElement *bin = NULL;
1377     GstCaps *preview_caps = NULL;
1378     GDigicamMode mode;
1379     GError *error = NULL;
1380     gint vf_w, vf_h;
1381     gint res_w, res_h;
1382     gint fps_n, fps_d;
1383     gboolean enabled;
1384     gboolean result;
1385
1386     helper = (GDigicamCamerabinAspectRatioResolutionHelper *) user_data;
1387
1388     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new aspect ratio "
1389                      "and resolution \n");
1390
1391     TSTAMP (gst-resolution);
1392
1393     /* Get "camerabin" Gstreamer bin  */
1394     result = g_digicam_manager_get_gstreamer_bin (manager,
1395                                                   &bin,
1396                                                   &error);
1397
1398     /* Check errors */
1399     if (!result) {
1400         if (NULL != error) {
1401             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1402         }
1403         goto free;
1404     }
1405
1406     /* Get mode to set specific resolution and aspect ratio*/
1407     result = g_digicam_manager_get_mode (manager,
1408                                          &mode,
1409                                          &error);
1410
1411     /* Check errors */
1412     if (!result) {
1413         if (NULL != error) {
1414             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1415         }
1416         goto free;
1417     }
1418
1419
1420     TSTAMP (gst-before-res-changed);
1421
1422     /* Get resolution specific values depending on the camera mode */
1423     _get_aspect_ratio_and_resolution (mode,
1424                                       helper->aspect_ratio,
1425                                       helper->resolution,
1426                                       &vf_w, &vf_h,
1427                                       &res_w, &res_h,
1428                                       &fps_n, &fps_d);
1429
1430     /* Set Image Capturing settings  */
1431     if (G_DIGICAM_MODE_STILL == mode) {
1432         G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting capture resolution "
1433                          "to %dx%d\n", res_w, res_h);
1434
1435         /* Capture resolution */
1436         g_signal_emit_by_name (bin,
1437                                "user-image-res",
1438                                res_w, res_h,
1439                                0);
1440     }
1441
1442     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new recording/viewfinder "
1443                      "resolution and fps: %dx%d at %d/%d fps \n",
1444                      vf_w, vf_h, fps_n, fps_d);
1445
1446     /* Sete Viewfinder and Recording settings */
1447     g_signal_emit_by_name (bin,
1448                            "user-res-fps",
1449                            vf_w, vf_h,
1450                            fps_n, fps_d,
1451                            0);
1452
1453     /* Preview size will be the same as viewfinder size */
1454     g_digicam_manager_preview_enabled (manager, &enabled, NULL);
1455     if (enabled) {
1456         preview_caps = _new_preview_caps (vf_w, vf_h);
1457         g_object_set (G_OBJECT (bin),
1458                       "preview-caps", preview_caps,
1459                       NULL);
1460     }
1461
1462
1463     TSTAMP (gst-after-res-changed);
1464
1465     /* free */
1466 free:
1467     if (NULL != bin) {
1468         gst_object_unref (bin);
1469     }
1470     if (NULL != preview_caps) {
1471         gst_caps_unref (preview_caps);
1472     }
1473     if (NULL != error) {
1474         g_error_free (error);
1475     }
1476
1477     return result;
1478 }
1479
1480
1481 /**
1482  * _g_digicam_camerabin_set_locks:
1483  * @manager: A #GDigicamManager.
1484  * @user_data: A #GDigicamCamerabinLocksHelper helper data
1485  * structure.
1486  *
1487  * Implementation of "set_focus_mode" GDigicam operation
1488  * specifically for the "camerabin" GStreamer bin.
1489  *
1490  * Returns: FALSE if invalid input arguments are received or
1491  * the operation fails, it returns TRUE otherwise.
1492  **/
1493 static gboolean
1494 _g_digicam_camerabin_set_locks (GDigicamManager *manager,
1495                                 gpointer user_data)
1496 {
1497     GDigicamCamerabinLocksHelper *helper = NULL;
1498     GstElement *bin = NULL;
1499     GError *error = NULL;
1500     gboolean result;
1501
1502     helper = (GDigicamCamerabinLocksHelper *) user_data;
1503
1504     /* Get "camerabin" Gstreamer bin  */
1505     result = g_digicam_manager_get_gstreamer_bin (manager,
1506                                                   &bin,
1507                                                   &error);
1508
1509     /* Check errors */
1510     if (!result) {
1511         if (NULL != error) {
1512             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1513         }
1514         goto free;
1515     }
1516
1517     if (helper->locks & G_DIGICAM_LOCK_AUTOFOCUS) {
1518         TSTAMP (before-gst-af);
1519         G_DIGICAM_DEBUG ("GDigicamCamerabin: Emit autofocus to camerabin\n");
1520         gst_photography_set_autofocus (GST_PHOTOGRAPHY (bin), TRUE);
1521     } else {
1522         G_DIGICAM_DEBUG ("GDigicamCamerabin: Stop autofocus to camerabin\n");
1523         gst_photography_set_autofocus (GST_PHOTOGRAPHY (bin), FALSE);
1524     }
1525
1526     /* free */
1527 free:
1528     if (NULL != bin) {
1529         gst_object_unref (bin);
1530     }
1531     if (NULL != error) {
1532         g_error_free (error);
1533     }
1534
1535     return result;
1536 }
1537
1538
1539 /**
1540  * _g_digicam_camerabin_set_zoom:
1541  * @manager: A #GDigicamManager.
1542  * @user_data: A #GDigicamCamerabinZoomHelper.
1543  *
1544  * Implementation of "set_zoom" GDigicam operation specifically
1545  * for the "camerabin" GStreamer bin.
1546  *
1547  * Returns: #FALSE if invalid input arguments are received or the
1548  * operation fails, #TRUE otherwise.
1549  **/
1550 static gboolean
1551 _g_digicam_camerabin_set_zoom (GDigicamManager *manager,
1552                                gpointer user_data)
1553 {
1554     GDigicamCamerabinZoomHelper *helper = NULL;
1555     GstElement *bin = NULL;
1556     GError *error = NULL;
1557     gint value;
1558     gboolean result;
1559
1560     helper = (GDigicamCamerabinZoomHelper *) user_data;
1561
1562     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new zoom value to %f\n",
1563                      helper->value);
1564
1565     /* Get "camerabin" Gstreamer bin  */
1566     result = g_digicam_manager_get_gstreamer_bin (manager,
1567                                                   &bin,
1568                                                   &error);
1569
1570     /* Check errors */
1571     if (!result) {
1572         if (NULL != error) {
1573             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1574         }
1575         goto free;
1576     }
1577
1578     /* Establish new zoom value */
1579     /* FIXME: What about digital zoom */
1580     value = 100 * helper->value;
1581     g_object_set (bin, "zoom", value, NULL);
1582
1583     /* free */
1584 free:
1585     if (NULL != bin) {
1586         gst_object_unref (bin);
1587     }
1588     if (NULL != error) {
1589         g_error_free (error);
1590     }
1591
1592     return result;
1593 }
1594
1595
1596 /**
1597  * _g_digicam_camerabin_set_audio:
1598  * @manager: A #GDigicamManager.
1599  * @user_data: A #GDigicamCamerabinVideoHelper.
1600  *
1601  * Implementation of "set_audio" GDigicam operation specifically for
1602  * the "camerabin" GStreamer bin.
1603  *
1604  * Returns: #FALSE if invalid input arguments are received or the
1605  * operation fails, #TRUE otherwise.
1606  **/
1607 static gboolean
1608 _g_digicam_camerabin_set_audio (GDigicamManager *manager,
1609                                 gpointer user_data)
1610 {
1611     GDigicamCamerabinVideoHelper *helper = NULL;
1612     GstElement *bin = NULL;
1613     gboolean audio_mute;
1614     GError *error = NULL;
1615     gboolean result;
1616
1617     helper = (GDigicamCamerabinVideoHelper *) user_data;
1618
1619     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new mute value to %d\n",
1620                      helper->audio);
1621
1622     /* Get "camerabin" Gstreamer bin  */
1623     result = g_digicam_manager_get_gstreamer_bin (manager,
1624                                                   &bin,
1625                                                   &error);
1626
1627     /* Check errors */
1628     if (!result) {
1629         if (NULL != error) {
1630             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1631         }
1632         goto free;
1633     }
1634
1635     /* Establish new mute value */
1636     if (helper->audio & G_DIGICAM_AUDIO_RECORDOFF) {
1637         audio_mute = TRUE;
1638     } else {
1639         audio_mute = FALSE;
1640     }
1641
1642     g_object_set (bin, "mute", audio_mute, NULL);
1643
1644     /* free */
1645 free:
1646     if (NULL != bin) {
1647         gst_object_unref (bin);
1648     }
1649     if (NULL != error) {
1650         g_error_free (error);
1651     }
1652
1653     return result;
1654 }
1655
1656
1657
1658 /**
1659  * _g_digicam_camerabin_set_preview_mode:
1660  * @manager: A #GDigicamManager.
1661  * @user_data: A #GDigicamCamerabinAspectRatioResolutionHelper.
1662  *
1663  * Implementation of "set_preview_mode" GDigicam operation
1664  * specifically for the "camerabin" GStreamer bin.
1665  *
1666  * Returns: #FALSE if invalid input arguments are received or the
1667  * operation fails, #TRUE otherwise.
1668  **/
1669 static gboolean
1670 _g_digicam_camerabin_set_preview_mode (GDigicamManager *manager,
1671                                        gpointer user_data)
1672 {
1673     GDigicamCamerabinPreviewHelper *helper = NULL;
1674     GstElement *bin = NULL;
1675     GstCaps *caps = NULL;
1676     GError *error = NULL;
1677     GDigicamMode mode;
1678     GDigicamAspectratio ar;
1679     GDigicamResolution res;
1680     gint vf_w, vf_h;
1681     gint res_w, res_h;
1682     gint fps_n, fps_d;
1683     gboolean result;
1684
1685     helper = (GDigicamCamerabinPreviewHelper *) user_data;
1686
1687     G_DIGICAM_DEBUG ("GDigicamCamerabin: Setting new preview value to %d\n",
1688                      helper->mode);
1689
1690     /* Get "camerabin" Gstreamer bin  */
1691     result = g_digicam_manager_get_gstreamer_bin (manager,
1692                                                   &bin,
1693                                                   &error);
1694     /* Check errors */
1695     if (!result) {
1696         if (NULL != error) {
1697             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1698         }
1699         goto free;
1700     }
1701
1702     /* Get operation mode */
1703     result = g_digicam_manager_get_mode (manager,
1704                                          &mode,
1705                                          &error);
1706     /* Check errors */
1707     if (!result) {
1708         if (NULL != error) {
1709             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1710         }
1711         goto free;
1712     }
1713
1714     /* Get resoluton */
1715     result = g_digicam_manager_get_resolution (manager, &res, &error);
1716
1717     /* Check errors */
1718     if (!result) {
1719         if (NULL != error) {
1720             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1721         }
1722         goto free;
1723     }
1724
1725     /* Get aspect ratio  */
1726     result = g_digicam_manager_get_aspect_ratio (manager, &ar, &error);
1727
1728     /* Check errors */
1729     if (!result) {
1730         if (NULL != error) {
1731             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1732         }
1733         goto free;
1734     }
1735
1736     /* Get resolution specific values depending on the camera mode */
1737     _get_aspect_ratio_and_resolution (mode,
1738                                       ar, res,
1739                                       &vf_w, &vf_h,
1740                                       &res_w, &res_h,
1741                                       &fps_n, &fps_d);
1742
1743     /* Establish new preview mode value */
1744     if (helper->mode & G_DIGICAM_PREVIEW_ON) {
1745         caps = _new_preview_caps (vf_w, vf_h);
1746         g_object_set (G_OBJECT (bin),
1747                       "preview-caps", caps,
1748                       NULL);
1749     } else if (helper->mode & G_DIGICAM_PREVIEW_OFF) {
1750         g_object_set (G_OBJECT (bin),
1751                       "preview-caps", NULL,
1752                       NULL);
1753     } else {
1754         G_DIGICAM_ERR ("GDigicamCamerabin: invalid preview mode %d received.",
1755                        helper->mode);
1756         goto free;
1757     }
1758
1759     /* free */
1760 free:
1761     if (NULL != bin) {
1762         gst_object_unref (bin);
1763     }
1764     if (NULL != caps) {
1765         gst_caps_unref (caps);
1766     }
1767     if (NULL != error) {
1768         g_error_free (error);
1769     }
1770
1771     return result;
1772 }
1773
1774 /**
1775  * _g_digicam_camerabin_get_still_picture:
1776  * @manager: A #GDigicamManager.
1777  * @user_data: A #GDigicamCamerabinPictureHelper.
1778  *
1779  * Implementation of "get_still_picture" GDigicam operation
1780  * specifically for the "camerabin" GStreamer bin.
1781  *
1782  * Returns: #FALSE if invalid input arguments are received or the
1783  * operation fails, #TRUE otherwise.
1784  **/
1785 static gboolean
1786 _g_digicam_camerabin_get_still_picture (GDigicamManager *manager,
1787                                         gpointer user_data)
1788 {
1789     GDigicamCamerabinPictureHelper *helper = NULL;
1790     GstElement *bin = NULL;
1791     GError *error = NULL;
1792     gboolean result;
1793
1794     helper = (GDigicamCamerabinPictureHelper *) user_data;
1795
1796     G_DIGICAM_DEBUG ("GDigicamCamerabin: Capturing still picture ...");
1797
1798     /* Get "camerabin" Gstreamer bin  */
1799     result = g_digicam_manager_get_gstreamer_bin (manager,
1800                                                   &bin,
1801                                                   &error);
1802
1803     /* Check errors */
1804     if (!result) {
1805         if (NULL != error) {
1806             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1807         }
1808         goto free;
1809     }
1810
1811
1812     /* Set application domain metadata */
1813     _g_digicam_camerabin_set_picture_metadata (bin, helper->metadata);
1814
1815
1816     /* take picture */
1817     g_object_set (bin, "filename", helper->file_path, NULL);
1818     TSTAMP (before-gst-capture);
1819     g_signal_emit_by_name (bin, "user-start", 0);
1820     g_signal_emit_by_name (bin, "user-stop", 0);
1821     TSTAMP (after-gst-capture);
1822
1823     /* free */
1824 free:
1825     if (NULL != bin) {
1826         gst_object_unref (bin);
1827     }
1828     if (NULL != error) {
1829         g_error_free (error);
1830     }
1831
1832     return result;
1833 }
1834
1835
1836 /**
1837  * _gdigicam_camerabin_start_recording_video:
1838  * @manager: A #GDigicamManager.
1839  * @user_data: A #GDigicamCamerabinVideoHelper.
1840  *
1841  * Implementation of "start_recording_video" GDigicam operation
1842  * specifically for the "camerabin" GStreamer bin.
1843  *
1844  * Returns: #FALSE if invalid input arguments are received or the
1845  * operation fails, #TRUE otherwise.
1846  **/
1847 static gboolean
1848 _g_digicam_camerabin_start_recording_video (GDigicamManager *manager,
1849                                             gpointer user_data)
1850 {
1851     GDigicamCamerabinVideoHelper *helper = NULL;
1852     GstElement *bin = NULL;
1853     GError *error = NULL;
1854     gboolean result;
1855
1856     helper = (GDigicamCamerabinVideoHelper *) user_data;
1857
1858     G_DIGICAM_DEBUG ("GDigicamCamerabin: Capturing video ...");
1859
1860     /* Get "camerabin" Gstreamer bin  */
1861     result = g_digicam_manager_get_gstreamer_bin (manager,
1862                                                   &bin,
1863                                                   &error);
1864
1865     /* Check errors */
1866     if (!result) {
1867         if (NULL != error) {
1868             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1869         }
1870         goto free;
1871     }
1872
1873
1874     /* Set application domain metadata */
1875     _g_digicam_camerabin_set_video_metadata (bin, helper->metadata);
1876
1877
1878     /* Start recording mode */
1879     g_object_set (bin, "filename", helper->file_path, NULL);
1880     TSTAMP (before-gst-video-capture);
1881     g_signal_emit_by_name(bin, "user-start", 0);
1882     TSTAMP (after-gst-video-capture);
1883
1884     /* free */
1885 free:
1886     if (NULL != bin) {
1887         gst_object_unref (bin);
1888     }
1889     if (NULL != error) {
1890         g_error_free (error);
1891     }
1892
1893     return TRUE;
1894 }
1895
1896
1897 /**
1898  * _g_digicam_camerabin_pause_recording_video:
1899  * @manager: A #GDigicamManager.
1900  * @user_data: A #GDigicamCamerabinVideoHelper.
1901  *
1902  * Implementation of "pause_recording_video" GDigicam operation
1903  * specifically for the "camerabin" GStreamer bin.
1904  *
1905  * Returns: #FALSE if invalid input arguments are received or the
1906  * operation fails, #TRUE otherwise.
1907  **/
1908 static gboolean
1909 _g_digicam_camerabin_pause_recording_video (GDigicamManager *manager,
1910                                             gpointer user_data)
1911 {
1912     GDigicamCamerabinVideoHelper *helper = NULL;
1913     GstElement *bin = NULL;
1914     GError *error = NULL;
1915     gboolean result;
1916
1917     helper = (GDigicamCamerabinVideoHelper *) user_data;
1918
1919     G_DIGICAM_DEBUG ("GDigicamCamerabin: Recording operation paused \n");
1920
1921     /* Get "camerabin" Gstreamer bin  */
1922     result = g_digicam_manager_get_gstreamer_bin (manager,
1923                                                   &bin,
1924                                                   &error);
1925
1926     /* Check errors */
1927     if (!result) {
1928         if (NULL != error) {
1929             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1930         }
1931         goto free;
1932     }
1933
1934     /* Pause/Resume recording mode */
1935     if (helper->resume) {
1936         g_signal_emit_by_name (bin, "user-start", 0);
1937     } else {
1938         g_signal_emit_by_name (bin, "user-pause", 0);
1939     }
1940
1941     /* free */
1942 free:
1943     if (NULL != bin) {
1944         gst_object_unref (bin);
1945     }
1946     if (NULL != error) {
1947         g_error_free (error);
1948     }
1949
1950     return result;
1951 }
1952
1953
1954 /**
1955  * _g_digicam_camerabin_finish_recording_video:
1956  * @manager: A #GDigicamManager.
1957  * @user_data: A #GDigicamCamerabinVideoHelper.
1958  *
1959  * Implementation of "finish_recording_video" GDigicam operation
1960  * specifically for the "camerabin" GStreamer bin.
1961  *
1962  * Returns: #FALSE if invalid input arguments are received or the
1963  * operation fails, #TRUE otherwise.
1964  **/
1965 static gboolean
1966 _g_digicam_camerabin_finish_recording_video (GDigicamManager *manager,
1967                                              gpointer user_data)
1968 {
1969     GDigicamCamerabinVideoHelper *helper = NULL;
1970     GstElement *bin = NULL;
1971     GError *error = NULL;
1972     gboolean result;
1973
1974     helper = (GDigicamCamerabinVideoHelper *) user_data;
1975
1976     G_DIGICAM_DEBUG ("GDigicamCamerabin: Recording operation stopped \n");
1977
1978     /* Get "camerabin" Gstreamer bin  */
1979     result = g_digicam_manager_get_gstreamer_bin (manager,
1980                                                   &bin,
1981                                                   &error);
1982
1983     /* Check errors */
1984     if (!result) {
1985         if (NULL != error) {
1986             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
1987         }
1988         goto free;
1989     }
1990
1991     /* Stopping recording mode */
1992     g_signal_emit_by_name (bin, "user-stop", 0);
1993     TSTAMP (after-gst-capture-stop);
1994
1995     /* free */
1996 free:
1997     if (NULL != bin) {
1998         gst_object_unref (bin);
1999     }
2000     if (NULL != error) {
2001         g_error_free (error);
2002     }
2003
2004     return result;
2005 }
2006
2007
2008 /**
2009  * _g_digicam_camerabin_set_picture_metadata:
2010  * @gst_camera_bin: A camerabin #GstElement.
2011  * @metadata: A #GDigicamCamerabinMetadata.
2012  *
2013  * Sets the metadata in pictures.
2014  **/
2015 static void
2016 _g_digicam_camerabin_set_picture_metadata (GstElement *gst_camera_bin,
2017                                            const GDigicamCamerabinMetadata *metadata)
2018 {
2019     /* for more information about image metadata tags, see:
2020      * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/tests/icles/metadata_editor.c
2021      * and for the mapping:
2022      * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/ext/metadata/metadata_mapping.htm?view=co
2023      */
2024
2025     /* TODO: These location tags in quotes have to be in sync with
2026      * other tags after GStreamer's headers are updated.
2027      * See NB#125831 */
2028
2029     GstTagSetter *setter = NULL;
2030     GstTagList *list = NULL;
2031     GTimeVal time = { 0,0 };
2032     gchar *date_str = NULL;
2033
2034     g_return_if_fail (GST_IS_ELEMENT (gst_camera_bin));
2035     g_return_if_fail (NULL != metadata);
2036     setter = GST_TAG_SETTER (gst_camera_bin);
2037
2038     /* Modified time */
2039     g_get_current_time(&time);
2040     date_str = g_time_val_to_iso8601 (&time); /* this is UTC */
2041
2042     ULOG_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_set_picture_metadata: "
2043                 "Writing Picture Metadata: \n"
2044                 "\n\tdate: %s"
2045                 "\n\tmake: %s"
2046                 "\n\tmodel: %s"
2047                 "\n\tauthor: %s"
2048                 "\n\tcountry: %s"
2049                 "\n\tcity: %s"
2050                 "\n\tsuburb: %s"
2051                 "\n\taltitude: %f"
2052                 "\n\tlatitude: %f"
2053                 "\n\tlongtitude: %f"
2054                 "\n\torientation: %d",
2055                 date_str, metadata->make,
2056                 metadata->model,
2057                 metadata->author,
2058                 metadata->country_name,
2059                 metadata->city_name,
2060                 metadata->suburb_name,
2061                 metadata->altitude,
2062                 metadata->latitude,
2063                 metadata->longitude,
2064                 metadata->orientation);
2065
2066     /* Creating the tag list with the mandatory tags. */
2067     list = gst_tag_list_new ();
2068     gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2069                       GST_TAG_DATE_TIME_ORIGINAL, date_str,
2070                       GST_TAG_DATE_TIME_MODIFIED, date_str,
2071                       GST_TAG_DEVICE_MAKE, metadata->make,
2072                       GST_TAG_DEVICE_MODEL, metadata->model,
2073                       GST_TAG_CAPTURE_ORIENTATION, metadata->orientation,
2074                       NULL);
2075
2076     /* Adding coordinates, just if set. */
2077     if (G_MAXDOUBLE != metadata->latitude &&
2078         G_MAXDOUBLE != metadata->longitude) {
2079         gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2080                           GST_TAG_GEO_LOCATION_LATITUDE, metadata->latitude,
2081                           GST_TAG_GEO_LOCATION_LONGITUDE, metadata->longitude,
2082                           NULL);
2083         if (G_MAXDOUBLE != metadata->altitude) {
2084             gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2085                               GST_TAG_GEO_LOCATION_ELEVATION, metadata->altitude,
2086                               NULL);
2087         }
2088     }
2089
2090     /* Adding optional metadata tags. */
2091     if (NULL != metadata->author) {
2092         gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2093                           GST_TAG_COMPOSER, metadata->author,
2094                           NULL);
2095     }
2096
2097     /* We should have all the geotags. */
2098     if (NULL != metadata->country_name) {
2099         gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2100                           GST_TAG_GEO_LOCATION_COUNTRY, metadata->country_name,
2101                           NULL);
2102         if (NULL != metadata->city_name) {
2103                 gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2104                                   GST_TAG_GEO_LOCATION_CITY, metadata->city_name,
2105                                   NULL);
2106             }
2107         if (NULL != metadata->suburb_name) {
2108             gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2109                               GST_TAG_GEO_LOCATION_SUBLOCATION, metadata->suburb_name,
2110                               NULL);
2111         }
2112     }
2113
2114     /* Set metadata tags. */
2115     gst_tag_setter_merge_tags (setter, list,
2116                                GST_TAG_MERGE_REPLACE_ALL);
2117
2118     /* Free. */
2119     gst_tag_list_free (list);
2120     g_free (date_str);
2121 }
2122
2123
2124 /**
2125  * _g_digicam_camerabin_set_video_metadata:
2126  * @gst_camera_bin: A camerabin #GstElement.
2127  * @metadata: A #GDigicamCamerabinMetadata.
2128  *
2129  * Sets the metadata in videos.
2130  **/
2131 static void
2132 _g_digicam_camerabin_set_video_metadata (GstElement *gst_camera_bin,
2133                                          const GDigicamCamerabinMetadata *metadata)
2134 {
2135     /* for more information about image metadata tags, see:
2136      * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/tests/icles/metadata_editor.c
2137      * and for the mapping:
2138      * http://webcvs.freedesktop.org/gstreamer/gst-plugins-bad/ext/metadata/metadata_mapping.htm?view=co
2139      */
2140
2141     /* TODO: These location tags in quotes have to be in sync with
2142      * other tags after GStreamer's headers are updated.
2143      * See NB#125831 */
2144
2145     GstTagSetter *setter = NULL;
2146     GstTagList *list = NULL;
2147     gchar *geo_name = NULL;
2148     gchar *tmp = NULL;
2149     /*we should not set Date if hantro is used as its automatically set by it.
2150     If we set date and time, hantro extract only year from it and erase the automatic date */
2151     /*TODO: Verfiy aumatice date set. */
2152     /*GTimeVal time = { 0,0 };
2153     gchar *date_str = NULL;*/
2154
2155     g_return_if_fail (GST_IS_ELEMENT (gst_camera_bin));
2156     g_return_if_fail (NULL != metadata);
2157     setter = GST_TAG_SETTER (gst_camera_bin);
2158
2159     /* Modified time */
2160     /*g_get_current_time(&time);
2161     date_str = g_time_val_to_iso8601 (&time);*/ /* this is UTC */
2162
2163     ULOG_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_set_video_metadata: "
2164                 "Writing Video Metadata: \n"
2165                 "\n\tauthor: %s"
2166                 "\n\tcountry: %s"
2167                 "\n\tcity: %s"
2168                 "\n\tsuburb: %s"
2169                 "\n\taltitude: %f"
2170                 "\n\tlatitude: %f"
2171                 "\n\tlongtitude: %f",
2172                 metadata->author,
2173                 metadata->country_name,
2174                 metadata->city_name,
2175                 metadata->suburb_name,
2176                 metadata->altitude,
2177                 metadata->latitude,
2178                 metadata->longitude);
2179
2180     /* Creating the tag list with the mandatory tags. */
2181     list = gst_tag_list_new ();
2182     gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2183                       GST_TAG_CLASSIFICATION, metadata->unique_id,
2184                       NULL);
2185
2186     /* Adding coordinates, just if set. */
2187     if (G_MAXDOUBLE != metadata->latitude &&
2188         G_MAXDOUBLE != metadata->longitude) {
2189         gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2190                           GST_TAG_GEO_LOCATION_LATITUDE, metadata->latitude,
2191                           GST_TAG_GEO_LOCATION_LONGITUDE, metadata->longitude,
2192                           NULL);
2193         if (G_MAXDOUBLE != metadata->altitude) {
2194             gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2195                               GST_TAG_GEO_LOCATION_ELEVATION, metadata->altitude,
2196                               NULL);
2197         }
2198     }
2199
2200     /* Adding optional metadata tags. */
2201     if (NULL != metadata->author) {
2202         gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2203                           GST_TAG_ARTIST, metadata->author,
2204                           NULL);
2205     }
2206
2207     /* We should have all the geotags. */
2208     if (NULL != metadata->country_name) {
2209         geo_name = g_strdup (metadata->country_name);
2210         if (NULL != metadata->city_name) {
2211             tmp = g_strconcat (geo_name,
2212                                ",",
2213                                metadata->city_name,
2214                                NULL);
2215             g_free (geo_name);
2216             geo_name = tmp;
2217             tmp = NULL;
2218         }
2219         if (NULL != metadata->suburb_name) {
2220             tmp = g_strconcat (geo_name,
2221                                ",",
2222                                metadata->suburb_name,
2223                                NULL);
2224             g_free (geo_name);
2225             geo_name = tmp;
2226             tmp = NULL;
2227         }
2228
2229         gst_tag_list_add (list, GST_TAG_MERGE_APPEND,
2230                           GST_TAG_GEO_LOCATION_NAME, geo_name,
2231                           NULL);
2232     }
2233
2234     /* Set metadata tags. */
2235     gst_tag_setter_merge_tags (setter, list,
2236                                GST_TAG_MERGE_REPLACE_ALL);
2237
2238     /* Free. */
2239     gst_tag_list_free (list);
2240     g_free (geo_name);
2241     g_free (tmp);
2242 }
2243
2244
2245 /**
2246  * _g_digicam_camerabin_handle_bus_message:
2247  * @manager: A #GDigicamManager.
2248  * @user_data: A #GstMessage.
2249  *
2250  * Function to handle custom gstreamer bus messages.
2251  *
2252  * Returns: #FALSE if invalid input arguments are received or the
2253  * operation fails, #TRUE otherwise.
2254  **/
2255 static gboolean
2256 _g_digicam_camerabin_handle_bus_message (GDigicamManager *manager,
2257                                          gpointer user_data)
2258 {
2259     const GstStructure *structure = NULL;
2260     gint status = GST_PHOTOGRAPHY_FOCUS_STATUS_NONE;
2261     const gchar *message_name = NULL;
2262     GstState old = 0;
2263     GstState new = 0;
2264     GstState pending = 0;
2265     GError *error = NULL;
2266     GDigicamMode mode;
2267     GstElement *bin = NULL;
2268     gboolean result = FALSE;
2269
2270     switch (GST_MESSAGE_TYPE (GST_MESSAGE (user_data))) {
2271     case GST_MESSAGE_STATE_CHANGED:
2272         /* Don't care if it is not coming from camerabin itself */
2273         result = g_digicam_manager_get_gstreamer_bin (manager,
2274                                                       &bin,
2275                                                       &error);
2276
2277         /* Check errors */
2278         if (!result) {
2279             if (NULL != error) {
2280                 G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_bus_message: "
2281                                  "%s", error->message);
2282             }
2283             goto free;
2284         }
2285
2286         if (GST_ELEMENT (GST_MESSAGE_SRC (GST_MESSAGE (user_data))) == bin) {
2287             gst_message_parse_state_changed (GST_MESSAGE (user_data),
2288                                              &old,
2289                                              &new,
2290                                              &pending);
2291             if (GST_STATE_PLAYING == new) {
2292                 result = g_digicam_manager_get_mode (manager,
2293                                                      &mode,
2294                                                      &error);
2295
2296                 /* Check errors */
2297                 if (!result) {
2298                     if (NULL != error) {
2299                         G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_bus_message: "
2300                                          "%s", error->message);
2301                     }
2302                     goto free;
2303                 }
2304
2305                 switch (mode) {
2306                 case G_DIGICAM_MODE_STILL:
2307                     g_object_set (bin, "mode", 0, NULL);
2308                     break;
2309                 case G_DIGICAM_MODE_VIDEO:
2310                     g_object_set (bin, "mode", 1, NULL);
2311                     break;
2312                 default:
2313                     g_assert_not_reached ();
2314                 }
2315             }
2316         }
2317         break;
2318     case GST_MESSAGE_ELEMENT:
2319         structure = gst_message_get_structure (GST_MESSAGE (user_data));
2320         message_name = gst_structure_get_name (structure);
2321
2322         /* autofocus message */
2323         if (g_strcmp0 (message_name, GST_PHOTOGRAPHY_AUTOFOCUS_DONE) == 0) {
2324             gst_structure_get_int (structure, "status", &status);
2325             switch (status) {
2326             case GST_PHOTOGRAPHY_FOCUS_STATUS_FAIL:
2327                 G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_bus_message: "
2328                                  "Autofocus failed message received.");
2329                 g_signal_emit_by_name (manager,
2330                                        "focus-done",
2331                                        G_DIGICAM_FOCUSMODESTATUS_UNABLETOREACH);
2332                 break;
2333             case GST_PHOTOGRAPHY_FOCUS_STATUS_SUCCESS:
2334                 G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_bus_message: "
2335                                  "Autofocus success message received.");
2336                 g_signal_emit_by_name (manager,
2337                                        "focus-done",
2338                                        G_DIGICAM_FOCUSMODESTATUS_REACHED);
2339                 break;
2340             case GST_PHOTOGRAPHY_FOCUS_STATUS_NONE:
2341                 G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_bus_message: "
2342                                  "Autofocus none message received.");
2343                 break;
2344             case GST_PHOTOGRAPHY_FOCUS_STATUS_RUNNING:
2345                 G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_bus_message: "
2346                                  "Autofocus running message received.");
2347                 break;
2348             default:
2349                 break;
2350             }
2351             return TRUE;
2352         }
2353
2354         /* Shake risk message */
2355         if (g_strcmp0 (message_name, GST_PHOTOGRAPHY_SHAKE_RISK) == 0) {
2356             return TRUE;
2357         }
2358
2359         break;
2360     default:
2361         /* Not handling this message */
2362         break;
2363     }
2364
2365     /* Free */
2366 free:
2367     if (NULL != bin) {
2368         gst_object_unref (bin);
2369     }
2370     if (NULL != error) {
2371         g_error_free (error);
2372     }
2373
2374     return TRUE;
2375 }
2376
2377 /**
2378  * _g_digicam_camerabin_handle_sync_bus_message:
2379  * @manager: A #GDigicamManager.
2380  * @user_data: A #GstMessage.
2381  *
2382  * Function to handle custom gstreamer sync bus messages.
2383  *
2384  * Returns: #FALSE if invalid input arguments are received or the
2385  * message is not processed, #TRUE otherwise.
2386  **/
2387 static gboolean
2388 _g_digicam_camerabin_handle_sync_bus_message (GDigicamManager *manager,
2389                                               gpointer user_data)
2390 {
2391     const GstStructure *structure = NULL;
2392     const gchar *message_name = NULL;
2393     const GValue *value = NULL;
2394     PreviewHelper *helper = NULL;
2395     GstBuffer *buff = NULL;
2396     GdkPixbuf *preview = NULL;
2397     gboolean alpha;
2398     GstElement *bin = NULL;
2399     GError *error = NULL;
2400     gboolean result = FALSE;
2401     gboolean success = FALSE;
2402
2403     structure = gst_message_get_structure (GST_MESSAGE (user_data));
2404     g_return_val_if_fail (structure != NULL, FALSE);
2405     message_name = gst_structure_get_name (structure);
2406
2407     /* Don't care if it is not coming from camerabin itself */
2408     success = g_digicam_manager_get_gstreamer_bin (manager,
2409                                                    &bin,
2410                                                    &error);
2411
2412     /* Check errors */
2413     if (!success) {
2414         if (NULL != error) {
2415             G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_bus_message: "
2416                              "%s", error->message);
2417         }
2418         goto free;
2419     }
2420
2421     if (GST_ELEMENT (GST_MESSAGE_SRC (GST_MESSAGE (user_data))) == bin) {
2422         if (g_strcmp0 (message_name, G_DIGICAM_CAMERABIN_PHOTO_CAPTURE_END_MESSAGE) == 0) {
2423             G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_sync_bus_message: "
2424                              "Capture end message received.");
2425             TSTAMP (after-gst-next-shot);
2426
2427             /* Release lock and inform capture was completed */
2428             _g_digicam_manager_release_capture_lock (manager);
2429
2430             /* Emit a signal in the main loop */
2431             g_idle_add (_emit_capture_end_signal, manager);
2432
2433             result = TRUE;
2434             goto free;
2435         } else if (g_strcmp0 (message_name, G_DIGICAM_CAMERABIN_PHOTO_PREVIEW_MESSAGE) == 0) {
2436             G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_sync_bus_message: "
2437                              "Image preview message received.");
2438             TSTAMP (after-gst-snapshot);
2439             value = gst_structure_get_value (structure, "buffer");
2440             buff = gst_value_get_buffer (value);
2441             alpha = FALSE;
2442
2443             /* Preview using the RGB row data from GstBuffer */
2444             preview = _pixbuf_from_buffer (manager, buff, alpha);
2445
2446             /* FIXME: shouldn't we send the signal even if we don't have any data? */
2447             /* Send the acquired preview */
2448             if (NULL != preview) {
2449                 helper = g_slice_new0 (PreviewHelper);
2450                 helper->mgr = manager;
2451                 helper->preview = preview;
2452                 g_idle_add (_emit_preview_signal, helper);
2453             }
2454
2455             result = TRUE;
2456             goto free;
2457         } else {
2458             G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_sync_bus_message: "
2459                              "Unhandled sync DBus message "
2460                              "coming from camerabin.");
2461         }
2462     } else {
2463         if (g_strcmp0 (message_name, G_DIGICAM_CAMERABIN_PHOTO_CAPTURE_START_MESSAGE) == 0) {
2464             G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_sync_bus_message: "
2465                              "Capture start message received.");
2466
2467             /* Set lock and inform capture was started */
2468             _g_digicam_manager_set_capture_lock (manager);
2469
2470             /* Emit a signal in the main loop */
2471             g_idle_add (_emit_capture_start_signal, manager);
2472
2473             result = TRUE;
2474             goto free;
2475         } else if (g_strcmp0 (message_name, G_DIGICAM_CAMERABIN_PHOTO_CAPTURE_PICTURE_GOT_MESSAGE) == 0) {
2476             G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_sync_bus_message: "
2477                              "Picture got message received.");
2478
2479             /* Emit a signal in the main loop */
2480             g_idle_add (_emit_picture_got_signal, manager);
2481
2482             result = TRUE;
2483             goto free;
2484         } else {
2485             G_DIGICAM_DEBUG ("GDigicamCamerabin::_g_digicam_camerabin_handle_sync_bus_message: "
2486                              "Unhandled sync DBus message "
2487                              "not coming from camerabin.");
2488         }
2489     }
2490
2491     /* Free */
2492 free:
2493     if (NULL != bin) {
2494         gst_object_unref (bin);
2495     }
2496     if (NULL != error) {
2497         g_error_free (error);
2498     }
2499
2500     return result;
2501 }
2502
2503
2504 /*********************************/
2505 /* Private utility functions     */
2506 /*********************************/
2507
2508
2509 static void
2510 _pixbuf_destroy (guchar *pixels, gpointer data)
2511 {
2512   gst_buffer_unref (GST_BUFFER (data));
2513 }
2514
2515
2516 static GdkPixbuf *
2517 _pixbuf_from_buffer (GDigicamManager *manager,
2518                      GstBuffer *buff,
2519                      gboolean has_alpha)
2520 {
2521     GdkPixbuf *pix = NULL;
2522     GstVideoFormat fmt = GST_VIDEO_FORMAT_RGB;
2523     const guchar *data = NULL;
2524     GError *error = NULL;
2525     GDigicamMode mode;
2526     GDigicamAspectratio ar;
2527     GDigicamResolution res;
2528     gint vf_w, vf_h;
2529     gint res_w, res_h;
2530     gint fps_n, fps_d;
2531     gint minsize, buff_size, bytes_per_pixel;
2532     gint rowstride;
2533     gboolean result;
2534
2535
2536     /* Get mode to set specific resolution and aspect ratio*/
2537     result = g_digicam_manager_get_mode (manager,
2538                                          &mode,
2539                                          &error);
2540     /* Check errors */
2541     if (!result) {
2542         if (NULL != error) {
2543             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
2544         }
2545         goto free;
2546     }
2547
2548     /* Get resolution */
2549     result = g_digicam_manager_get_resolution (manager, &res, &error);
2550
2551     /* Check errors */
2552     if (!result) {
2553         if (NULL != error) {
2554             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
2555         }
2556         goto free;
2557     }
2558
2559     /* Get aspect ratio  */
2560     result = g_digicam_manager_get_aspect_ratio (manager, &ar, &error);
2561
2562     /* Check errors */
2563     if (!result) {
2564         if (NULL != error) {
2565             G_DIGICAM_DEBUG ("GDigicamCamerabin: %s", error->message);
2566         }
2567         goto free;
2568     }
2569
2570     /* Get resolution specific values depending on the camera mode */
2571     _get_aspect_ratio_and_resolution (mode,
2572                                       ar, res,
2573                                       &vf_w, &vf_h,
2574                                       &res_w, &res_h,
2575                                       &fps_n, &fps_d);
2576
2577     /* Build pixbuf */
2578     rowstride = gst_video_format_get_row_stride (fmt, 0, vf_w);
2579     if (has_alpha) {
2580         bytes_per_pixel = 4;
2581     } else {
2582         bytes_per_pixel = 3;
2583     }
2584
2585     /* Last row needn't have row padding */
2586     minsize = (rowstride * (vf_h - 1)) + (bytes_per_pixel * vf_w);
2587     buff_size = GST_BUFFER_SIZE (buff);
2588     g_return_val_if_fail (buff_size >= minsize, NULL);
2589
2590     /* Create pixbuf, ref it to keep data around as long as we use the
2591      * pixbuf */
2592     buff = gst_buffer_ref (buff);
2593     data = GST_BUFFER_DATA (buff);
2594     pix = gdk_pixbuf_new_from_data (data,
2595                                     GDK_COLORSPACE_RGB,
2596                                     has_alpha, 8, vf_w, vf_h,
2597                                     rowstride,
2598                                     _pixbuf_destroy, buff);
2599
2600     G_DIGICAM_DEBUG ("GDigicamCamerabin: thumbail generated!!!");
2601
2602 free:
2603     return pix;
2604 }
2605
2606
2607 static gboolean
2608 _emit_preview_signal (gpointer user_data)
2609 {
2610     PreviewHelper *helper = NULL;
2611
2612     helper = (PreviewHelper *) user_data;
2613
2614     /* Emit image-preview signal */
2615     g_signal_emit_by_name (helper->mgr,
2616                            "image-preview", helper->preview,
2617                            0);
2618
2619     /* Free */
2620     g_object_unref (helper->preview);
2621     g_slice_free (PreviewHelper, helper);
2622
2623     return FALSE;
2624 }
2625
2626 static gboolean
2627 _emit_capture_start_signal (gpointer user_data)
2628 {
2629     GDigicamManager *manager = NULL;
2630
2631     manager = G_DIGICAM_MANAGER (user_data);
2632
2633     /* Emit the capture-start signal */
2634     g_signal_emit_by_name (manager,
2635                            "capture-start",
2636                            0);
2637
2638     return FALSE;
2639 }
2640
2641 static gboolean
2642 _emit_capture_end_signal (gpointer user_data)
2643 {
2644     GDigicamManager *manager = NULL;
2645
2646     manager = G_DIGICAM_MANAGER (user_data);
2647
2648     /* Emit the capture-end signal */
2649     g_signal_emit_by_name (manager,
2650                            "capture-end",
2651                            0);
2652
2653     return FALSE;
2654 }
2655
2656
2657 static gboolean
2658 _emit_picture_got_signal (gpointer user_data)
2659 {
2660     GDigicamManager *manager = NULL;
2661
2662     manager = G_DIGICAM_MANAGER (user_data);
2663
2664     /* Emit the picture-got signal */
2665     g_signal_emit_by_name (manager, "picture-got", 0);
2666
2667     return FALSE;
2668 }
2669
2670
2671 static GstCaps *
2672 _new_preview_caps (gint pre_w,
2673                    gint pre_h)
2674 {
2675     GstCaps *caps = NULL;
2676
2677     caps = gst_caps_new_simple ("video/x-raw-rgb",
2678                                 "width", G_TYPE_INT, pre_w,
2679                                 "height", G_TYPE_INT, pre_h,
2680                                 "bpp", G_TYPE_INT, 24,
2681                                 NULL);
2682
2683     return caps;
2684 }
2685
2686
2687 static void
2688 _get_aspect_ratio_and_resolution (GDigicamMode mode,
2689                                   GDigicamAspectratio ar,
2690                                   GDigicamResolution res,
2691                                   gint *vf_w, gint *vf_h,
2692                                   gint *res_w, gint *res_h,
2693                                   gint *fps_n, gint *fps_d)
2694 {
2695     switch (mode) {
2696     case G_DIGICAM_MODE_STILL:
2697         _get_still_aspect_ratio_and_resolution (ar, res,
2698                                                 vf_w, vf_h,
2699                                                 res_w, res_h,
2700                                                 fps_n, fps_d);
2701         break;
2702     case G_DIGICAM_MODE_VIDEO:
2703         _get_video_aspect_ratio_and_resolution (ar, res,
2704                                                 vf_w, vf_h,
2705                                                 res_w, res_h,
2706                                                 fps_n, fps_d);
2707         break;
2708     default:
2709         g_assert_not_reached ();
2710     }
2711 }
2712
2713
2714 static void
2715 _get_still_aspect_ratio_and_resolution (GDigicamAspectratio ar,
2716                                         GDigicamResolution res,
2717                                         gint *vf_w, gint *vf_h,
2718                                         gint *res_w, gint *res_h,
2719                                         gint *fps_n, gint *fps_d)
2720 {
2721     switch (ar) {
2722     case G_DIGICAM_ASPECTRATIO_4X3:
2723         switch (res) {
2724         case G_DIGICAM_RESOLUTION_HIGH:
2725             *res_w = G_DIGICAM_CAMERABIN_STILL_4X3_HIGH_WIDTH;
2726             *res_h = G_DIGICAM_CAMERABIN_STILL_4X3_HIGH_HEIGHT;
2727             break;
2728         case G_DIGICAM_RESOLUTION_MEDIUM:
2729             *res_w = G_DIGICAM_CAMERABIN_STILL_4X3_MEDIUM_WIDTH;
2730             *res_h = G_DIGICAM_CAMERABIN_STILL_4X3_MEDIUM_HEIGHT;
2731             break;
2732         case G_DIGICAM_RESOLUTION_LOW:
2733             *res_w = G_DIGICAM_CAMERABIN_STILL_4X3_LOW_WIDTH;
2734             *res_h = G_DIGICAM_CAMERABIN_STILL_4X3_LOW_HEIGHT;
2735             break;
2736         default:
2737             g_assert_not_reached ();
2738         }
2739         *vf_w = G_DIGICAM_CAMERABIN_VIEWFINDER_4X3_WIDTH;
2740         *vf_h = G_DIGICAM_CAMERABIN_VIEWFINDER_4X3_HEIGHT;
2741         *fps_n = G_DIGICAM_CAMERABIN_VIEWFINDER_4X3_FPS;
2742         *fps_d = 100;
2743         break;
2744     case G_DIGICAM_ASPECTRATIO_16X9:
2745         switch (res) {
2746         case G_DIGICAM_RESOLUTION_HIGH:
2747             *res_w = G_DIGICAM_CAMERABIN_STILL_16X9_HIGH_WIDTH;
2748             *res_h = G_DIGICAM_CAMERABIN_STILL_16X9_HIGH_HEIGHT;
2749             break;
2750         case G_DIGICAM_RESOLUTION_MEDIUM:
2751             *res_w = G_DIGICAM_CAMERABIN_STILL_16X9_MEDIUM_WIDTH;
2752             *res_h = G_DIGICAM_CAMERABIN_STILL_16X9_MEDIUM_HEIGHT;
2753             break;
2754         case G_DIGICAM_RESOLUTION_LOW:
2755             *res_w = G_DIGICAM_CAMERABIN_STILL_16X9_LOW_WIDTH;
2756             *res_h = G_DIGICAM_CAMERABIN_STILL_16X9_LOW_HEIGHT;
2757             break;
2758         default:
2759             g_assert_not_reached ();
2760             }
2761         *vf_w = G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_WIDTH;
2762         *vf_h = G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_HEIGHT;
2763         *fps_n = G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_FPS;
2764         *fps_d = 100;
2765         break;
2766     default:
2767         g_assert_not_reached ();
2768     }
2769 }
2770
2771
2772 static void
2773 _get_video_aspect_ratio_and_resolution (GDigicamAspectratio ar,
2774                                         GDigicamResolution res,
2775                                         gint *vf_w, gint *vf_h,
2776                                         gint *res_w, gint *res_h,
2777                                         gint *fps_n, gint *fps_d)