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)
2778
{
2779
    switch (ar) {
2780
    case G_DIGICAM_ASPECTRATIO_4X3:
2781
        switch (res) {
2782
        case G_DIGICAM_RESOLUTION_HIGH:
2783
            *vf_w = G_DIGICAM_CAMERABIN_VIDEO_4X3_HIGH_WIDTH;
2784
            *vf_h = G_DIGICAM_CAMERABIN_VIDEO_4X3_HIGH_HEIGHT;
2785
            break;
2786
        case G_DIGICAM_RESOLUTION_MEDIUM:
2787
            *vf_w = G_DIGICAM_CAMERABIN_VIDEO_4X3_MEDIUM_WIDTH;
2788
            *vf_h = G_DIGICAM_CAMERABIN_VIDEO_4X3_MEDIUM_HEIGHT;
2789
            break;
2790
        case G_DIGICAM_RESOLUTION_LOW:
2791
            *vf_w = G_DIGICAM_CAMERABIN_VIDEO_4X3_LOW_WIDTH;
2792
            *vf_h = G_DIGICAM_CAMERABIN_VIDEO_4X3_LOW_HEIGHT;
2793
            break;
2794
        default:
2795
            g_assert_not_reached ();
2796
        }
2797
        *fps_n = G_DIGICAM_CAMERABIN_VIEWFINDER_4X3_FPS;
2798
        *fps_d = 100;
2799
        break;
2800
    case G_DIGICAM_ASPECTRATIO_16X9:
2801
        switch (res) {
2802
        case G_DIGICAM_RESOLUTION_HIGH:
2803
            *vf_w = G_DIGICAM_CAMERABIN_VIDEO_16X9_HIGH_WIDTH;
2804
            *vf_h = G_DIGICAM_CAMERABIN_VIDEO_16X9_HIGH_HEIGHT;
2805
            break;
2806
        case G_DIGICAM_RESOLUTION_MEDIUM:
2807
            *vf_w = G_DIGICAM_CAMERABIN_VIDEO_16X9_MEDIUM_WIDTH;
2808
            *vf_h = G_DIGICAM_CAMERABIN_VIDEO_16X9_MEDIUM_HEIGHT;
2809
            break;
2810
        case G_DIGICAM_RESOLUTION_LOW:
2811
            *vf_w = G_DIGICAM_CAMERABIN_VIDEO_16X9_LOW_WIDTH;
2812
            *vf_h = G_DIGICAM_CAMERABIN_VIDEO_16X9_LOW_HEIGHT;
2813
            break;
2814
        default:
2815
            g_assert_not_reached ();
2816
        }
2817
        *fps_n = G_DIGICAM_CAMERABIN_VIEWFINDER_16X9_VIDEO_FPS;
2818
        *fps_d = 100;
2819
        break;
2820
    default:
2821
        g_assert_not_reached ();
2822
    }
2823
}