[cheese/f19] Add a number of bug-fixes to deal better with high res cams (#873434)
Hans de Goede
jwrdegoede at fedoraproject.org
Mon Jun 17 12:25:11 UTC 2013
commit 65a88490987032a8f26eb1d79b8f4b0d46d4f5c2
Author: Hans de Goede <hdegoede at redhat.com>
Date: Mon Jun 17 14:24:49 2013 +0200
Add a number of bug-fixes to deal better with high res cams (#873434)
- Fix cheese-introduction.png being in both cheese and cheese-libs (#893756)
- Put the COPYING file in the docs for cheese-libs (#893800)
- Fix the flash when taking a photo being dark grey instead of white (#965813)
- Fix needing to press the effects button twice to select effects after
selecting an effect for the first time
- Various other bug-fixes
...ra-Add-a-capsfilter-to-our-video-source-b.patch | 49 ++++
...b-view-Don-t-set-columns-to-5000-in-horiz.patch | 126 ---------
...ra-remove-extranous-csp_post_balance-vide.patch | 65 +++++
...camera_device_update_format_table-going-i.patch | 45 ---
...e-camera-Set-image-and-video-capture-caps.patch | 30 ++
...h-is-a-multiple-of-8-and-height-a-multipl.patch | 73 -----
...ra-Fix-the-no-video-after-switching-resol.patch | 57 ++++
...se-camera-2-minor-error-handling-cleanups.patch | 43 +++
...ra-Fix-video-source-memleak-when-switchin.patch | 28 ++
0007-cheese-camera-Remove-unused-enum.patch | 36 +++
...cheese-camera-device-Fix-compiler-warning.patch | 26 ++
...era-device-Fix-memleak-in-get_best_format.patch | 54 ++++
...ra-device-Keep-track-of-highest-available.patch | 281 ++++++++++++++++++++
...ra-device-Add-cheese_camera_device_find_f.patch | 74 +++++
...ra-device-limit-caps-to-the-maximum-frame.patch | 94 +++++++
...ra-device-get_caps_for_format-simplify-th.patch | 29 ++
...amera-device-Make-get_best_format-smarter.patch | 67 +++++
...eese-camera-device-Plug-some-memory-leaks.patch | 47 ++++
0016-cheese-camera-Drop-unused-preview_caps.patch | 26 ++
...ra-Do-not-add-videoconvert-elements-aroun.patch | 52 ++++
...ra-Check-for-the-current-effect-being-the.patch | 81 ++++++
...ra-Don-t-block-the-main-valve-while-recor.patch | 30 ++
...ra-Downscale-image-for-effects-preview-pi.patch | 119 +++++++++
...indow-Fix-de-activation-of-effects-button.patch | 51 ++++
...ow-Make-mode-toggle-and-effects-button-in.patch | 98 +++++++
...dd-_init_with_args-init-function-variants.patch | 213 +++++++++++++++
0024-cheese-Use-cheese_gtk_init_with_args.patch | 196 ++++++++++++++
...Remove-last-remnants-of-the-old-menu-code.patch | 206 ++++++++++++++
...ect-set_wide_mode-set_fullscreen-against-.patch | 52 ++++
...-rid-of-special-set_startup_foo-functions.patch | 94 +++++++
...the-need-to-press-F11-twice-after-startin.patch | 32 +++
...e-widemode-controllable-from-the-app-menu.patch | 68 +++++
...-reading-of-widemode-setting-to-cheese-ma.patch | 54 ++++
...reading-of-fullscreen-setting-from-config.patch | 34 +++
...t-show-thumbnails-when-toggling-widemode-.patch | 53 ++++
...updating-of-device-selection-combo-sensit.patch | 54 ++++
...e-Fix-assert-failures-when-taking-a-photo.patch | 38 +++
...flash-Fix-the-flash-no-longer-being-white.patch | 65 +++++
cheese.spec | 124 +++++++--
39 files changed, 2700 insertions(+), 264 deletions(-)
---
diff --git a/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch b/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch
new file mode 100644
index 0000000..a4569a7
--- /dev/null
+++ b/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch
@@ -0,0 +1,49 @@
+From a602ffdd541b828ab9b8aac9b20db31ce427ba8b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 19:48:47 +0200
+Subject: [PATCH 01/35] cheese-camera: Add a capsfilter to our video-source bin
+
+This serves 2 purposes:
+1) It forces gstreamer to actually run the video source at the configured
+ resolution, rather then say run it at 1600x1200 @ 5 fps and downscale
+ that to 800x600 (still at 5 fps), as gstreamer opts to do with my
+ Logitech Webcam Pro 9000, when left to its own auto negotiate code.
+2) By greatly reducing the amount of advertised caps (this cam supports lots
+ of different resolutions at many different framerates per resolution), it
+ avoids a caps intersect "explosion", reducing the pipeline caps negotiation
+ on my core i5 @ 3.1Ghz from aprox 1.1 sec to aprox 350 ms (*).
+
+*) When combined with later patches in this patchset which also limit the
+framerates in the filtered caps.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index a78affd..c42d896 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -417,7 +417,7 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+ }
+
+ camera_input = g_strdup_printf (
+- "%s name=video_source device=%s",
++ "%s name=video_source device=%s ! capsfilter name=video_source_filter",
+ cheese_camera_device_get_src (selected_camera),
+ cheese_camera_device_get_device_node (selected_camera));
+
+@@ -762,7 +762,8 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+
+ if (!gst_caps_is_empty (caps))
+ {
+- GST_INFO_OBJECT (camera, "SETTING caps%" GST_PTR_FORMAT, caps);
++ GST_INFO_OBJECT (camera, "SETTING caps %" GST_PTR_FORMAT, caps);
++ g_object_set (gst_bin_get_by_name (GST_BIN (priv->video_source), "video_source_filter"), "caps", caps, NULL);
+ g_object_set (priv->camerabin, "viewfinder-caps", caps, NULL);
+ }
+ gst_caps_unref (caps);
+--
+1.8.2.1
+
diff --git a/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch b/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch
new file mode 100644
index 0000000..091ac69
--- /dev/null
+++ b/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch
@@ -0,0 +1,65 @@
+From 4740659c6092018a35bb820dfefac545b23c5dc2 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Sun, 9 Jun 2013 17:14:00 +0200
+Subject: [PATCH 02/35] cheese-camera: remove extranous csp_post_balance
+ videoconvert element
+
+camerabin2 already has a videoconvert element both before and after its
+video-source-filter element, so ending our own video-source-filter bin with
+a videoconvert element puts 2 videoconvert elements behind each other, which
+is not really useful.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 15 ++++-----------
+ 1 file changed, 4 insertions(+), 11 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index c42d896..7737209 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -89,7 +89,7 @@ struct _CheeseCameraPrivate
+ ClutterTexture *video_texture;
+
+ GstElement *effect_filter;
+- GstElement *video_balance, *csp_post_balance;
++ GstElement *video_balance;
+ GstElement *camera_tee, *effects_tee;
+ GstElement *main_valve, *effects_valve;
+
+@@ -608,29 +608,22 @@ cheese_camera_create_video_filter_bin (CheeseCamera *camera, GError **error)
+ cheese_camera_set_error_element_not_found (error, "videobalance");
+ return FALSE;
+ }
+- if ((priv->csp_post_balance = gst_element_factory_make ("videoconvert", "csp_post_balance")) == NULL)
+- {
+- cheese_camera_set_error_element_not_found (error, "videoconvert");
+- return FALSE;
+- }
+
+ if (error != NULL && *error != NULL)
+ return FALSE;
+
+ gst_bin_add_many (GST_BIN (priv->video_filter_bin), priv->camera_tee,
+ priv->main_valve, priv->effect_filter,
+- priv->video_balance, priv->csp_post_balance,
+- priv->effects_preview_bin, NULL);
++ priv->video_balance, priv->effects_preview_bin, NULL);
+
+ ok &= gst_element_link_many (priv->camera_tee, priv->main_valve,
+- priv->effect_filter, priv->video_balance,
+- priv->csp_post_balance, NULL);
++ priv->effect_filter, priv->video_balance, NULL);
+ gst_pad_link (gst_element_get_request_pad (priv->camera_tee, "src_%u"),
+ gst_element_get_static_pad (priv->effects_preview_bin, "sink"));
+
+ /* add ghostpads */
+
+- pad = gst_element_get_static_pad (priv->csp_post_balance, "src");
++ pad = gst_element_get_static_pad (priv->video_balance, "src");
+ gst_element_add_pad (priv->video_filter_bin, gst_ghost_pad_new ("src", pad));
+ gst_object_unref (GST_OBJECT (pad));
+
+--
+1.8.2.1
+
diff --git a/0003-cheese-camera-Set-image-and-video-capture-caps.patch b/0003-cheese-camera-Set-image-and-video-capture-caps.patch
new file mode 100644
index 0000000..203bf5b
--- /dev/null
+++ b/0003-cheese-camera-Set-image-and-video-capture-caps.patch
@@ -0,0 +1,30 @@
+From aedbd71c2c57b6555744a8ecf35f50816a809d97 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:12:41 +0200
+Subject: [PATCH 03/35] cheese-camera: Set image- and video-capture-caps
+
+Force the image / video capture to be in our desired resolution, rather then
+relying on constraints elsewhere in the pipeline resulting in us getting
+the desired resolution.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 7737209..9eeb245 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -758,6 +758,8 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+ GST_INFO_OBJECT (camera, "SETTING caps %" GST_PTR_FORMAT, caps);
+ g_object_set (gst_bin_get_by_name (GST_BIN (priv->video_source), "video_source_filter"), "caps", caps, NULL);
+ g_object_set (priv->camerabin, "viewfinder-caps", caps, NULL);
++ g_object_set (priv->camerabin, "image-capture-caps", caps, NULL);
++ g_object_set (priv->camerabin, "video-capture-caps", caps, NULL);
+ }
+ gst_caps_unref (caps);
+ }
+--
+1.8.2.1
+
diff --git a/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch b/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch
new file mode 100644
index 0000000..c7936d1
--- /dev/null
+++ b/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch
@@ -0,0 +1,57 @@
+From 62d880a4f15b2a4ccf84c7078b9c7232b27cd228 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:26:39 +0200
+Subject: [PATCH 04/35] cheese-camera: Fix the no video after switching
+ resolution problem
+
+There is a bug in wrappercamerabinsrc which causes it to loose its video-source
+setting after the pipeline has started, so on a stop / re-start, as we
+do when changing resolution, its video-source has become NULL, and we no
+longer have video.
+
+This patch works around this by moving the setting of the video-source
+property to cheese_camera_play(), so that it gets (re)set each time before
+we start the pipeline.
+
+I've also written a patch fixing the underlying cause, but since the workaround
+is simple, and has no adverse effects when the underlying issue is fixed,
+it seems a good idea to have this workaround in cheese, see here for the
+gst-plugins-bad fix: https://bugzilla.gnome.org/show_bug.cgi?id=701915
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 9eeb245..b353152 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -424,7 +424,7 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+ priv->video_source = gst_parse_bin_from_description (camera_input, TRUE, &err);
+ g_free (camera_input);
+
+- if (priv->video_source == NULL || priv->camera_source == NULL)
++ if (priv->video_source == NULL)
+ {
+ if (err != NULL)
+ {
+@@ -433,7 +433,6 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+ }
+ return FALSE;
+ }
+- g_object_set (priv->camera_source, "video-source", priv->video_source, NULL);
+
+ return TRUE;
+ }
+@@ -769,6 +768,7 @@ cheese_camera_play (CheeseCamera *camera)
+ {
+ CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
+ cheese_camera_set_new_caps (camera);
++ g_object_set (priv->camera_source, "video-source", priv->video_source, NULL);
+ gst_element_set_state (priv->camerabin, GST_STATE_PLAYING);
+ priv->pipeline_is_playing = TRUE;
+ }
+--
+1.8.2.1
+
diff --git a/0005-cheese-camera-2-minor-error-handling-cleanups.patch b/0005-cheese-camera-2-minor-error-handling-cleanups.patch
new file mode 100644
index 0000000..b80f076
--- /dev/null
+++ b/0005-cheese-camera-2-minor-error-handling-cleanups.patch
@@ -0,0 +1,43 @@
+From b770f7675a42a0ff0bc0845aff1af1a739525e3c Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:39:16 +0200
+Subject: [PATCH 05/35] cheese-camera: 2 minor error handling cleanups
+
+1) Simplify error cleanup in cheese_camera_set_camera_source()
+2) Don't call g_error_free on a possible NULL error in
+ cheese_camera_element_from_effect()
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index b353152..b55dc82 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -426,11 +426,7 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+
+ if (priv->video_source == NULL)
+ {
+- if (err != NULL)
+- {
+- g_error_free (err);
+- err = NULL;
+- }
++ g_clear_error(&err);
+ return FALSE;
+ }
+
+@@ -867,7 +863,7 @@ cheese_camera_element_from_effect (CheeseCamera *camera, CheeseEffect *effect)
+ g_free (effects_pipeline_desc);
+ if (!effect_filter || (err != NULL))
+ {
+- g_error_free (err);
++ g_clear_error (&err);
+ g_warning ("Error with effect filter %s. Ignored", name);
+ g_free (name);
+ return NULL;
+--
+1.8.2.1
+
diff --git a/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch b/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch
new file mode 100644
index 0000000..c1391dd
--- /dev/null
+++ b/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch
@@ -0,0 +1,28 @@
+From 6d3749f799b1217363ac40eb7e618a37301b008b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:46:10 +0200
+Subject: [PATCH 06/35] cheese-camera: Fix video-source memleak when switching
+ between cameras
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index b55dc82..c6cb4eb 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -400,6 +400,9 @@ cheese_camera_set_camera_source (CheeseCamera *camera)
+ guint i;
+ CheeseCameraDevice *selected_camera;
+
++ if (priv->video_source)
++ gst_object_unref (priv->video_source);
++
+ /* If we have a matching video device use that one, otherwise use the first */
+ priv->selected_device = 0;
+ selected_camera = g_ptr_array_index (priv->camera_devices, 0);
+--
+1.8.2.1
+
diff --git a/0007-cheese-camera-Remove-unused-enum.patch b/0007-cheese-camera-Remove-unused-enum.patch
new file mode 100644
index 0000000..31010b6
--- /dev/null
+++ b/0007-cheese-camera-Remove-unused-enum.patch
@@ -0,0 +1,36 @@
+From b0478b500889ccc7b17c1a3ba8e5aac87e12fdd0 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:46:43 +0200
+Subject: [PATCH 07/35] cheese-camera: Remove unused enum
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 12 ------------
+ 1 file changed, 12 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index c6cb4eb..fd5d2bf 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -59,18 +59,6 @@ G_DEFINE_TYPE (CheeseCamera, cheese_camera, G_TYPE_OBJECT)
+
+ #define CHEESE_CAMERA_ERROR cheese_camera_error_quark ()
+
+-typedef enum {
+- GST_CAMERABIN_FLAG_SOURCE_RESIZE = (1 << 0),
+- GST_CAMERABIN_FLAG_SOURCE_COLOR_CONVERSION = (1 << 1),
+- GST_CAMERABIN_FLAG_VIEWFINDER_COLOR_CONVERSION = (1 << 2),
+- GST_CAMERABIN_FLAG_VIEWFINDER_SCALE = (1 << 3),
+- GST_CAMERABIN_FLAG_AUDIO_CONVERSION = (1 << 4),
+- GST_CAMERABIN_FLAG_DISABLE_AUDIO = (1 << 5),
+- GST_CAMERABIN_FLAG_IMAGE_COLOR_CONVERSION = (1 << 6),
+- GST_CAMERABIN_FLAG_VIDEO_COLOR_CONVERSION = (1 << 7)
+-} GstCameraBinFlags;
+-
+-
+ struct _CheeseCameraPrivate
+ {
+ GstBus *bus;
+--
+1.8.2.1
+
diff --git a/0008-cheese-camera-device-Fix-compiler-warning.patch b/0008-cheese-camera-device-Fix-compiler-warning.patch
new file mode 100644
index 0000000..bf87947
--- /dev/null
+++ b/0008-cheese-camera-device-Fix-compiler-warning.patch
@@ -0,0 +1,26 @@
+From 5df60ca7f29d6008f894e8b702b288dad55851f9 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 10:56:25 +0200
+Subject: [PATCH 08/35] cheese-camera-device: Fix compiler warning
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 92d03a3..c7b7a07 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -165,7 +165,7 @@ compare_formats (gconstpointer a, gconstpointer b)
+ * Returns: the filtered #GstCaps
+ */
+ static GstCaps *
+-cheese_camera_device_filter_caps (CheeseCameraDevice *device, const GstCaps *caps, GStrv formats)
++cheese_camera_device_filter_caps (CheeseCameraDevice *device, GstCaps *caps, GStrv formats)
+ {
+ GstCaps *filter;
+ GstCaps *allowed;
+--
+1.8.2.1
+
diff --git a/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch b/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch
new file mode 100644
index 0000000..e74eefd
--- /dev/null
+++ b/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch
@@ -0,0 +1,54 @@
+From d5e114ae636089ff6c1554c1d98b1ea8d8ad3ff3 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 13:44:47 +0200
+Subject: [PATCH 09/35] cheese-camera-device: Fix memleak in get_best_format
+
+cheese_camera_device_get_best_format() calls
+cheese_camera_device_get_format_list(), which returns a sorted copy of the
+format lists, then takes the first element of that list, and returns a
+copy of that element. While never freeing the list copy.
+
+This patch fixes this leak by simply making the priv->formats list sorted
+so that cheese_camera_device_get_best_format can use it directly without
+the need to make (and then later free) a copy.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index c7b7a07..e5ec5fa 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -219,7 +219,7 @@ cheese_camera_device_add_format (CheeseCameraDevice *device, CheeseVideoFormat *
+
+ GST_INFO ("%dx%d", format->width, format->height);
+
+- priv->formats = g_list_append (priv->formats, format);
++ priv->formats = g_list_insert_sorted (priv->formats, format, compare_formats);
+ }
+
+ /*
+@@ -700,7 +700,7 @@ cheese_camera_device_get_format_list (CheeseCameraDevice *device)
+ {
+ g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+
+- return g_list_sort (g_list_copy (device->priv->formats), compare_formats);
++ return g_list_copy (device->priv->formats);
+ }
+
+ /**
+@@ -788,8 +788,7 @@ cheese_camera_device_get_best_format (CheeseCameraDevice *device)
+
+ g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+
+- format = g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT,
+- cheese_camera_device_get_format_list (device)->data);
++ format = g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT, device->priv->formats->data);
+
+ GST_INFO ("%dx%d", format->width, format->height);
+ return format;
+--
+1.8.2.1
+
diff --git a/0010-cheese-camera-device-Keep-track-of-highest-available.patch b/0010-cheese-camera-device-Keep-track-of-highest-available.patch
new file mode 100644
index 0000000..4311329
--- /dev/null
+++ b/0010-cheese-camera-device-Keep-track-of-highest-available.patch
@@ -0,0 +1,281 @@
+From 8b76b4ebc3f38e742f39ccded070be5e5290d41d Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 14:15:58 +0200
+Subject: [PATCH 10/35] cheese-camera-device: Keep track of highest available
+ framerate per format
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 167 ++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 149 insertions(+), 18 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index e5ec5fa..c684367 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -109,11 +109,29 @@ struct _CheeseCameraDevicePrivate
+ gchar *name;
+ guint v4lapi_version;
+ GstCaps *caps;
+- GList *formats;
++ GList *formats; /* list members are CheeseVideoFormatFull structs */
+
+ GError *construct_error;
+ };
+
++typedef struct _CheeseVideoFormatFull CheeseVideoFormatFull;
++
++/*
++ * This is our private version of CheeseVideoFormat, with extra fields added
++ * at the end. IMPORTANT the first fields *must* be kept in sync with the
++ * public CheeseVideoFormat, since in various places we cast pointers to
++ * CheeseVideoFormatFull to CheeseVideoFormat.
++ */
++struct _CheeseVideoFormatFull
++{
++ /* CheeseVideoFormat members keep synced with cheese-camera-device.h! */
++ gint width;
++ gint height;
++ /* libcheese private members */
++ gint fr_numerator;
++ gint fr_denominator;
++};
++
+ GQuark cheese_camera_device_error_quark (void);
+
+ GQuark
+@@ -145,8 +163,8 @@ G_DEFINE_BOXED_TYPE (CheeseVideoFormat, cheese_video_format,
+ static gint
+ compare_formats (gconstpointer a, gconstpointer b)
+ {
+- const CheeseVideoFormat *c = a;
+- const CheeseVideoFormat *d = b;
++ const CheeseVideoFormatFull *c = a;
++ const CheeseVideoFormatFull *d = b;
+
+ /* descending sort for rectangle area */
+ return (d->width * d->height - c->width * c->height);
+@@ -197,42 +215,154 @@ cheese_camera_device_filter_caps (CheeseCameraDevice *device, GstCaps *caps, GSt
+ }
+
+ /*
++ * cheese_camera_device_get_highest_framerate:
++ * @framerate: a #GValue holding a framerate cap
++ * @numerator: destination to store the numerator of the highest rate
++ * @denominator: destination to store the denominator of the highest rate
++ *
++ * Get the numerator and denominator for the highest framerate stored in
++ * a framerate cap.
++ *
++ * Note this function does not handle framerate ranges, if @framerate
++ * contains a range it will return 0/0 as framerate
++ */
++static void
++cheese_camera_device_get_highest_framerate(const GValue *framerate,
++ gint *numerator, gint *denominator)
++{
++ *numerator = 0;
++ *denominator = 0;
++
++ if (GST_VALUE_HOLDS_FRACTION (framerate))
++ {
++ *numerator = gst_value_get_fraction_numerator (framerate);
++ *denominator = gst_value_get_fraction_denominator (framerate);
++ }
++ else if (GST_VALUE_HOLDS_ARRAY (framerate))
++ {
++ float curr, highest = 0;
++ guint i, size = gst_value_array_get_size (framerate);
++
++ for (i = 0; i < size; i++)
++ {
++ const GValue *val = gst_value_array_get_value(framerate, i);
++
++ if (!GST_VALUE_HOLDS_FRACTION (val) ||
++ gst_value_get_fraction_denominator(val) == 0) {
++ continue;
++ }
++
++ curr = (float)gst_value_get_fraction_numerator(val) /
++ (float)gst_value_get_fraction_denominator(val);
++ if (curr > highest && curr <= CHEESE_MAXIMUM_RATE)
++ {
++ highest = curr;
++ *numerator = gst_value_get_fraction_numerator (val);
++ *denominator = gst_value_get_fraction_denominator (val);
++ }
++ }
++ }
++ else if (GST_VALUE_HOLDS_LIST (framerate))
++ {
++ float curr, highest = 0;
++ guint i, size = gst_value_list_get_size (framerate);
++
++ for (i = 0; i < size; i++)
++ {
++ const GValue *val = gst_value_list_get_value(framerate, i);
++
++ if (!GST_VALUE_HOLDS_FRACTION (val) ||
++ gst_value_get_fraction_denominator(val) == 0) {
++ continue;
++ }
++
++ curr = (float)gst_value_get_fraction_numerator(val) /
++ (float)gst_value_get_fraction_denominator(val);
++ if (curr > highest && curr <= CHEESE_MAXIMUM_RATE)
++ {
++ highest = curr;
++ *numerator = gst_value_get_fraction_numerator (val);
++ *denominator = gst_value_get_fraction_denominator (val);
++ }
++ }
++ }
++}
++
++/*
++ * cheese_camera_device_format_update_framerate:
++ * @format: the #CheeseVideoFormatFull to update the framerate of
++ * @framerate: a #GValue holding a framerate cap
++ *
++ * This function updates the framerate in @format with the highest framerate
++ * from @framerate, if @framerate contains a framerate higher then the
++ * framerate currently stored in @format.
++ */
++static void
++cheese_camera_device_format_update_framerate(CheeseVideoFormatFull *format,
++ const GValue *framerate)
++{
++ float high, curr = (float)format->fr_numerator / format->fr_denominator;
++ gint high_numerator, high_denominator;
++
++ cheese_camera_device_get_highest_framerate (framerate, &high_numerator,
++ &high_denominator);
++ if (high_denominator == 0)
++ return;
++
++ high = (float)high_numerator / (float)high_denominator;
++ if (high > curr) {
++ format->fr_numerator = high_numerator;
++ format->fr_denominator = high_denominator;
++ GST_INFO ("%dx%d new framerate %d/%d", format->width, format->height,
++ format->fr_numerator, format->fr_denominator);
++ }
++}
++
++/*
+ * cheese_camera_device_add_format:
+ * @device: a #CheeseCameraDevice
+- * @format: the #CheeseVideoFormat to add
++ * @format: the #CheeseVideoFormatFull to add
+ *
+ * Add the supplied @format to the list of formats supported by the @device.
+ */
+ static void
+-cheese_camera_device_add_format (CheeseCameraDevice *device, CheeseVideoFormat *format)
++cheese_camera_device_add_format (CheeseCameraDevice *device,
++ CheeseVideoFormatFull *format, const GValue *framerate)
+ {
+ CheeseCameraDevicePrivate *priv = device->priv;
+ GList *l;
+
+ for (l = priv->formats; l != NULL; l = l->next)
+ {
+- CheeseVideoFormat *item = l->data;
++ CheeseVideoFormatFull *item = l->data;
+ if ((item != NULL) &&
+ (item->width == format->width) &&
+- (item->height == format->height)) return;
++ (item->height == format->height))
++ {
++ cheese_camera_device_format_update_framerate (item, framerate);
++ return;
++ }
+ }
+
+- GST_INFO ("%dx%d", format->width, format->height);
++ cheese_camera_device_get_highest_framerate (framerate,
++ &format->fr_numerator, &format->fr_denominator);
++ GST_INFO ("%dx%d framerate %d/%d", format->width, format->height,
++ format->fr_numerator, format->fr_denominator);
+
+ priv->formats = g_list_insert_sorted (priv->formats, format, compare_formats);
+ }
+
+ /*
+ * free_format_list_foreach:
+- * @data: the #CheeseVideoFormat to free
++ * @data: the #CheeseVideoFormatFull to free
+ * @user_data: unused
+ *
+- * Free the individual #CheeseVideoFormat.
++ * Free the individual #CheeseVideoFormatFull.
+ */
+ static void
+ free_format_list_foreach (gpointer data, G_GNUC_UNUSED gpointer user_data)
+ {
+- g_slice_free (CheeseVideoFormat, data);
++ g_slice_free (CheeseVideoFormatFull, data);
+ }
+
+ /*
+@@ -271,19 +401,20 @@ cheese_camera_device_update_format_table (CheeseCameraDevice *device)
+ for (i = 0; i < num_structures; i++)
+ {
+ GstStructure *structure;
+- const GValue *width, *height;
++ const GValue *width, *height, *framerate;
+ structure = gst_caps_get_structure (priv->caps, i);
+
+ width = gst_structure_get_value (structure, "width");
+ height = gst_structure_get_value (structure, "height");
++ framerate = gst_structure_get_value (structure, "framerate");
+
+ if (G_VALUE_HOLDS_INT (width))
+ {
+- CheeseVideoFormat *format = g_slice_new0 (CheeseVideoFormat);
++ CheeseVideoFormatFull *format = g_slice_new0 (CheeseVideoFormatFull);
+
+ gst_structure_get_int (structure, "width", &(format->width));
+ gst_structure_get_int (structure, "height", &(format->height));
+- cheese_camera_device_add_format (device, format);
++ cheese_camera_device_add_format (device, format, framerate);
+ }
+ else if (GST_VALUE_HOLDS_INT_RANGE (width))
+ {
+@@ -310,14 +441,14 @@ cheese_camera_device_update_format_table (CheeseCameraDevice *device)
+ * we use <= here (and not below) to make this work */
+ while (cur_width <= max_width && cur_height <= max_height)
+ {
+- CheeseVideoFormat *format = g_slice_new0 (CheeseVideoFormat);
++ CheeseVideoFormatFull *format = g_slice_new0 (CheeseVideoFormatFull);
+
+ /* Gstreamer wants resolutions for YUV formats where the width is
+ * a multiple of 8, and the height is a multiple of 2 */
+ format->width = cur_width & ~7;
+ format->height = cur_height & ~1;
+
+- cheese_camera_device_add_format (device, format);
++ cheese_camera_device_add_format (device, format, framerate);
+
+ cur_width *= 2;
+ cur_height *= 2;
+@@ -327,14 +458,14 @@ cheese_camera_device_update_format_table (CheeseCameraDevice *device)
+ cur_height = max_height;
+ while (cur_width > min_width && cur_height > min_height)
+ {
+- CheeseVideoFormat *format = g_slice_new0 (CheeseVideoFormat);
++ CheeseVideoFormatFull *format = g_slice_new0 (CheeseVideoFormatFull);
+
+ /* Gstreamer wants resolutions for YUV formats where the width is
+ * a multiple of 8, and the height is a multiple of 2 */
+ format->width = cur_width & ~7;
+ format->height = cur_height & ~1;
+
+- cheese_camera_device_add_format (device, format);
++ cheese_camera_device_add_format (device, format, framerate);
+
+ cur_width /= 2;
+ cur_height /= 2;
+--
+1.8.2.1
+
diff --git a/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch b/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch
new file mode 100644
index 0000000..b3e7d22
--- /dev/null
+++ b/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch
@@ -0,0 +1,74 @@
+From 0d5c4a4df0836bdbab85b3ccbca1dffeb54affe1 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 14:27:04 +0200
+Subject: [PATCH 11/35] cheese-camera-device: Add
+ cheese_camera_device_find_full_format() helper
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 40 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index c684367..25d4a51 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -319,6 +319,30 @@ cheese_camera_device_format_update_framerate(CheeseVideoFormatFull *format,
+ }
+
+ /*
++ * cheese_camera_device_find_full_format
++ * @device: a #CheeseCameraDevice
++ * @format: #CheeseVideoFormat to find the matching #CheeseVideoFormatFull for
++ *
++ * Find a #CheeseVideoFormatFull matching the passed in #CheeseVideoFormat
++ */
++static CheeseVideoFormatFull *
++cheese_camera_device_find_full_format(CheeseCameraDevice *device,
++ CheeseVideoFormat* format)
++{
++ GList *l;
++
++ for (l = device->priv->formats; l != NULL; l = l->next)
++ {
++ CheeseVideoFormatFull *item = l->data;
++ if ((item != NULL) &&
++ (item->width == format->width) &&
++ (item->height == format->height))
++ return item;
++ }
++ return NULL;
++}
++
++/*
+ * cheese_camera_device_add_format:
+ * @device: a #CheeseCameraDevice
+ * @format: the #CheeseVideoFormatFull to add
+@@ -330,18 +354,14 @@ cheese_camera_device_add_format (CheeseCameraDevice *device,
+ CheeseVideoFormatFull *format, const GValue *framerate)
+ {
+ CheeseCameraDevicePrivate *priv = device->priv;
+- GList *l;
++ CheeseVideoFormatFull *existing;
+
+- for (l = priv->formats; l != NULL; l = l->next)
++ existing = cheese_camera_device_find_full_format(device,
++ (CheeseVideoFormat *)format);
++ if (existing)
+ {
+- CheeseVideoFormatFull *item = l->data;
+- if ((item != NULL) &&
+- (item->width == format->width) &&
+- (item->height == format->height))
+- {
+- cheese_camera_device_format_update_framerate (item, framerate);
+- return;
+- }
++ cheese_camera_device_format_update_framerate (existing, framerate);
++ return;
+ }
+
+ cheese_camera_device_get_highest_framerate (framerate,
+--
+1.8.2.1
+
diff --git a/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch b/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch
new file mode 100644
index 0000000..5d33b82
--- /dev/null
+++ b/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch
@@ -0,0 +1,94 @@
+From b9720475545f37baeb2eb1da4f45ca29faeb482f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 14:47:40 +0200
+Subject: [PATCH 12/35] cheese-camera-device: limit caps to the maximum
+ framerate
+
+Limit the caps returned by cheese_camera_device_get_caps_for_format() to
+the maximum framerate supported at the requested resolution. This is
+necessary because gstreamer first selects a format and then a framerate,
+resulting in it picking for 1280x720 ie yuyv @ 15 fps, instead of mjpg @ 30
+fps (*), or at 1600x1200 yuyv @ 5 fps instead of mjpeg @ 10 fps.
+
+*) Which will be converted to i420 by the videoconvert element in camerabin
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 46 ++++++++++++++++++++++++++++------------
+ 1 file changed, 32 insertions(+), 14 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 25d4a51..273d530 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -954,35 +954,53 @@ cheese_camera_device_get_best_format (CheeseCameraDevice *device)
+ *
+ * Returns: (transfer full): the #GstCaps for the given @format
+ */
++
++static GstCaps *
++cheese_camera_device_format_to_caps (const char *media_type,
++ CheeseVideoFormatFull *format)
++{
++ if (format->fr_numerator != 0 && format->fr_denominator != 0)
++ return gst_caps_new_simple (media_type,
++ "framerate", GST_TYPE_FRACTION,
++ format->fr_numerator, format->fr_denominator,
++ "width", G_TYPE_INT, format->width,
++ "height", G_TYPE_INT, format->height, NULL);
++ else
++ return gst_caps_new_simple (media_type,
++ "width", G_TYPE_INT, format->width,
++ "height", G_TYPE_INT, format->height, NULL);
++}
++
+ GstCaps *
+ cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
+ CheeseVideoFormat *format)
+ {
++ CheeseVideoFormatFull *full_format;
+ GstCaps *desired_caps;
+ GstCaps *subset_caps;
+ guint i, length;
+
+ g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+
+- GST_INFO ("Getting caps for %dx%d", format->width, format->height);
+-
+- desired_caps = gst_caps_new_simple (supported_formats[0],
+- "width", G_TYPE_INT,
+- format->width,
+- "height", G_TYPE_INT,
+- format->height,
+- NULL);
++ full_format = cheese_camera_device_find_full_format(device, format);
++ if (!full_format)
++ {
++ GST_INFO ("Getting caps for %dx%d: no such format!",
++ format->width, format->height);
++ return gst_caps_new_empty ();
++ }
++ GST_INFO ("Getting caps for %dx%d @ %d/%d fps",
++ full_format->width, full_format->height,
++ full_format->fr_numerator, full_format->fr_denominator);
+
++ desired_caps = cheese_camera_device_format_to_caps(supported_formats[0],
++ full_format);
+ length = g_strv_length (supported_formats);
+ for (i = 1; i < length; i++)
+ {
+ gst_caps_append (desired_caps,
+- gst_caps_new_simple (supported_formats[i],
+- "width", G_TYPE_INT,
+- format->width,
+- "height", G_TYPE_INT,
+- format->height,
+- NULL));
++ cheese_camera_device_format_to_caps(supported_formats[i],
++ full_format));
+ }
+
+ subset_caps = gst_caps_intersect (desired_caps, device->priv->caps);
+--
+1.8.2.1
+
diff --git a/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch b/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch
new file mode 100644
index 0000000..906146f
--- /dev/null
+++ b/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch
@@ -0,0 +1,29 @@
+From af213c390521acf0c73a440a8f0ccf42e7393195 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Mon, 10 Jun 2013 20:25:44 +0200
+Subject: [PATCH 13/35] cheese-camera-device: get_caps_for_format: simplify the
+ returned caps
+
+This results in much simpler caps, which as main advantage that they are
+way easier to read when trawling to debug logs.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 273d530..c23069d 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -1004,6 +1004,7 @@ cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
+ }
+
+ subset_caps = gst_caps_intersect (desired_caps, device->priv->caps);
++ subset_caps = gst_caps_simplify (subset_caps);
+ gst_caps_unref (desired_caps);
+
+ GST_INFO ("Got %" GST_PTR_FORMAT, subset_caps);
+--
+1.8.2.1
+
diff --git a/0014-cheese-camera-device-Make-get_best_format-smarter.patch b/0014-cheese-camera-device-Make-get_best_format-smarter.patch
new file mode 100644
index 0000000..8288a98
--- /dev/null
+++ b/0014-cheese-camera-device-Make-get_best_format-smarter.patch
@@ -0,0 +1,67 @@
+From 4711194d75b412fe1ba092adbe3101f252ac77fb Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 11:07:37 +0200
+Subject: [PATCH 14/35] cheese-camera-device: Make get_best_format smarter
+
+If we've a device which can do 1600x900 at 10 fps and 1280x800 @ 25 fps,
+then 1600x900 is not really the best format, as 10 fps leads to a bad
+user experience.
+
+So this patch makes get_best_format return the highest resolution at which
+the device can do atleast 15 fps.
+
+Since some (older) cameras may have something like 640x480 @ 10 fps and
+320x240 @ 30 fps as modes, there is an additional check that the mode
+must also have a width of at least 640 pixels.
+
+If no mode matching the widh >= 640 && frame_rate >= 15 criteria is found,
+get_best_format will behave as before as simply return the highest resolution
+mode.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index c23069d..402bbb8 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -935,14 +935,30 @@ cheese_camera_device_get_device_node (CheeseCameraDevice *device)
+ CheeseVideoFormat *
+ cheese_camera_device_get_best_format (CheeseCameraDevice *device)
+ {
+- CheeseVideoFormat *format;
++ CheeseVideoFormatFull *format = NULL;
++ GList *l;
+
+ g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
+
+- format = g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT, device->priv->formats->data);
++ /* First check for the highest res with width >= 640 and fps >= 15 */
++ for (l = device->priv->formats; l != NULL; l = l->next)
++ {
++ CheeseVideoFormatFull *item = l->data;
++ float frame_rate = (float)item->fr_numerator / (float)item->fr_denominator;
++ if (item->width >= 640 && frame_rate >= 15)
++ {
++ format = item;
++ break;
++ }
++ }
++ /* Else simply return the highest res */
++ if (!format)
++ format = device->priv->formats->data;
++
++ GST_INFO ("%dx%d@%d/%d", format->width, format->height,
++ format->fr_numerator, format->fr_denominator);
+
+- GST_INFO ("%dx%d", format->width, format->height);
+- return format;
++ return g_boxed_copy (CHEESE_TYPE_VIDEO_FORMAT, format);;
+ }
+
+ /**
+--
+1.8.2.1
+
diff --git a/0015-cheese-camera-device-Plug-some-memory-leaks.patch b/0015-cheese-camera-device-Plug-some-memory-leaks.patch
new file mode 100644
index 0000000..a055d49
--- /dev/null
+++ b/0015-cheese-camera-device-Plug-some-memory-leaks.patch
@@ -0,0 +1,47 @@
+From 59811406ccd626704a0bb810032c39a089e1965a Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 14:18:52 +0200
+Subject: [PATCH 15/35] cheese-camera-device: Plug some memory leaks
+
+1) If we already have a format in the list, free it
+2) Not only free the formats in the list, but also the actual GList structures
+ themselves
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera-device.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
+index 402bbb8..a12b0f7 100644
+--- a/libcheese/cheese-camera-device.c
++++ b/libcheese/cheese-camera-device.c
+@@ -360,6 +360,7 @@ cheese_camera_device_add_format (CheeseCameraDevice *device,
+ (CheeseVideoFormat *)format);
+ if (existing)
+ {
++ g_slice_free (CheeseVideoFormatFull, format);
+ cheese_camera_device_format_update_framerate (existing, framerate);
+ return;
+ }
+@@ -380,7 +381,7 @@ cheese_camera_device_add_format (CheeseCameraDevice *device,
+ * Free the individual #CheeseVideoFormatFull.
+ */
+ static void
+-free_format_list_foreach (gpointer data, G_GNUC_UNUSED gpointer user_data)
++free_format_list_foreach (gpointer data)
+ {
+ g_slice_free (CheeseVideoFormatFull, data);
+ }
+@@ -396,7 +397,7 @@ free_format_list (CheeseCameraDevice *device)
+ {
+ CheeseCameraDevicePrivate *priv = device->priv;
+
+- g_list_foreach (priv->formats, free_format_list_foreach, NULL);
++ g_list_free_full (priv->formats, free_format_list_foreach);
+ priv->formats = NULL;
+ }
+
+--
+1.8.2.1
+
diff --git a/0016-cheese-camera-Drop-unused-preview_caps.patch b/0016-cheese-camera-Drop-unused-preview_caps.patch
new file mode 100644
index 0000000..5a2dc43
--- /dev/null
+++ b/0016-cheese-camera-Drop-unused-preview_caps.patch
@@ -0,0 +1,26 @@
+From 7cb124b1919198af87013fa5a26d4d11250fbb9f Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 09:22:09 +0200
+Subject: [PATCH 16/35] cheese-camera: Drop unused preview_caps
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index fd5d2bf..eafc381 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -81,8 +81,6 @@ struct _CheeseCameraPrivate
+ GstElement *camera_tee, *effects_tee;
+ GstElement *main_valve, *effects_valve;
+
+- GstCaps *preview_caps;
+-
+ gboolean is_recording;
+ gboolean pipeline_is_playing;
+ gchar *photo_filename;
+--
+1.8.2.1
+
diff --git a/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch b/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch
new file mode 100644
index 0000000..6e11917
--- /dev/null
+++ b/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch
@@ -0,0 +1,52 @@
+From 8e50910e9604c5d719397dd3f6a5fccc463eaa35 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 09:05:51 +0200
+Subject: [PATCH 17/35] cheese-camera: Do not add videoconvert elements around
+ the "no effect" effect
+
+The "no effect" effect is our default value, and thus worth optimizing a bit
+for. Clearly in the "no effect" effect case adding a videoconvert element both
+before and after the element is not needed.
+
+Note we also don't add the videoconvert elements when creating the initial
+pipeline, so this also keeps the way the pipeline looks initially and when
+"no-effect" is selected consistent.
+
+When starting cheese with "no-effect" selected, this shaves of another 130ms
+of the initial pipeline creation time, for a total improvement for this patch
+set from aprox 1.1 sec to aprox 220 ms.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index eafc381..7b7fac5 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -888,12 +888,20 @@ void
+ cheese_camera_set_effect (CheeseCamera *camera, CheeseEffect *effect)
+ {
+ GstElement *effect_filter;
++ gchar *effect_desc;
+
+ g_return_if_fail (CHEESE_IS_CAMERA (camera));
+
+- effect_filter = cheese_camera_element_from_effect (camera, effect);
++ g_object_get (G_OBJECT (effect), "pipeline-desc", &effect_desc, NULL);
++
++ if (strcmp(effect_desc, "identity") == 0)
++ effect_filter = gst_element_factory_make ("identity", "effect");
++ else
++ effect_filter = cheese_camera_element_from_effect (camera, effect);
+ if (effect_filter != NULL)
+ cheese_camera_change_effect_filter (camera, effect_filter);
++
++ g_free (effect_desc);
+ }
+
+ /**
+--
+1.8.2.1
+
diff --git a/0018-cheese-camera-Check-for-the-current-effect-being-the.patch b/0018-cheese-camera-Check-for-the-current-effect-being-the.patch
new file mode 100644
index 0000000..a2bb200
--- /dev/null
+++ b/0018-cheese-camera-Check-for-the-current-effect-being-the.patch
@@ -0,0 +1,81 @@
+From 7f7e1b27e05ce3ba29e409fcf5cb58241ef99067 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 09:35:14 +0200
+Subject: [PATCH 18/35] cheese-camera: Check for the current effect being the
+ same as the one set
+
+And if so, turn the cheese_camera_set_effect call into a nop.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 7b7fac5..9cfaf7e 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -80,6 +80,7 @@ struct _CheeseCameraPrivate
+ GstElement *video_balance;
+ GstElement *camera_tee, *effects_tee;
+ GstElement *main_valve, *effects_valve;
++ gchar *current_effect_desc;
+
+ gboolean is_recording;
+ gboolean pipeline_is_playing;
+@@ -587,6 +588,7 @@ cheese_camera_create_video_filter_bin (CheeseCamera *camera, GError **error)
+ cheese_camera_set_error_element_not_found (error, "identity");
+ return FALSE;
+ }
++ priv->current_effect_desc = g_strdup("identity");
+ if ((priv->video_balance = gst_element_factory_make ("videobalance", "video_balance")) == NULL)
+ {
+ cheese_camera_set_error_element_not_found (error, "videobalance");
+@@ -887,19 +889,36 @@ cheese_camera_element_from_effect (CheeseCamera *camera, CheeseEffect *effect)
+ void
+ cheese_camera_set_effect (CheeseCamera *camera, CheeseEffect *effect)
+ {
++ CheeseCameraPrivate *priv;
+ GstElement *effect_filter;
+ gchar *effect_desc;
+
+ g_return_if_fail (CHEESE_IS_CAMERA (camera));
+
++ priv = camera->priv;
++
+ g_object_get (G_OBJECT (effect), "pipeline-desc", &effect_desc, NULL);
+
++ if (strcmp(priv->current_effect_desc, effect_desc) == 0)
++ {
++ GST_INFO_OBJECT (camera, "Effect is: \"%s\", not updating", effect_desc);
++ g_free (effect_desc);
++ return;
++ }
++
++ GST_INFO_OBJECT (camera, "Changing effect to: \"%s\"", effect_desc);
++
+ if (strcmp(effect_desc, "identity") == 0)
+ effect_filter = gst_element_factory_make ("identity", "effect");
+ else
+ effect_filter = cheese_camera_element_from_effect (camera, effect);
+ if (effect_filter != NULL)
++ {
+ cheese_camera_change_effect_filter (camera, effect_filter);
++ g_free (priv->current_effect_desc);
++ priv->current_effect_desc = effect_desc;
++ return;
++ }
+
+ g_free (effect_desc);
+ }
+@@ -1202,6 +1221,7 @@ cheese_camera_finalize (GObject *object)
+
+ if (priv->photo_filename)
+ g_free (priv->photo_filename);
++ g_free (priv->current_effect_desc);
+ g_free (priv->device_node);
+ g_boxed_free (CHEESE_TYPE_VIDEO_FORMAT, priv->current_format);
+
+--
+1.8.2.1
+
diff --git a/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch b/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch
new file mode 100644
index 0000000..68c50d2
--- /dev/null
+++ b/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch
@@ -0,0 +1,30 @@
+From 39c02d60193596a61c00cdc5b5952a425bb5e34b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 13:14:14 +0200
+Subject: [PATCH 19/35] cheese-camera: Don't block the main valve while
+ recording
+
+Otherwise we end up dropping frames intended for the recording.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 9cfaf7e..2dc5655 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -942,7 +942,8 @@ cheese_camera_toggle_effects_pipeline (CheeseCamera *camera, gboolean active)
+ if (active)
+ {
+ g_object_set (G_OBJECT (priv->effects_valve), "drop", FALSE, NULL);
+- g_object_set (G_OBJECT (priv->main_valve), "drop", TRUE, NULL);
++ if (!priv->is_recording)
++ g_object_set (G_OBJECT (priv->main_valve), "drop", TRUE, NULL);
+ }
+ else
+ {
+--
+1.8.2.1
+
diff --git a/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch b/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch
new file mode 100644
index 0000000..143bc75
--- /dev/null
+++ b/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch
@@ -0,0 +1,119 @@
+From 5cb470a89ed733ef7b0db3c534d1ce6e76648fae Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 16:16:23 +0200
+Subject: [PATCH 20/35] cheese-camera: Downscale image for effects-preview
+ pipeline
+
+Having the whole effects-preview bin deal with ie 1280x800 images is not very
+useful, esp since even when fullscreen on a full-hd monitor, the preview images
+are smaller then 640xXXX. This useless high-res processing for 9 preview images
+in paralellel brings my 2nd gen core i5 @ 3.1 GHz to its knees, resulting in a
+non fluid preview panel.
+
+Also after clicking through all effect preview pages, so that all effect
+preview textures are connected, cheese will use 1GB of *resident* ram with
+the example 1280x800 capture resolution.
+
+This patch fixes this by downscaling the images from the video-source to
+640xXXX where XXX is determined by the original resolution aspect-ratio.
+
+After this patch the effects preview framerate is much smoother, and the
+latency is noticably less. And as a bonus the maximal resident size of cheese
+in this example is reduced to 350 MB.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-camera.c | 42 ++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 34 insertions(+), 8 deletions(-)
+
+diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
+index 2dc5655..31348d2 100644
+--- a/libcheese/cheese-camera.c
++++ b/libcheese/cheese-camera.c
+@@ -76,7 +76,7 @@ struct _CheeseCameraPrivate
+
+ ClutterTexture *video_texture;
+
+- GstElement *effect_filter;
++ GstElement *effect_filter, *effects_capsfilter;
+ GstElement *video_balance;
+ GstElement *camera_tee, *effects_tee;
+ GstElement *main_valve, *effects_valve;
+@@ -517,27 +517,39 @@ cheese_camera_create_effects_preview_bin (CheeseCamera *camera, GError **error)
+ CheeseCameraPrivate *priv = camera->priv;
+
+ gboolean ok = TRUE;
++ GstElement *scale;
+ GstPad *pad;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ priv->effects_preview_bin = gst_bin_new ("effects_preview_bin");
+
+- if ((priv->effects_tee = gst_element_factory_make ("tee", "effects_tee")) == NULL)
++ if ((priv->effects_valve = gst_element_factory_make ("valve", "effects_valve")) == NULL)
+ {
+- cheese_camera_set_error_element_not_found (error, "tee");
++ cheese_camera_set_error_element_not_found (error, "effects_valve");
+ return FALSE;
+ }
+- if ((priv->effects_valve = gst_element_factory_make ("valve", "effects_valve")) == NULL)
++ if ((scale = gst_element_factory_make ("videoscale", "effects_scale")) == NULL)
+ {
+- cheese_camera_set_error_element_not_found (error, "effects_valve");
++ cheese_camera_set_error_element_not_found (error, "videoscale");
++ return FALSE;
++ }
++ if ((priv->effects_capsfilter = gst_element_factory_make ("capsfilter", "effects_capsfilter")) == NULL)
++ {
++ cheese_camera_set_error_element_not_found (error, "capsfilter");
++ return FALSE;
++ }
++ if ((priv->effects_tee = gst_element_factory_make ("tee", "effects_tee")) == NULL)
++ {
++ cheese_camera_set_error_element_not_found (error, "tee");
+ return FALSE;
+ }
+
+- gst_bin_add_many (GST_BIN (priv->effects_preview_bin),
+- priv->effects_valve, priv->effects_tee, NULL);
++ gst_bin_add_many (GST_BIN (priv->effects_preview_bin), priv->effects_valve,
++ scale, priv->effects_capsfilter, priv->effects_tee, NULL);
+
+- ok &= gst_element_link_many (priv->effects_valve, priv->effects_tee, NULL);
++ ok &= gst_element_link_many (priv->effects_valve, scale,
++ priv->effects_capsfilter, priv->effects_tee, NULL);
+
+ /* add ghostpads */
+
+@@ -723,6 +735,8 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+ CheeseCameraPrivate *priv;
+ CheeseCameraDevice *device;
+ GstCaps *caps;
++ gchar *caps_desc;
++ int width, height;
+
+ g_return_if_fail (CHEESE_IS_CAMERA (camera));
+
+@@ -746,6 +760,18 @@ cheese_camera_set_new_caps (CheeseCamera *camera)
+ g_object_set (priv->camerabin, "viewfinder-caps", caps, NULL);
+ g_object_set (priv->camerabin, "image-capture-caps", caps, NULL);
+ g_object_set (priv->camerabin, "video-capture-caps", caps, NULL);
++ gst_caps_unref (caps);
++
++ width = priv->current_format->width;
++ width = width > 640 ? 640 : width;
++ height = width * priv->current_format->height / priv->current_format->width;
++ /* !! Gstreamer will crash if this is not a multiple of 2 !! */
++ height = (height + 1) & ~1;
++ caps_desc = g_strdup_printf ("video/x-raw, width=%d, height=%d",
++ width, height);
++ caps = gst_caps_from_string (caps_desc);
++ g_free (caps_desc);
++ g_object_set (priv->effects_capsfilter, "caps", caps, NULL);
+ }
+ gst_caps_unref (caps);
+ }
+--
+1.8.2.1
+
diff --git a/0021-cheese-window-Fix-de-activation-of-effects-button.patch b/0021-cheese-window-Fix-de-activation-of-effects-button.patch
new file mode 100644
index 0000000..d328d14
--- /dev/null
+++ b/0021-cheese-window-Fix-de-activation-of-effects-button.patch
@@ -0,0 +1,51 @@
+From 775c5d479d47c96a1a0e78a852ec31418809c0dc Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 12:51:09 +0200
+Subject: [PATCH 21/35] cheese-window: Fix de-activation of effects button
+
+So that the user does not need to click twice on the effect button to change
+the effect (after the first time the effect was changed).
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 70293aa..9ebb5e1 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -895,7 +895,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ else
+ if (is_effects_selector_active)
+ {
+- // FIXME: Set the effects action to be inactive.
++ effects_toggle_button.set_active (false);
+ }
+ }
+ return false;
+@@ -1031,7 +1031,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ public void set_effects (bool effects)
+ {
+ toggle_effects_selector (effects);
+- // FIXME: Set the mode action to be inverse sensitivity to effects.
+ }
+
+ /**
+@@ -1045,12 +1044,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ Clutter.ButtonEvent event)
+ {
+ /* Disable the effects selector after selecting an effect. */
+- toggle_effects_selector(false);
++ effects_toggle_button.set_active (false);
+
+ selected_effect = source.get_data ("effect");
+ camera.set_effect (selected_effect);
+ settings.set_string ("selected-effect", selected_effect.name);
+- // FIXME: Set the effects action to be inactive.
+ return false;
+ }
+
+--
+1.8.2.1
+
diff --git a/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch b/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch
new file mode 100644
index 0000000..872413c
--- /dev/null
+++ b/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch
@@ -0,0 +1,98 @@
+From 113a466ab26633d765cb76461ef8a63b0fa86911 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Tue, 11 Jun 2013 13:09:39 +0200
+Subject: [PATCH 22/35] cheese-window: Make mode-toggle and effects button
+ inactive when recording
+
+While at it also fixup the indentation of enable_mode_change / disable, to
+be 2 spaces like most other code in cheese-window.vala.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 44 +++++++++++++++++++++++++++++++-------------
+ 1 file changed, 31 insertions(+), 13 deletions(-)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 9ebb5e1..e8ccb47 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -95,6 +95,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ private bool is_command_line_startup;
+
+ private Gtk.Button[] buttons;
++ private Gtk.Button[] mode_buttons;
+
+ private Cheese.Camera camera;
+ private Cheese.FileUtil fileutil;
+@@ -527,23 +528,37 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ set_fullscreen_mode (fullscreen);
+ }
+
+- /**
+- * Make the media capture mode actions sensitive.
+- */
+- private void enable_mode_change ()
++ /**
++ * Make the media capture mode actions sensitive.
++ */
++ private void enable_mode_change ()
++ {
++ foreach (Gtk.Button b in mode_buttons)
+ {
+- // FIXME: Set the mode action to be sensitive
+- // FIXME: Set the effects action to be sensitive.
++ b.sensitive = true;
+ }
++ effects_toggle_button.sensitive = true;
++ }
+
+- /**
+- * Make the media capture mode actions insensitive.
+- */
+- private void disable_mode_change ()
++ /**
++ * Make the media capture mode actions insensitive.
++ */
++ private void disable_mode_change ()
++ {
++ foreach (Gtk.Button b in mode_buttons)
+ {
+- // FIXME: Set the mode action to be sensitive
+- // FIXME: Set the effects action to be insensitive.
++ b.sensitive = false;
+ }
++ /* Allow changing the effects while recording a video */
++ if (current_mode != MediaMode.VIDEO)
++ {
++ effects_toggle_button.sensitive = false;
++ if (is_effects_selector_active)
++ {
++ effects_toggle_button.set_active (false);
++ }
++ }
++ }
+
+ /**
+ * Set the capture resolution, based on the current capture mode.
+@@ -966,7 +981,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ {
+ is_bursting = true;
+ this.disable_mode_change ();
+- // FIXME: Set the effects action to be inactive.
+ take_action_button_label.label = "<b>" + _("Stop _Taking Pictures") + "</b>";
+ take_action_button.tooltip_text = _("Stop taking pictures");
+ burst_take_photo ();
+@@ -1416,6 +1430,10 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ effects_toggle_button,
+ leave_fullscreen_button};
+
++ mode_buttons = {photo_toggle_button,
++ video_toggle_button,
++ burst_toggle_button};
++
+ video_preview = clutter_builder.get_object ("video_preview") as Clutter.Texture;
+ viewport_layout = clutter_builder.get_object ("viewport_layout") as Clutter.Box;
+ viewport_layout_manager = clutter_builder.get_object ("viewport_layout_manager") as Clutter.BinLayout;
+--
+1.8.2.1
+
diff --git a/0023-libcheese-Add-_init_with_args-init-function-variants.patch b/0023-libcheese-Add-_init_with_args-init-function-variants.patch
new file mode 100644
index 0000000..661796b
--- /dev/null
+++ b/0023-libcheese-Add-_init_with_args-init-function-variants.patch
@@ -0,0 +1,213 @@
+From e7b7314b5af40aaf9aa2a782a1fd025f2e08345e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 12:07:20 +0200
+Subject: [PATCH 23/35] libcheese: Add _init_with_args init function variants
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ docs/reference/cheese-sections.txt | 2 ++
+ libcheese/cheese-gtk.c | 57 ++++++++++++++++++++++++++++++++++++++
+ libcheese/cheese-gtk.h | 5 ++++
+ libcheese/cheese-gtk.symbols | 1 +
+ libcheese/cheese.c | 25 +++++++++++++++++
+ libcheese/cheese.h | 5 ++++
+ src/vapi/cheese-common.vapi | 14 ++++++++++
+ 7 files changed, 109 insertions(+)
+
+diff --git a/docs/reference/cheese-sections.txt b/docs/reference/cheese-sections.txt
+index 81e835c..bed1e75 100644
+--- a/docs/reference/cheese-sections.txt
++++ b/docs/reference/cheese-sections.txt
+@@ -2,12 +2,14 @@
+ <FILE>cheese-init</FILE>
+ <TITLE>Initializing libcheese</TITLE>
+ cheese_init
++cheese_init_with_args
+ </SECTION>
+
+ <SECTION>
+ <FILE>cheese-gtk-init</FILE>
+ <TITLE>Initializing libcheese-gtk</TITLE>
+ cheese_gtk_init
++cheese_gtk_init_with_args
+ </SECTION>
+
+ <SECTION>
+diff --git a/libcheese/cheese-gtk.c b/libcheese/cheese-gtk.c
+index f6f7715..008ebef 100644
+--- a/libcheese/cheese-gtk.c
++++ b/libcheese/cheese-gtk.c
+@@ -18,6 +18,7 @@
+ */
+
+ #include <gtk/gtk.h>
++#include <gst/gst.h>
+ #ifdef GDK_WINDOWING_X11
+ #include <X11/Xlib.h>
+ #endif
+@@ -65,3 +66,59 @@ cheese_gtk_init (int *argc, char ***argv)
+
+ return TRUE;
+ }
++
++/**
++ * cheese_gtk_init_with_args:
++ * @argc: pointer to the argument list count
++ * @argv: pointer to the argument list vector
++ * @parameter_string: string which is displayed in the first line of --help
++ * output, after programname [OPTION...]
++ * @entries: a NULL-terminated array of GOptionEntries describing the options
++ * of your program
++ * @translation_domain: a translation domain to use for translating the
++ * --help output for the options in entries with gettext(), or NULL
++ * @error: a return location for errors
++ *
++ * Initialize libcheese-gtk, by initializing Clutter, GStreamer and GTK+. This
++ * automatically calls cheese_init_with_args(), initializing libcheese.
++ *
++ * Returns: %TRUE if the initialization was successful, %FALSE otherwise
++ */
++gboolean
++cheese_gtk_init_with_args (int *argc, char ***argv,
++ const char *parameter_string,
++ GOptionEntry *entries,
++ const char *translation_domain,
++ GError **error)
++{
++ GOptionContext *context;
++ gboolean res;
++
++#ifdef GDK_WINDOWING_X11
++ /* We can't call clutter_gst_init() before gtk_clutter_init(), so no
++ * choice but to initialise X11 threading ourself */
++ XInitThreads ();
++#endif
++
++ /* We cannot simply call gtk_clutter_init_with_args() here, since that
++ * will result in the commandline being parsed without gst support. */
++ context = g_option_context_new (parameter_string);
++ g_option_context_add_main_entries (context, entries, translation_domain);
++ g_option_context_set_translation_domain (context, translation_domain);
++ g_option_context_add_group (context, gst_init_get_option_group ());
++ g_option_context_add_group (context, gtk_get_option_group (TRUE));
++ g_option_context_add_group (context, cogl_get_option_group ());
++ g_option_context_add_group (context,
++ clutter_get_option_group_without_init ());
++ g_option_context_add_group (context, gtk_clutter_get_option_group ());
++
++ res = g_option_context_parse (context, argc, argv, error);
++
++ g_option_context_free (context);
++
++ if (!res)
++ return FALSE;
++
++ return cheese_init_with_args (argc, argv, parameter_string, entries,
++ translation_domain, error);
++}
+diff --git a/libcheese/cheese-gtk.h b/libcheese/cheese-gtk.h
+index 77640e2..1a4f1b8 100644
+--- a/libcheese/cheese-gtk.h
++++ b/libcheese/cheese-gtk.h
+@@ -25,6 +25,11 @@
+ G_BEGIN_DECLS
+
+ gboolean cheese_gtk_init (int *argc, char ***argv);
++gboolean cheese_gtk_init_with_args (int *argc, char ***argv,
++ const char *parameter_string,
++ GOptionEntry *entries,
++ const char *translation_domain,
++ GError **error);
+
+ G_END_DECLS
+
+diff --git a/libcheese/cheese-gtk.symbols b/libcheese/cheese-gtk.symbols
+index fc43faf..a207c3d 100644
+--- a/libcheese/cheese-gtk.symbols
++++ b/libcheese/cheese-gtk.symbols
+@@ -1,4 +1,5 @@
+ cheese_gtk_init
++cheese_gtk_init_with_args
+ cheese_widget_get_type
+ cheese_widget_new
+ cheese_widget_get_camera
+diff --git a/libcheese/cheese.c b/libcheese/cheese.c
+index 0393562..fcab5a8 100644
+--- a/libcheese/cheese.c
++++ b/libcheese/cheese.c
+@@ -52,3 +52,28 @@ cheese_init (int *argc, char ***argv)
+
+ return TRUE;
+ }
++
++/**
++ * cheese_init_with_args:
++ * @argc: pointer to the argument list count
++ * @argv: pointer to the argument list vector
++ * @parameter_string: string which is displayed in the first line of --help
++ * output, after programname [OPTION...]
++ * @entries: a NULL-terminated array of GOptionEntries describing the options
++ * of your program
++ * @translation_domain: a translation domain to use for translating the
++ * --help output for the options in entries with gettext(), or NULL
++ * @error: a return location for errors
++ *
++ * Initialize libcheese, by initializing Clutter and GStreamer.
++ *
++ * Returns: %TRUE if the initialization was successful, %FALSE otherwise
++ */
++gboolean
++cheese_init_with_args (int *argc, char ***argv, const char *parameter_string,
++ GOptionEntry *entries, const char *translation_domain,
++ GError **error)
++{
++ return clutter_gst_init_with_args (argc, argv, parameter_string, entries,
++ translation_domain, error) == CLUTTER_INIT_SUCCESS;
++}
+diff --git a/libcheese/cheese.h b/libcheese/cheese.h
+index ec3239f..0f6e06c 100644
+--- a/libcheese/cheese.h
++++ b/libcheese/cheese.h
+@@ -25,6 +25,11 @@
+ G_BEGIN_DECLS
+
+ gboolean cheese_init (int *argc, char ***argv);
++gboolean cheese_init_with_args (int *argc, char ***argv,
++ const char *parameter_string,
++ GOptionEntry *entries,
++ const char *translation_domain,
++ GError **error);
+
+ G_END_DECLS
+
+diff --git a/src/vapi/cheese-common.vapi b/src/vapi/cheese-common.vapi
+index 075b594..e4d4bec 100644
+--- a/src/vapi/cheese-common.vapi
++++ b/src/vapi/cheese-common.vapi
+@@ -6,9 +6,23 @@ namespace Cheese
+ [CCode (cheader_filename = "cheese.h")]
+ public static bool init([CCode (array_length_pos = 0.9)] ref unowned string[] argv);
+
++ [CCode (cheader_filename = "cheese.h")]
++ public static bool init_with_args(
++ [CCode (array_length_pos = 0.9)] ref unowned string[] argv,
++ string parameter_string,
++ [CCode (array_length = false)] GLib.OptionEntry[] entries,
++ string? translation_domain) throws GLib.OptionError;
++
+ [CCode (cheader_filename = "cheese-gtk.h")]
+ public static bool gtk_init([CCode (array_length_pos = 0.9)] ref unowned string[] argv);
+
++ [CCode (cheader_filename = "cheese-gtk.h")]
++ public static bool gtk_init_with_args(
++ [CCode (array_length_pos = 0.9)] ref unowned string[] argv,
++ string parameter_string,
++ [CCode (array_length = false)] GLib.OptionEntry[] entries,
++ string? translation_domain) throws GLib.OptionError;
++
+ [CCode (cheader_filename = "cheese-effect.h")]
+ public class Effect : GLib.Object
+ {
+--
+1.8.2.1
+
diff --git a/0024-cheese-Use-cheese_gtk_init_with_args.patch b/0024-cheese-Use-cheese_gtk_init_with_args.patch
new file mode 100644
index 0000000..4f1d063
--- /dev/null
+++ b/0024-cheese-Use-cheese_gtk_init_with_args.patch
@@ -0,0 +1,196 @@
+From 5bcbdb44dd1cd4f0ed0a69a92a27634616e8df3e Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 13:28:11 +0200
+Subject: [PATCH 24/35] cheese: Use cheese_gtk_init_with_args
+
+Currently our --help output only shows gstreamer related info:
+
+[hans at shalem cheese]$ cheese --help
+Usage:
+ cheese [OPTION...] - GStreamer initialization
+
+Help Options:
+ -h, --help Show help options
+ --help-all Show all help options
+ --help-gst Show GStreamer Options
+
+This is caused by this gstreamer bug:
+https://bugzilla.gnome.org/show_bug.cgi?id=702089
+
+Besides suffering from this bug, our commandline parsing code also is not
+exactly pretty, and not a good example of how to do commandline parsing
+for other libcheese using applications.
+
+Also adding all the various option_groups manually is rather error prone
+ie currently the cogl group is missing.
+
+This patch fixes all this (including working around the --help issue)
+by using cheese_gtk_init_with_args, resulting in much simpler code.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 124 +++++++++++++--------------------------------------
+ 1 file changed, 30 insertions(+), 94 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index ac5ba6f..5905597 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -24,12 +24,21 @@ using Gtk;
+ using Clutter;
+ using Gst;
+
++static bool wide;
++static string device;
++static bool version;
++static bool fullscreen;
++
++const OptionEntry[] options = {
++ {"wide", 'w', 0, OptionArg.NONE, ref wide, N_("Start in wide mode"), null },
++ {"device", 'd', 0, OptionArg.FILENAME, ref device, N_("Device to use as a camera"), N_("DEVICE")},
++ {"version", 'v', 0, OptionArg.NONE, ref version, N_("Output version information and exit"), null },
++ {"fullscreen", 'f', 0, OptionArg.NONE, ref fullscreen, N_("Start in fullscreen mode"), null },
++ {null}
++};
++
+ public class Cheese.Main : Gtk.Application
+ {
+- static bool wide;
+- static string device;
+- static bool version;
+- static bool fullscreen;
+
+ static MainWindow main_window;
+
+@@ -47,14 +56,6 @@ public class Cheese.Main : Gtk.Application
+ { "quit", on_quit }
+ };
+
+- const OptionEntry[] options = {
+- {"wide", 'w', 0, OptionArg.NONE, ref wide, N_("Start in wide mode"), null },
+- {"device", 'd', 0, OptionArg.FILENAME, ref device, N_("Device to use as a camera"), N_("DEVICE")},
+- {"version", 'v', 0, OptionArg.NONE, ref version, N_("Output version information and exit"), null },
+- {"fullscreen", 'f', 0, OptionArg.NONE, ref fullscreen, N_("Start in fullscreen mode"), null },
+- {null}
+- };
+-
+ public Main (string app_id, ApplicationFlags flags)
+ {
+ GLib.Object (application_id: app_id, flags: flags);
+@@ -140,87 +141,6 @@ public class Cheese.Main : Gtk.Application
+ }
+ }
+
+- /**
+- * Overridden method of GApplication, to handle the arguments locally.
+- *
+- * @param arguments the command-line arguments
+- * @param exit_status the exit status to return to the OS
+- * @return true if the arguments were successfully processed, false otherwise
+- */
+- public override bool local_command_line ([CCode (array_null_terminated = true, array_length = false)]
+- ref unowned string[] arguments,
+- out int exit_status)
+- {
+- // Try to register.
+- try
+- {
+- register();
+- }
+- catch (Error e)
+- {
+- stdout.printf ("Error: %s\n", e.message);
+- exit_status = 1;
+- return true;
+- }
+-
+- // Workaround until bug 642885 is solved.
+- unowned string[] local_args = arguments;
+-
+- // Check command line parameters.
+- int n_args = local_args.length;
+- if (n_args <= 1)
+- {
+- Gst.init (ref local_args);
+- activate ();
+- exit_status = 0;
+- }
+- else
+- {
+- // Set parser.
+- try
+- {
+- var context = new OptionContext (_("- Take photos and videos from your webcam"));
+- context.set_translation_domain (Config.GETTEXT_PACKAGE);
+- context.set_help_enabled (true);
+- context.add_main_entries (options, null);
+- context.add_group (Gtk.get_option_group (true));
+- context.add_group (Clutter.get_option_group ());
+- context.add_group (Gst.init_get_option_group ());
+- context.parse (ref local_args);
+- }
+- catch (OptionError e)
+- {
+- stdout.printf ("%s\n", e.message);
+- stdout.printf (_("Run '%s --help' to see a full list of available command line options.\n"), arguments[0]);
+- exit_status = 1;
+- return true;
+- }
+-
+- if (version)
+- {
+- stdout.printf ("%s %s\n", Config.PACKAGE_NAME, Config.PACKAGE_VERSION);
+- exit_status = 1;
+- return true;
+- }
+-
+- //Remote instance process commands locally.
+- if (get_is_remote ())
+- {
+- stdout.printf (_("Another instance of Cheese is currently running\n"));
+- exit_status = 1;
+- return true;
+- }
+- //Primary instance.
+- else
+- {
+- Gst.init (ref local_args);
+- activate ();
+- exit_status=0;
+- }
+- }
+- return true;
+- }
+-
+ /**
+ * Setup the camera listed in GSettings.
+ *
+@@ -543,8 +463,24 @@ public class Cheese.Main : Gtk.Application
+ Intl.bind_textdomain_codeset (Config.GETTEXT_PACKAGE, "UTF-8");
+ Intl.textdomain (Config.GETTEXT_PACKAGE);
+
+- if (!Cheese.gtk_init (ref args))
++ try
++ {
++ Cheese.gtk_init_with_args (ref args,
++ _("- Take photos and videos from your webcam"),
++ options, Config.GETTEXT_PACKAGE);
++ }
++ catch (OptionError e)
++ {
++ stdout.printf ("%s\n", e.message);
++ stdout.printf (_("Run '%s --help' to see a full list of available command line options.\n"), args[0]);
+ return Posix.EXIT_FAILURE;
++ }
++
++ if (version)
++ {
++ stdout.printf ("%s %s\n", Config.PACKAGE_NAME, Config.PACKAGE_VERSION);
++ return Posix.EXIT_SUCCESS;
++ }
+
+ Cheese.Main app;
+ app = new Cheese.Main ("org.gnome.Cheese", ApplicationFlags.FLAGS_NONE);
+--
+1.8.2.1
+
diff --git a/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch b/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch
new file mode 100644
index 0000000..6e18eaa
--- /dev/null
+++ b/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch
@@ -0,0 +1,206 @@
+From 29a1bab965e67b39eb0eef44038a1400d6de6029 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 17:26:25 +0200
+Subject: [PATCH 25/35] cheese: Remove last remnants of the old menu code
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ data/cheese-actions.ui | 18 -----------
+ src/cheese-window.vala | 85 +++++++++++++++++---------------------------------
+ 2 files changed, 29 insertions(+), 74 deletions(-)
+
+diff --git a/data/cheese-actions.ui b/data/cheese-actions.ui
+index 2374c36..8657c08 100644
+--- a/data/cheese-actions.ui
++++ b/data/cheese-actions.ui
+@@ -46,24 +46,6 @@
+ </object>
+ <accelerator key="Delete" modifiers="GDK_SHIFT_MASK"/>
+ </child>
+- <child>
+- <object class="GtkAction" id="move_all_to_trash">
+- <property name="name">RemoveAll</property>
+- <property name="label" translatable="yes">Move _All to Trash</property>
+- <signal name="activate" handler="cheese_main_window_on_file_move_to_trash_all"/>
+- </object>
+- </child>
+- </object>
+- </child>
+- <child>
+- <object class="GtkActionGroup" id="layout_actions">
+- <child>
+- <object class="GtkToggleAction" id="wide_mode">
+- <property name="name">WideMode</property>
+- <property name="label" translatable="yes">_Wide Mode</property>
+- <signal name="toggled" handler="cheese_main_window_on_layout_wide_mode"/>
+- </object>
+- </child>
+ </object>
+ </child>
+ <child>
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index e8ccb47..6425a7f 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -79,7 +79,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ private List<Clutter.Box> effects_grids;
+
+ private HashTable<string, bool> action_sensitivities;
+- private Gtk.ToggleAction wide_mode_action;
+ private Gtk.Action countdown_action;
+ private Gtk.Action effects_page_prev_action;
+ private Gtk.Action effects_page_next_action;
+@@ -494,41 +493,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ }
+
+ /**
+- * Toggle wide mode and save the preference to GSettings.
+- *
+- * @param action the action that emitted the signal
+- */
+- [CCode (instance_pos = -1)]
+- public void on_layout_wide_mode (ToggleAction action)
+- {
+- if (!is_command_line_startup)
+- {
+- /* Don't save to settings when using -w mode from command-line, so
+- * command-line options change the mode for one run only. */
+- settings.set_boolean ("wide-mode", action.active);
+- }
+- set_wide_mode (action.active);
+- }
+-
+- /**
+- * Toggle fullscreen mode and save the preference to GSettings.
+- *
+- * @param fullscreen whether the window should be fullscreean
+- */
+- [CCode (instance_pos = -1)]
+- public void set_fullscreen (bool fullscreen)
+- {
+- if (!is_command_line_startup)
+- {
+- /* Don't save to settings when using -f mode from command-line, so
+- * command-line options change the mode for one run only. */
+- settings.set_boolean ("fullscreen", fullscreen);
+- }
+-
+- set_fullscreen_mode (fullscreen);
+- }
+-
+- /**
+ * Make the media capture mode actions sensitive.
+ */
+ private void enable_mode_change ()
+@@ -657,19 +621,28 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ }
+
+ /**
+- * Enable or disable fullscreen mode to the requested state.
++ * Enable or disable fullscreen mode
+ *
+- * @param fullscreen_mode whether to enable or disable fullscreen mode
++ * @param fullscreen whether the window should be fullscreean
+ */
+- private void set_fullscreen_mode (bool fullscreen_mode)
++ [CCode (instance_pos = -1)]
++ public void set_fullscreen (bool fullscreen)
+ {
+ /* After the first time the window has been shown using this.show_all (),
+ * the value of leave_fullscreen_button_container.no_show_all should be set to false
+ * So that the next time leave_fullscreen_button_container.show_all () is called, the button is actually shown
+ * FIXME: If this code can be made cleaner/clearer, please do */
+
+- is_fullscreen = fullscreen_mode;
+- if (fullscreen_mode)
++ is_fullscreen = fullscreen;
++
++ if (!is_command_line_startup)
++ {
++ /* Don't save to settings when using -f mode from command-line, so
++ * command-line options change the mode for one run only. */
++ settings.set_boolean ("fullscreen", is_fullscreen);
++ }
++
++ if (is_fullscreen)
+ {
+ if (is_wide_mode)
+ {
+@@ -722,14 +695,23 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ }
+
+ /**
+- * Enable or disable wide mode to the requested state.
++ * Enable or disable wide mode to the requested state and save the
++ * preference to GSettings.
+ *
+ * @param wide_mode whether to enable or disable wide mode
+ */
+- private void set_wide_mode (bool wide_mode)
++ [CCode (instance_pos = -1)]
++ public void set_wide_mode (bool wide_mode)
+ {
+ is_wide_mode = wide_mode;
+
++ if (!is_command_line_startup)
++ {
++ /* Don't save to settings when using -w mode from command-line, so
++ * command-line options change the mode for one run only. */
++ settings.set_boolean ("wide-mode", is_wide_mode);
++ }
++
+ /* keep the viewport to its current size while rearranging the ui,
+ * so that thumbview moves from right to bottom and viceversa
+ * while the rest of the window stays unchanged */
+@@ -1298,13 +1280,12 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+
+ /* Keep only these actions sensitive. */
+ string [] active_actions = { "quit",
+- "help_contents",
++ "help",
+ "about",
+ "open",
+ "save_as",
+ "move_to_trash",
+- "delete",
+- "move_all_to_trash"};
++ "delete"};
+
+ /* Gross hack because Vala's `in` operator doesn't really work */
+ bool flag;
+@@ -1358,7 +1339,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ }
+
+ is_command_line_startup = true;
+- wide_mode_action.set_active (true);
++ set_wide_mode (true);
+ is_command_line_startup = false;
+ }
+
+@@ -1414,7 +1395,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ thumbnail_popup = gtk_builder.get_object ("thumbnail_popup") as Gtk.Menu;
+
+ countdown_action = gtk_builder.get_object ("countdown") as Gtk.Action;
+- wide_mode_action = gtk_builder.get_object ("wide_mode") as Gtk.ToggleAction;
+ effects_page_next_action = gtk_builder.get_object ("effects_page_next") as Gtk.Action;
+ effects_page_prev_action = gtk_builder.get_object ("effects_page_prev") as Gtk.Action;
+ share_action = gtk_builder.get_object ("share") as Gtk.Action;
+@@ -1477,14 +1457,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ * if the widget is not realized */
+ viewport_widget.realize ();
+
+- /* call set_active instead of our set_wide_mode so that the toggle
+- * action state is updated */
+- wide_mode_action.set_active (settings.get_boolean ("wide-mode"));
+-
+- /* apparently set_active doesn't emit toggled nothing has
+- * changed, do it manually */
+- if (!settings.get_boolean ("wide-mode"))
+- wide_mode_action.toggled ();
++ set_wide_mode (settings.get_boolean ("wide-mode"));
+
+ set_mode (MediaMode.PHOTO);
+ setup_effects_selector ();
+--
+1.8.2.1
+
diff --git a/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch b/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch
new file mode 100644
index 0000000..5413575
--- /dev/null
+++ b/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch
@@ -0,0 +1,52 @@
+From b0bdc5489ab2476bac63fcf2919f92efe743c828 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 17:54:02 +0200
+Subject: [PATCH 26/35] cheese: Protect set_wide_mode / set_fullscreen against
+ double calls
+
+Make it safe to call set_wide_mode / set_fullscreen twice with the same
+value.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 6425a7f..906105b 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -86,6 +86,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+
+ private bool is_fullscreen;
+ private bool is_wide_mode;
++ private bool is_wide_mode_initialized;
+ private bool is_recording; /* Video Recording Flag */
+ private bool is_bursting;
+ private bool is_effects_selector_active;
+@@ -633,6 +634,10 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ * So that the next time leave_fullscreen_button_container.show_all () is called, the button is actually shown
+ * FIXME: If this code can be made cleaner/clearer, please do */
+
++ if (is_fullscreen == fullscreen)
++ {
++ return;
++ }
+ is_fullscreen = fullscreen;
+
+ if (!is_command_line_startup)
+@@ -703,6 +708,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ [CCode (instance_pos = -1)]
+ public void set_wide_mode (bool wide_mode)
+ {
++ if (is_wide_mode_initialized && is_wide_mode == wide_mode)
++ {
++ return;
++ }
++ is_wide_mode_initialized = true;
+ is_wide_mode = wide_mode;
+
+ if (!is_command_line_startup)
+--
+1.8.2.1
+
diff --git a/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch b/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch
new file mode 100644
index 0000000..9b3d5d6
--- /dev/null
+++ b/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch
@@ -0,0 +1,94 @@
+From bd78a9a2a02dbc8c7513c73579dfd5ce848ae9f2 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 17:59:13 +0200
+Subject: [PATCH 27/35] cheese: Get rid of special set_startup_foo() functions
+
+So that cheese-main can toggle / activate the related actions when parsing
+the cmdline and thus have the action state properly reflects the actual state,
+avoiding ie the need to press F11 twice to leave fullscreen after starting
+cheese with -f.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 7 +++++--
+ src/cheese-window.vala | 31 ++-----------------------------
+ 2 files changed, 7 insertions(+), 31 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index 5905597..e4f2460 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -126,9 +126,12 @@ public class Cheese.Main : Gtk.Application
+ main_window.start_thumbview_monitors ();
+
+ if (wide)
+- main_window.set_startup_wide_mode ();
++ main_window.set_wide_mode (true);
+ if (fullscreen)
+- main_window.set_startup_fullscreen_mode ();
++ main_window.set_fullscreen (true);
++
++ /* Tell the main window to save any changes from here on to GSettings */
++ main_window.is_command_line_startup = false;
+
+ /* Shoot when the webcam capture button is pressed. */
+ main_window.add_events (Gdk.EventMask.KEY_PRESS_MASK
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 906105b..7a3db6b 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -92,7 +92,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ private bool is_effects_selector_active;
+ private bool is_camera_actions_sensitive;
+ private bool action_cancelled;
+- private bool is_command_line_startup;
++ public bool is_command_line_startup;
+
+ private Gtk.Button[] buttons;
+ private Gtk.Button[] mode_buttons;
+@@ -122,6 +122,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ public MainWindow (Gtk.Application application)
+ {
+ GLib.Object (application: application);
++ is_command_line_startup = true;
+ }
+
+ /**
+@@ -1337,34 +1338,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ }
+
+ /**
+- * Set wide mode active when started from the command line (and do not change
+- * the GSetting).
+- */
+- public void set_startup_wide_mode ()
+- {
+- if (is_wide_mode)
+- {
+- /* Cheese was already in wide mode, avoid setting it again. */
+- return;
+- }
+-
+- is_command_line_startup = true;
+- set_wide_mode (true);
+- is_command_line_startup = false;
+- }
+-
+- /**
+- * Set fullscreen mode active when started from the command line (and do not
+- * change the GSetting).
+- */
+- public void set_startup_fullscreen_mode ()
+- {
+- is_command_line_startup = true;
+- set_fullscreen (true);
+- is_command_line_startup = false;
+- }
+-
+- /**
+ * Load the UI from the GtkBuilder description.
+ */
+ public void setup_ui ()
+--
+1.8.2.1
+
diff --git a/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch b/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch
new file mode 100644
index 0000000..f07b6e1
--- /dev/null
+++ b/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch
@@ -0,0 +1,32 @@
+From cfc2a636dca6e859e0c6ae8ea4a5fd53238dc9b9 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Wed, 12 Jun 2013 18:03:23 +0200
+Subject: [PATCH 28/35] cheese: Fix the need to press F11 twice after starting
+ with -f
+
+Change the fullscreen action state, rather then directly calling set_fullscreen
+so that the action state properly reflects the actual fullscreen state,
+avoiding the need to press F11 twice to leave fullscreen after starting
+cheese with -f.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index e4f2460..032e8cb 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -128,7 +128,7 @@ public class Cheese.Main : Gtk.Application
+ if (wide)
+ main_window.set_wide_mode (true);
+ if (fullscreen)
+- main_window.set_fullscreen (true);
++ change_action_state("fullscreen", true);
+
+ /* Tell the main window to save any changes from here on to GSettings */
+ main_window.is_command_line_startup = false;
+--
+1.8.2.1
+
diff --git a/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch b/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch
new file mode 100644
index 0000000..f14bfef
--- /dev/null
+++ b/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch
@@ -0,0 +1,68 @@
+From 7ca2edc8abfcba8384455a180a3c2e4f841abdfd Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 09:40:18 +0200
+Subject: [PATCH 29/35] cheese: Make widemode controllable from the app menu
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 23 ++++++++++++++++++++++-
+ 1 file changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index 032e8cb..2adfdc0 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -49,6 +49,7 @@ public class Cheese.Main : Gtk.Application
+ { "shoot", on_shoot },
+ { "mode", on_action_radio, "s", "'photo'", on_mode_change },
+ { "fullscreen", on_action_toggle, null, "false", on_fullscreen_change },
++ { "widemode", on_action_toggle, null, "false", on_widemode_change },
+ { "effects", on_action_toggle, null, "false", on_effects_change },
+ { "preferences", on_preferences },
+ { "about", on_about },
+@@ -103,6 +104,9 @@ public class Cheese.Main : Gtk.Application
+ item = new GLib.MenuItem (_("_Fullscreen"), "app.fullscreen");
+ item.set_attribute ("accel", "s", "F11");
+ section.append_item (item);
++ item = new GLib.MenuItem (_("_Wide Mode"), "app.widemode");
++ item.set_attribute ("accel", "s", "w");
++ section.append_item (item);
+ section = new GLib.Menu ();
+ menu.append_section (null, section);
+ section.append (_("_Effects"), "app.effects");
+@@ -126,7 +130,7 @@ public class Cheese.Main : Gtk.Application
+ main_window.start_thumbview_monitors ();
+
+ if (wide)
+- main_window.set_wide_mode (true);
++ change_action_state("widemode", true);
+ if (fullscreen)
+ change_action_state("fullscreen", true);
+
+@@ -324,6 +328,23 @@ public class Cheese.Main : Gtk.Application
+ }
+
+ /**
++ * Handle wide mode being toggled on / off.
++ *
++ * @param action the action that emitted the signal
++ * @param value the state to switch to
++ */
++ private void on_widemode_change (SimpleAction action, Variant? value)
++ {
++ return_if_fail (value != null);
++
++ var state = value.get_boolean ();
++
++ main_window.set_wide_mode (state);
++
++ action.set_state (value);
++ }
++
++ /**
+ * Handle the effects state being changed.
+ *
+ * @param action the action that emitted the signal
+--
+1.8.2.1
+
diff --git a/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch b/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch
new file mode 100644
index 0000000..d3e27b9
--- /dev/null
+++ b/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch
@@ -0,0 +1,54 @@
+From ac1d5ac64b9c8371bfabb144a77e053b38ff63c5 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 09:48:11 +0200
+Subject: [PATCH 30/35] cheese: Move reading of widemode setting to cheese-main
+
+So that the actiontoggle's state always properly reflects the actual
+wide-mode setting.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 4 ++++
+ src/cheese-window.vala | 4 ++--
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index 2adfdc0..d0f9b41 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -129,6 +129,10 @@ public class Cheese.Main : Gtk.Application
+ main_window.setup_ui ();
+ main_window.start_thumbview_monitors ();
+
++ /* If not set from the cmdline, get the settings from config file */
++ if (!wide)
++ wide = main_window.settings.get_boolean ("wide-mode");
++
+ if (wide)
+ change_action_state("widemode", true);
+ if (fullscreen)
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index 7a3db6b..c75c5f0 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -44,7 +44,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ private Gtk.Builder gtk_builder;
+ private Clutter.Script clutter_builder;
+
+- private GLib.Settings settings;
++ public GLib.Settings settings;
+
+ private Gtk.Widget thumbnails;
+ private GtkClutter.Embed viewport_widget;
+@@ -1440,7 +1440,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ * if the widget is not realized */
+ viewport_widget.realize ();
+
+- set_wide_mode (settings.get_boolean ("wide-mode"));
++ set_wide_mode (false);
+
+ set_mode (MediaMode.PHOTO);
+ setup_effects_selector ();
+--
+1.8.2.1
+
diff --git a/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch b/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch
new file mode 100644
index 0000000..e36b16f
--- /dev/null
+++ b/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch
@@ -0,0 +1,34 @@
+From 435f7bb98f99affa437dd3cc2cd71fafb4a42332 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 09:51:04 +0200
+Subject: [PATCH 31/35] cheese: Fix reading of fullscreen setting from config
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-main.vala | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/cheese-main.vala b/src/cheese-main.vala
+index d0f9b41..9ba1a5f 100644
+--- a/src/cheese-main.vala
++++ b/src/cheese-main.vala
+@@ -124,14 +124,14 @@ public class Cheese.Main : Gtk.Application
+ section.append_item (item);
+ set_app_menu (menu);
+
+- // FIXME: Read fullscreen state from GSettings.
+-
+ main_window.setup_ui ();
+ main_window.start_thumbview_monitors ();
+
+ /* If not set from the cmdline, get the settings from config file */
+ if (!wide)
+ wide = main_window.settings.get_boolean ("wide-mode");
++ if (!fullscreen)
++ fullscreen = main_window.settings.get_boolean ("fullscreen");
+
+ if (wide)
+ change_action_state("widemode", true);
+--
+1.8.2.1
+
diff --git a/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch b/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch
new file mode 100644
index 0000000..9c07761
--- /dev/null
+++ b/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch
@@ -0,0 +1,53 @@
+From fa71136c97624724befd0d35cb5a319da30c0afd Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 10:05:46 +0200
+Subject: [PATCH 32/35] cheese: Don't show thumbnails when toggling widemode in
+ fullscreen
+
+This can be done for example from the app-menu when in fullscreen mode on
+a secondary monitor.
+
+Also remove the unnecessary resize calls.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-window.vala | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/src/cheese-window.vala b/src/cheese-window.vala
+index c75c5f0..25d9506 100644
+--- a/src/cheese-window.vala
++++ b/src/cheese-window.vala
+@@ -739,9 +739,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ thumbnails_bottom.remove (thumb_nav);
+ }
+ thumbnails_right.add (thumb_nav);
+- thumbnails_right.show_all ();
+- thumbnails_right.resize_children ();
+- thumbnails_bottom.hide ();
++ if (!is_fullscreen)
++ {
++ thumbnails_right.show_all ();
++ thumbnails_bottom.hide ();
++ }
+ }
+ else
+ {
+@@ -752,9 +754,11 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow
+ thumbnails_right.remove (thumb_nav);
+ }
+ thumbnails_bottom.add (thumb_nav);
+- thumbnails_bottom.show_all ();
+- thumbnails_bottom.resize_children ();
+- thumbnails_right.hide ();
++ if (!is_fullscreen)
++ {
++ thumbnails_bottom.show_all ();
++ thumbnails_right.hide ();
++ }
+ }
+
+ /* handy trick to keep the window to the desired size while not
+--
+1.8.2.1
+
diff --git a/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch b/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch
new file mode 100644
index 0000000..cafd6bb
--- /dev/null
+++ b/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch
@@ -0,0 +1,54 @@
+From 1b2af9add59924b46b524bd7b64bbaf12e875a57 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 10:30:02 +0200
+Subject: [PATCH 33/35] cheese: Fix updating of device selection combo
+ sensitivity on hotplug
+
+If one started cheese with 1 device, and then added a 2nd, the device selection
+stayed inactive, making it impossible to select the 2nd device.
+
+This fixes this, and also makes the combo go insensitive again when going from
+>= 2 devices to <= 1 device.
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/cheese-preferences.vala | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala
+index d4d5501..e078cbb 100644
+--- a/src/cheese-preferences.vala
++++ b/src/cheese-preferences.vala
+@@ -136,8 +136,7 @@ public class Cheese.PreferencesDialog : GLib.Object
+ camera_model = new ListStore (2, typeof (string), typeof (Cheese.CameraDevice));
+
+ source_combo.model = camera_model;
+- if (devices.len <= 1)
+- source_combo.sensitive = false;
++ source_combo.sensitive = false;
+
+ devices.foreach(add_camera_device);
+
+@@ -499,6 +498,9 @@ public class Cheese.PreferencesDialog : GLib.Object
+
+ if (camera.get_selected_device ().get_device_node () == dev.get_device_node ())
+ source_combo.set_active_iter (iter);
++
++ if (camera_model.iter_n_children (null) > 1)
++ source_combo.sensitive = true;
+ }
+
+ /**
+@@ -522,6 +524,9 @@ public class Cheese.PreferencesDialog : GLib.Object
+ this.dialog.hide();
+ }
+ camera_model.remove (iter);
++
++ if (camera_model.iter_n_children (null) <= 1)
++ source_combo.sensitive = false;
+ }
+
+ /**
+--
+1.8.2.1
+
diff --git a/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch b/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch
new file mode 100644
index 0000000..6e7dd37
--- /dev/null
+++ b/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch
@@ -0,0 +1,38 @@
+From f6d7f1e2a240641080b8d87a169c22571d39316c Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 11:37:19 +0200
+Subject: [PATCH 34/35] cheese: Fix assert failures when taking a photo
+
+Before this patch, cheese would log the following each time the user takes
+a photo:
+
+(cheese:21719): GLib-GIO-CRITICAL **: g_file_info_get_size: assertion `G_IS_FILE_INFO (info)' failed
+
+(cheese:21719): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ src/thumbview/cheese-thumb-view.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/thumbview/cheese-thumb-view.c b/src/thumbview/cheese-thumb-view.c
+index c229b1a..a702fc0 100644
+--- a/src/thumbview/cheese-thumb-view.c
++++ b/src/thumbview/cheese-thumb-view.c
+@@ -205,6 +205,13 @@ cheese_thumb_view_append_item (CheeseThumbView *thumb_view, GFile *file)
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, 0, NULL,
+ NULL);
++ if (!info)
++ {
++ /* This is normal since photos first get created with a tmpname, ie:
++ * "2013-06-13-113155.jpg.DQRGYW" and then moved to their final name,
++ * we will get another append_item call for the final name. */
++ return;
++ }
+ size = g_file_info_get_size (info);
+ g_object_unref (info);
+
+--
+1.8.2.1
+
diff --git a/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch b/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch
new file mode 100644
index 0000000..475c67e
--- /dev/null
+++ b/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch
@@ -0,0 +1,65 @@
+From 81ad92ad8228ba36209130ed4eaf67752ea79bb8 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede at redhat.com>
+Date: Thu, 13 Jun 2013 12:39:44 +0200
+Subject: [PATCH 35/35] cheese-flash: Fix the flash no longer being white
+
+Signed-off-by: Hans de Goede <hdegoede at redhat.com>
+---
+ libcheese/cheese-flash.c | 23 ++++-------------------
+ 1 file changed, 4 insertions(+), 19 deletions(-)
+
+diff --git a/libcheese/cheese-flash.c b/libcheese/cheese-flash.c
+index fd46818..37cd36d 100644
+--- a/libcheese/cheese-flash.c
++++ b/libcheese/cheese-flash.c
+@@ -76,29 +76,13 @@ struct _CheeseFlashPrivate
+ guint fade_timeout_tag;
+ };
+
+-/*
+- * cheese_flash_draw_event_cb:
+- * @widget: the #CheeseFlash
+- * @cr: the Cairo context
+- * @user_data: the user data of the signal
+- *
+- * Draw the flash.
+- *
+- * Returns: %TRUE
+- */
+-static gboolean
+-cheese_flash_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer user_data)
+-{
+- cairo_fill (cr);
+- return TRUE;
+-}
+-
+ static void
+ cheese_flash_init (CheeseFlash *self)
+ {
+ CheeseFlashPrivate *priv = self->priv = CHEESE_FLASH_GET_PRIVATE (self);
+ cairo_region_t *input_region;
+ GtkWindow *window = GTK_WINDOW (self);
++ const GdkColor white = { 0, 65535, 65535, 65535 };
+
+ priv->flash_timeout_tag = 0;
+ priv->fade_timeout_tag = 0;
+@@ -113,13 +97,14 @@ cheese_flash_init (CheeseFlash *self)
+ gtk_window_set_accept_focus (window, FALSE);
+ gtk_window_set_focus_on_map (window, FALSE);
+
++ /* Make it white */
++ gtk_widget_modify_bg (GTK_WIDGET (window), GTK_STATE_NORMAL, &white);
++
+ /* Don't consume input */
+ gtk_widget_realize (GTK_WIDGET (window));
+ input_region = cairo_region_create ();
+ gdk_window_input_shape_combine_region (gtk_widget_get_window (GTK_WIDGET (window)), input_region, 0, 0);
+ cairo_region_destroy (input_region);
+-
+- g_signal_connect (G_OBJECT (window), "draw", G_CALLBACK (cheese_flash_draw_event_cb), NULL);
+ }
+
+ static void
+--
+1.8.2.1
+
diff --git a/cheese.spec b/cheese.spec
index f40674e..4284d5f 100644
--- a/cheese.spec
+++ b/cheese.spec
@@ -1,7 +1,7 @@
Name: cheese
Epoch: 2
Version: 3.8.2
-Release: 2%{?dist}
+Release: 3%{?dist}
Summary: Application for taking pictures and movies from a webcam
Group: Amusements/Graphics
@@ -9,6 +9,49 @@ License: GPLv2+
URL: http://projects.gnome.org/cheese/
#VCS: git:git://git.gnome.org/cheese
Source0: http://download.gnome.org/sources/cheese/3.8/%{name}-%{version}.tar.xz
+
+# HdG: since I hit a couple of issues in cheese, and cheese needed some loving
+# in general I ended up doing a whole lot of *bugfix* patches for cheese,
+# fixing various performance / device compatibility issues, but also things
+# like needing to press some buttons twice before they work, etc.
+# See here for a bug for tracking the upstreaming of this patchset:
+# https://bugzilla.gnome.org/show_bug.cgi?id=702264
+Patch1: 0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch
+Patch2: 0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch
+Patch3: 0003-cheese-camera-Set-image-and-video-capture-caps.patch
+Patch4: 0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch
+Patch5: 0005-cheese-camera-2-minor-error-handling-cleanups.patch
+Patch6: 0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch
+Patch7: 0007-cheese-camera-Remove-unused-enum.patch
+Patch8: 0008-cheese-camera-device-Fix-compiler-warning.patch
+Patch9: 0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch
+Patch10: 0010-cheese-camera-device-Keep-track-of-highest-available.patch
+Patch11: 0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch
+Patch12: 0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch
+Patch13: 0013-cheese-camera-device-get_caps_for_format-simplify-th.patch
+Patch14: 0014-cheese-camera-device-Make-get_best_format-smarter.patch
+Patch15: 0015-cheese-camera-device-Plug-some-memory-leaks.patch
+Patch16: 0016-cheese-camera-Drop-unused-preview_caps.patch
+Patch17: 0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch
+Patch18: 0018-cheese-camera-Check-for-the-current-effect-being-the.patch
+Patch19: 0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch
+Patch20: 0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch
+Patch21: 0021-cheese-window-Fix-de-activation-of-effects-button.patch
+Patch22: 0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch
+Patch23: 0023-libcheese-Add-_init_with_args-init-function-variants.patch
+Patch24: 0024-cheese-Use-cheese_gtk_init_with_args.patch
+Patch25: 0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch
+Patch26: 0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch
+Patch27: 0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch
+Patch28: 0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch
+Patch29: 0029-cheese-Make-widemode-controllable-from-the-app-menu.patch
+Patch30: 0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch
+Patch31: 0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch
+Patch32: 0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch
+Patch33: 0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch
+Patch34: 0034-cheese-Fix-assert-failures-when-taking-a-photo.patch
+Patch35: 0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch
+
# https://bugzilla.gnome.org/show_bug.cgi?id=678447
# Patch2: 0002-Setup-vp8enc-in-a-way-suitable-for-realtime-encoding.patch
@@ -41,7 +84,7 @@ BuildRequires: libxslt
BuildRequires: docbook-style-xsl
BuildRequires: /usr/bin/convert
-Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
Requires: gstreamer1-plugins-good
Requires: gstreamer1-plugins-bad-free
Requires: gnome-video-effects
@@ -51,19 +94,19 @@ Cheese is a Photobooth-inspired GNOME application for taking pictures and
videos from a webcam. It can also apply fancy graphical effects.
%package libs
-Summary: Webcam display and capture widgets
-Group: System Environment/Libraries
-License: GPLv2+
+Summary: Webcam display and capture widgets
+Group: System Environment/Libraries
+License: GPLv2+
%description libs
This package contains libraries needed for applications that
want to display a webcam in their interface.
%package libs-devel
-Summary: Development files for %{name}-libs
-Group: Development/Libraries
-License: GPLv2+
-Requires: %{name}-libs = %{epoch}:%{version}-%{release}
+Summary: Development files for %{name}-libs
+Group: Development/Libraries
+License: GPLv2+
+Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release}
%description libs-devel
This package contains the libraries and header files that are needed
@@ -71,7 +114,41 @@ for writing applications that require a webcam display widget.
%prep
%setup -q
-# %patch2 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
%build
@@ -85,10 +162,10 @@ make install DESTDIR=$RPM_BUILD_ROOT
rm -f $RPM_BUILD_ROOT%{_libdir}/libcheese.{a,la}
rm -f $RPM_BUILD_ROOT%{_libdir}/libcheese-gtk.{a,la}
-desktop-file-install --delete-original --vendor="" \
- --dir=$RPM_BUILD_ROOT%{_datadir}/applications \
- --add-category X-AudioVideoImport \
- $RPM_BUILD_ROOT%{_datadir}/applications/cheese.desktop
+desktop-file-install --delete-original --vendor="" \
+ --dir=$RPM_BUILD_ROOT%{_datadir}/applications \
+ --add-category X-AudioVideoImport \
+ $RPM_BUILD_ROOT%{_datadir}/applications/cheese.desktop
%find_lang %{name} --with-gnome
@@ -123,7 +200,7 @@ fi
glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%files
-%doc AUTHORS COPYING README
+%doc AUTHORS README
%{_bindir}/cheese
%{_datadir}/applications/cheese.desktop
%{_datadir}/cheese
@@ -131,17 +208,15 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%{_datadir}/icons/hicolor/*/actions/*.png
%{_datadir}/icons/hicolor/scalable/actions/*.svg
%{_mandir}/man1/cheese.1.gz
-# FIXME find-lang is supposed to pick these up
-%doc %{_datadir}/help/*/cheese
%files -f %{name}.lang libs
+%doc COPYING
%{_libdir}/libcheese.so.*
%{_libdir}/libcheese-gtk.so.*
%{_datadir}/glib-2.0/schemas/org.gnome.Cheese.gschema.xml
%{_libdir}/girepository-1.0/Cheese-3.0.typelib
%files libs-devel
-%doc COPYING
%{_libdir}/libcheese.so
%{_libdir}/libcheese-gtk.so
%{_includedir}/cheese/
@@ -151,6 +226,15 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
%{_datadir}/gir-1.0/Cheese-3.0.gir
%changelog
+* Mon Jun 17 2013 Hans de Goede <hdegoede at redhat.com> - 2:3.8.2-3
+- Add a number of bug-fixes to deal better with high res cams (#873434)
+- Fix cheese-introduction.png being in both cheese and cheese-libs (#893756)
+- Put the COPYING file in the docs for cheese-libs (#893800)
+- Fix the flash when taking a photo being dark grey instead of white (#965813)
+- Fix needing to press the effects button twice to select effects after
+ selecting an effect for the first time
+- Various other bug-fixes
+
* Tue May 14 2013 Matthias Clasen <mclasen at redhat.com> - 2:3.8.2-2
- Conserve space by shrinking images
@@ -357,7 +441,7 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
* Thu Aug 19 2010 Matthias Clasen <mclasen at redhat.com> 1:2.31.90-1
- Update to 2.31.90
-* Fri Aug 11 2010 Matthias Clasen <mclasen at redhat.com> 1:2.31.1-2
+* Wed Aug 11 2010 Matthias Clasen <mclasen at redhat.com> 1:2.31.1-2
- Add an epoch to stay ahead of F14
* Fri Aug 6 2010 Matthias Clasen <mclasen at redhat.com> 2.31.1-1
@@ -457,7 +541,7 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
* Wed Dec 3 2008 Matthias Clasen <mclasen at redhat.com> 2.25.2-1
- Update to 2.25.2
-* Thu Nov 21 2008 Matthias Clasen <mclasen at redhat.com> 2.25.1-4
+* Fri Nov 21 2008 Matthias Clasen <mclasen at redhat.com> 2.25.1-4
- Better URL
* Thu Nov 13 2008 Matthias Clasen <mclasen at redhat.com> 2.25.1-3
More information about the scm-commits
mailing list