diff --git a/.cheese.metadata b/.cheese.metadata new file mode 100644 index 0000000..40cbe00 --- /dev/null +++ b/.cheese.metadata @@ -0,0 +1 @@ +a3dd2105201a01860aaebf438cc1e211384c687f SOURCES/cheese-3.8.2.tar.xz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch b/SOURCES/0001-cheese-camera-Add-a-capsfilter-to-our-video-source-b.patch new file mode 100644 index 0000000..a4569a7 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch b/SOURCES/0002-cheese-camera-remove-extranous-csp_post_balance-vide.patch new file mode 100644 index 0000000..091ac69 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0003-cheese-camera-Set-image-and-video-capture-caps.patch b/SOURCES/0003-cheese-camera-Set-image-and-video-capture-caps.patch new file mode 100644 index 0000000..203bf5b --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch b/SOURCES/0004-cheese-camera-Fix-the-no-video-after-switching-resol.patch new file mode 100644 index 0000000..c7936d1 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0005-cheese-camera-2-minor-error-handling-cleanups.patch b/SOURCES/0005-cheese-camera-2-minor-error-handling-cleanups.patch new file mode 100644 index 0000000..b80f076 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch b/SOURCES/0006-cheese-camera-Fix-video-source-memleak-when-switchin.patch new file mode 100644 index 0000000..c1391dd --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0007-cheese-camera-Remove-unused-enum.patch b/SOURCES/0007-cheese-camera-Remove-unused-enum.patch new file mode 100644 index 0000000..31010b6 --- /dev/null +++ b/SOURCES/0007-cheese-camera-Remove-unused-enum.patch @@ -0,0 +1,36 @@ +From b0478b500889ccc7b17c1a3ba8e5aac87e12fdd0 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 10 Jun 2013 10:46:43 +0200 +Subject: [PATCH 07/35] cheese-camera: Remove unused enum + +Signed-off-by: Hans de Goede +--- + 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/SOURCES/0008-cheese-camera-device-Fix-compiler-warning.patch b/SOURCES/0008-cheese-camera-device-Fix-compiler-warning.patch new file mode 100644 index 0000000..bf87947 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch b/SOURCES/0009-cheese-camera-device-Fix-memleak-in-get_best_format.patch new file mode 100644 index 0000000..e74eefd --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0010-cheese-camera-device-Keep-track-of-highest-available.patch b/SOURCES/0010-cheese-camera-device-Keep-track-of-highest-available.patch new file mode 100644 index 0000000..4311329 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch b/SOURCES/0011-cheese-camera-device-Add-cheese_camera_device_find_f.patch new file mode 100644 index 0000000..b3e7d22 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch b/SOURCES/0012-cheese-camera-device-limit-caps-to-the-maximum-frame.patch new file mode 100644 index 0000000..5d33b82 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch b/SOURCES/0013-cheese-camera-device-get_caps_for_format-simplify-th.patch new file mode 100644 index 0000000..906146f --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0014-cheese-camera-device-Make-get_best_format-smarter.patch b/SOURCES/0014-cheese-camera-device-Make-get_best_format-smarter.patch new file mode 100644 index 0000000..8288a98 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0015-cheese-camera-device-Plug-some-memory-leaks.patch b/SOURCES/0015-cheese-camera-device-Plug-some-memory-leaks.patch new file mode 100644 index 0000000..a055d49 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0016-cheese-camera-Drop-unused-preview_caps.patch b/SOURCES/0016-cheese-camera-Drop-unused-preview_caps.patch new file mode 100644 index 0000000..5a2dc43 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch b/SOURCES/0017-cheese-camera-Do-not-add-videoconvert-elements-aroun.patch new file mode 100644 index 0000000..6e11917 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0018-cheese-camera-Check-for-the-current-effect-being-the.patch b/SOURCES/0018-cheese-camera-Check-for-the-current-effect-being-the.patch new file mode 100644 index 0000000..a2bb200 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch b/SOURCES/0019-cheese-camera-Don-t-block-the-main-valve-while-recor.patch new file mode 100644 index 0000000..68c50d2 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch b/SOURCES/0020-cheese-camera-Downscale-image-for-effects-preview-pi.patch new file mode 100644 index 0000000..143bc75 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0021-cheese-window-Fix-de-activation-of-effects-button.patch b/SOURCES/0021-cheese-window-Fix-de-activation-of-effects-button.patch new file mode 100644 index 0000000..d328d14 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch b/SOURCES/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch new file mode 100644 index 0000000..3fa9c8d --- /dev/null +++ b/SOURCES/0022-cheese-window-Make-mode-toggle-and-effects-button-in.patch @@ -0,0 +1,81 @@ +From 6bd6f3b72eef27eee71b67755ad98490e20df6ee Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 11 Jun 2013 13:09:39 +0200 +Subject: [PATCH 22/50] 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 +--- + src/cheese-window.vala | 43 ++++++++++++++++++++++++++++--------------- + 1 file changed, 28 insertions(+), 15 deletions(-) + +diff --git a/src/cheese-window.vala b/src/cheese-window.vala +index 9ebb5e1..2e4e5a8 100644 +--- a/src/cheese-window.vala ++++ b/src/cheese-window.vala +@@ -527,23 +527,37 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + set_fullscreen_mode (fullscreen); + } + +- /** +- * Make the media capture mode actions sensitive. +- */ +- private void enable_mode_change () +- { +- // FIXME: Set the mode action to be sensitive +- // FIXME: Set the effects action to be sensitive. +- } ++ /** ++ * Make the media capture mode actions sensitive. ++ */ ++ private void enable_mode_change () ++ { ++ var mode = this.application.lookup_action ("mode") as SimpleAction; ++ mode.set_enabled (true); + +- /** +- * Make the media capture mode actions insensitive. +- */ +- private void disable_mode_change () ++ var effects = this.application.lookup_action ("effects") as SimpleAction; ++ effects.set_enabled (true); ++ } ++ ++ /** ++ * Make the media capture mode actions insensitive. ++ */ ++ private void disable_mode_change () ++ { ++ var mode = this.application.lookup_action ("mode") as SimpleAction; ++ mode.set_enabled (false); ++ ++ /* Allow changing the effects while recording a video */ ++ if (current_mode != MediaMode.VIDEO) + { +- // FIXME: Set the mode action to be sensitive +- // FIXME: Set the effects action to be insensitive. ++ var effects = this.application.lookup_action ("effects") as SimpleAction; ++ effects.set_enabled (false); ++ if (is_effects_selector_active) ++ { ++ effects_toggle_button.set_active (false); ++ } + } ++ } + + /** + * Set the capture resolution, based on the current capture mode. +@@ -966,7 +980,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 = "" + _("Stop _Taking Pictures") + ""; + take_action_button.tooltip_text = _("Stop taking pictures"); + burst_take_photo (); +-- +1.8.2.1 + diff --git a/SOURCES/0023-libcheese-Add-_init_with_args-init-function-variants.patch b/SOURCES/0023-libcheese-Add-_init_with_args-init-function-variants.patch new file mode 100644 index 0000000..661796b --- /dev/null +++ b/SOURCES/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 +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 +--- + 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 @@ + cheese-init + Initializing libcheese + cheese_init ++cheese_init_with_args + + +
+ cheese-gtk-init + Initializing libcheese-gtk + cheese_gtk_init ++cheese_gtk_init_with_args +
+ +
+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 ++#include + #ifdef GDK_WINDOWING_X11 + #include + #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/SOURCES/0024-cheese-Use-cheese_gtk_init_with_args.patch b/SOURCES/0024-cheese-Use-cheese_gtk_init_with_args.patch new file mode 100644 index 0000000..4f1d063 --- /dev/null +++ b/SOURCES/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 +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@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 +--- + 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/SOURCES/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch b/SOURCES/0025-cheese-Remove-last-remnants-of-the-old-menu-code.patch new file mode 100644 index 0000000..6e18eaa --- /dev/null +++ b/SOURCES/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 +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 +--- + 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 @@ + + + +- +- +- RemoveAll +- Move _All to Trash +- +- +- +- +- +- +- +- +- +- WideMode +- _Wide Mode +- +- +- + + + +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 effects_grids; + + private HashTable 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/SOURCES/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch b/SOURCES/0026-cheese-Protect-set_wide_mode-set_fullscreen-against-.patch new file mode 100644 index 0000000..5413575 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch b/SOURCES/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch new file mode 100644 index 0000000..baa62b3 --- /dev/null +++ b/SOURCES/0027-cheese-Get-rid-of-special-set_startup_foo-functions.patch @@ -0,0 +1,94 @@ +From 6fc5ec37186612c38d1a94c1b1eb4b1b5b5078cf Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 12 Jun 2013 17:59:13 +0200 +Subject: [PATCH 27/50] 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 +--- + 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 35e4850..8916e95 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; + +@@ -121,6 +121,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + public MainWindow (Gtk.Application application) + { + GLib.Object (application: application); ++ is_command_line_startup = true; + } + + /** +@@ -1336,34 +1337,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/SOURCES/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch b/SOURCES/0028-cheese-Fix-the-need-to-press-F11-twice-after-startin.patch new file mode 100644 index 0000000..f07b6e1 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch b/SOURCES/0029-cheese-Make-widemode-controllable-from-the-app-menu.patch new file mode 100644 index 0000000..f14bfef --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch b/SOURCES/0030-cheese-Move-reading-of-widemode-setting-to-cheese-ma.patch new file mode 100644 index 0000000..d3e27b9 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch b/SOURCES/0031-cheese-Fix-reading-of-fullscreen-setting-from-config.patch new file mode 100644 index 0000000..e36b16f --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch b/SOURCES/0032-cheese-Don-t-show-thumbnails-when-toggling-widemode-.patch new file mode 100644 index 0000000..9c07761 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch b/SOURCES/0033-cheese-Fix-updating-of-device-selection-combo-sensit.patch new file mode 100644 index 0000000..cafd6bb --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch b/SOURCES/0034-cheese-Fix-assert-failures-when-taking-a-photo.patch new file mode 100644 index 0000000..6e7dd37 --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch b/SOURCES/0035-cheese-flash-Fix-the-flash-no-longer-being-white.patch new file mode 100644 index 0000000..475c67e --- /dev/null +++ b/SOURCES/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 +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 +--- + 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/SOURCES/0036-cheese-camera-Set-the-effects-valve-to-closed-when-c.patch b/SOURCES/0036-cheese-camera-Set-the-effects-valve-to-closed-when-c.patch new file mode 100644 index 0000000..3ff9c43 --- /dev/null +++ b/SOURCES/0036-cheese-camera-Set-the-effects-valve-to-closed-when-c.patch @@ -0,0 +1,26 @@ +From 73b89ecd0149a31be7b363003a8d0eea94a679cf Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 21 Jun 2013 09:25:17 +0200 +Subject: [PATCH 36/51] cheese-camera: Set the effects valve to closed when + creating the pipeline + +Signed-off-by: Hans de Goede +--- + libcheese/cheese-camera.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c +index 31348d2..89cf029 100644 +--- a/libcheese/cheese-camera.c ++++ b/libcheese/cheese-camera.c +@@ -529,6 +529,7 @@ cheese_camera_create_effects_preview_bin (CheeseCamera *camera, GError **error) + cheese_camera_set_error_element_not_found (error, "effects_valve"); + return FALSE; + } ++ g_object_set (priv->effects_valve, "drop", TRUE, NULL); + if ((scale = gst_element_factory_make ("videoscale", "effects_scale")) == NULL) + { + cheese_camera_set_error_element_not_found (error, "videoscale"); +-- +1.8.2.1 + diff --git a/SOURCES/0037-cheese-Move-disabling-of-shoot-button-to-cheese-wind.patch b/SOURCES/0037-cheese-Move-disabling-of-shoot-button-to-cheese-wind.patch new file mode 100644 index 0000000..859c888 --- /dev/null +++ b/SOURCES/0037-cheese-Move-disabling-of-shoot-button-to-cheese-wind.patch @@ -0,0 +1,60 @@ +From f059aee32f4463378dff03a60da8b6411291df60 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 17 Jun 2013 22:44:20 +0200 +Subject: [PATCH 37/50] cheese: Move disabling of shoot button to cheese-window + +We also have all the other action enable/disable code in cheese-window, so +this is more consistent. + +Also we have more state available in cheese-window, which allows us to leave +the shoot button enabled if (and only if) it is the stop recording button, +which is possible since we allow changing effects while recording a video. + +Signed-off-by: Hans de Goede +--- + src/cheese-window.vala | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/cheese-window.vala b/src/cheese-window.vala +index 53c033d..e7b6db3 100644 +--- a/src/cheese-window.vala ++++ b/src/cheese-window.vala +@@ -948,6 +948,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + this.is_recording = false; + this.enable_mode_change (); + } ++ update_shoot_enabled (); + } + + /** +@@ -1147,6 +1148,19 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + } + + /** ++ * Update shoot button enabled state based on effect selector status ++ */ ++ private void update_shoot_enabled () ++ { ++ var shoot = this.application.lookup_action ("shoot") as SimpleAction; ++ ++ if (is_effects_selector_active && !is_recording) ++ shoot.set_enabled (false); ++ else ++ shoot.set_enabled (true); ++ } ++ ++ /** + * Toggle the visibility of the effects selector. + * + * @param active whether the selector should be active +@@ -1184,6 +1198,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + + camera.toggle_effects_pipeline (active); + setup_effects_page_switch_sensitivity (); ++ update_shoot_enabled (); + } + + /** +-- +1.8.2.1 + diff --git a/SOURCES/0038-cheese-Use-shoot-action-for-webcam-button.patch b/SOURCES/0038-cheese-Use-shoot-action-for-webcam-button.patch new file mode 100644 index 0000000..f04fd1b --- /dev/null +++ b/SOURCES/0038-cheese-Use-shoot-action-for-webcam-button.patch @@ -0,0 +1,29 @@ +From 56331f71eb77c437e3521dd7ef33e4616e2985cd Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 17 Jun 2013 22:54:57 +0200 +Subject: [PATCH 38/50] cheese: Use shoot action for webcam button + +Rather then calling on_shoot directly, so that if shoot is disabled, it also +cannot be triggered through the webcam button. + +Signed-off-by: Hans de Goede +--- + 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 9ba1a5f..b5ac6cb 100644 +--- a/src/cheese-main.vala ++++ b/src/cheese-main.vala +@@ -244,7 +244,7 @@ public class Cheese.Main : Gtk.Application + switch (event.keyval) + { + case Gdk.Key.WebCam: +- on_shoot (); ++ activate_action("shoot", null); + return true; + } + +-- +1.8.2.1 + diff --git a/SOURCES/0039-cheese-window-Add-cancel_running_action-method.patch b/SOURCES/0039-cheese-window-Add-cancel_running_action-method.patch new file mode 100644 index 0000000..15a2204 --- /dev/null +++ b/SOURCES/0039-cheese-window-Add-cancel_running_action-method.patch @@ -0,0 +1,80 @@ +From 43667c547770778cf7c34aefb41235e6fc3c9c62 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 09:05:19 +0200 +Subject: [PATCH 39/50] cheese-window: Add cancel_running_action () method + +Signed-off-by: Hans de Goede +--- + src/cheese-window.vala | 47 ++++++++++++++++++++++++++++++----------------- + 1 file changed, 30 insertions(+), 17 deletions(-) + +diff --git a/src/cheese-window.vala b/src/cheese-window.vala +index e7b6db3..95b4e14 100644 +--- a/src/cheese-window.vala ++++ b/src/cheese-window.vala +@@ -873,6 +873,34 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + } + + /** ++ * Cancel the current action (if any) ++ */ ++ private bool cancel_running_action () ++ { ++ if ((current_countdown != null && current_countdown.running) || ++ is_bursting || is_recording) ++ { ++ action_cancelled = true; ++ switch (current_mode) ++ { ++ case MediaMode.PHOTO: ++ current_countdown.stop (); ++ finish_countdown_callback (); ++ break; ++ case MediaMode.BURST: ++ toggle_photo_bursting (false); ++ break; ++ case MediaMode.VIDEO: ++ toggle_video_recording (false); ++ break; ++ } ++ action_cancelled = false; ++ return true; ++ } ++ return false; ++ } ++ ++ /** + * Cancel the current activity if the escape key is pressed. + * + * @param event the key event, to check which key was pressed +@@ -885,25 +913,10 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + key = Gdk.keyval_name (event.keyval); + if (strcmp (key, "Escape") == 0) + { +- if ((current_countdown != null && current_countdown.running) || is_bursting || is_recording) ++ if (cancel_running_action()) + { +- action_cancelled = true; +- switch (current_mode) +- { +- case MediaMode.PHOTO: +- current_countdown.stop (); +- finish_countdown_callback (); +- break; +- case MediaMode.BURST: +- toggle_photo_bursting (false); +- break; +- case MediaMode.VIDEO: +- toggle_video_recording (false); +- break; +- } +- action_cancelled = false; ++ return false; + } +- else + if (is_effects_selector_active) + { + effects_toggle_button.set_active (false); +-- +1.8.2.1 + diff --git a/SOURCES/0040-cheese-window-Fix-toggle_camera_actions_sensitivitie.patch b/SOURCES/0040-cheese-window-Fix-toggle_camera_actions_sensitivitie.patch new file mode 100644 index 0000000..9cde0a6 --- /dev/null +++ b/SOURCES/0040-cheese-window-Fix-toggle_camera_actions_sensitivitie.patch @@ -0,0 +1,131 @@ +From f9899f78b6bd7f929613f2edf7421101b79ca365 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 09:12:21 +0200 +Subject: [PATCH 40/50] cheese-window: Fix toggle_camera_actions_sensitivities + +The action we should disable are part of cheese-main, not of the gtkbuilder +tree. Also: + +- Switch to using a whitelist rather then a blacklist, as there are + less actions we want to disable/enable then which we don't want to, and + having a whitelist allows for much simpler code. + +- Stop remembering the enabled state before disabling the actions, this is not + needed + +This fixes various controls not being disabled when the user starts cheese +on a machine with no video devices. + +Signed-off-by: Hans de Goede +--- + src/cheese-window.vala | 72 ++++++++++---------------------------------------- + 1 file changed, 14 insertions(+), 58 deletions(-) + +diff --git a/src/cheese-window.vala b/src/cheese-window.vala +index 95b4e14..ab383f9 100644 +--- a/src/cheese-window.vala ++++ b/src/cheese-window.vala +@@ -78,7 +78,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + private uint current_effects_page = 0; + private List effects_grids; + +- private HashTable action_sensitivities; + private Gtk.Action countdown_action; + private Gtk.Action effects_page_prev_action; + private Gtk.Action effects_page_next_action; +@@ -90,7 +89,6 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + private bool is_recording; /* Video Recording Flag */ + private bool is_bursting; + private bool is_effects_selector_active; +- private bool is_camera_actions_sensitive; + private bool action_cancelled; + public bool is_command_line_startup; + +@@ -1296,59 +1294,20 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + */ + public void toggle_camera_actions_sensitivities (bool active) + { +- is_camera_actions_sensitive = active; +- if (active) +- { +- var keys = action_sensitivities.get_keys (); +- foreach (var key in keys) +- { +- Gtk.Action action = gtk_builder.get_object (key) as Gtk.Action; +- action.sensitive = action_sensitivities.get (key); +- } +- } +- else +- { +- action_sensitivities = new HashTable (GLib.str_hash, +- GLib.direct_equal); +- GLib.SList objects = gtk_builder.get_objects (); +- foreach (GLib.Object obj in objects) +- { +- if (obj is Gtk.Action) +- { +- Gtk.Action action = (Gtk.Action)obj; +- action_sensitivities.set (action.name, action.sensitive); +- } +- } ++ string [] actions = { "shoot", "mode", "effects" }; + +- /* Keep only these actions sensitive. */ +- string [] active_actions = { "quit", +- "help", +- "about", +- "open", +- "save_as", +- "move_to_trash", +- "delete"}; +- +- /* Gross hack because Vala's `in` operator doesn't really work */ +- bool flag; +- foreach (GLib.Object obj in objects) +- { +- flag = false; +- if (obj is Gtk.Action) +- { +- Gtk.Action action = (Gtk.Action)obj; +- foreach (string s in active_actions) +- { +- if (action.name == s) +- { +- flag = true; +- } +- } +- if (!flag) +- ((Gtk.Action)obj).sensitive = false; +- } +- } +- } ++ /* If inactive, hide the effects selector, stop recording, etc. */ ++ if (!active) { ++ if (is_effects_selector_active) ++ effects_toggle_button.set_active (false); ++ cancel_running_action (); ++ } ++ ++ foreach (string name in actions) ++ { ++ var action = this.application.lookup_action (name) as SimpleAction; ++ action.set_enabled (active); ++ } + } + + /** +@@ -1356,10 +1315,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + */ + public void camera_state_change_playing () + { +- if (!is_camera_actions_sensitive) +- { +- toggle_camera_actions_sensitivities (true); +- } ++ toggle_camera_actions_sensitivities (true); + + Effect effect = effects_manager.get_effect (settings.get_string ("selected-effect")); + if (effect != null) +-- +1.8.2.1 + diff --git a/SOURCES/0041-cheese-window-Add-show_error-method.patch b/SOURCES/0041-cheese-window-Add-show_error-method.patch new file mode 100644 index 0000000..e5cefdb --- /dev/null +++ b/SOURCES/0041-cheese-window-Add-show_error-method.patch @@ -0,0 +1,97 @@ +From b851a44075fea20054c4c5345da46a52e3cba91c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 10:04:36 +0200 +Subject: [PATCH 41/50] cheese-window: Add show_error () method + +Signed-off-by: Hans de Goede +--- + src/cheese-window.vala | 54 +++++++++++++++++++++++++++++++------------------- + 1 file changed, 34 insertions(+), 20 deletions(-) + +diff --git a/src/cheese-window.vala b/src/cheese-window.vala +index ab383f9..77efd32 100644 +--- a/src/cheese-window.vala ++++ b/src/cheese-window.vala +@@ -1045,6 +1045,31 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + } + + /** ++ * Show an error. ++ * ++ * @param error the error to display, or null to hide the error layer ++ */ ++ [CCode (instance_pos = -1)] ++ public void show_error (string? error) ++ { ++ if (error != null) ++ { ++ current_effects_grid.hide (); ++ video_preview.hide (); ++ error_layer.text = error; ++ error_layer.show (); ++ } ++ else ++ { ++ error_layer.hide (); ++ if (is_effects_selector_active) ++ current_effects_grid.show (); ++ else ++ video_preview.show (); ++ } ++ } ++ ++ /** + * Toggle the display of the effect selector. + * + * @param effects whether effects should be enabled +@@ -1179,31 +1204,19 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + private void toggle_effects_selector (bool active) + { + is_effects_selector_active = active; +- if (active) ++ if (effects_grids.length () == 0) ++ { ++ show_error(active ? _("No effects found") : null); ++ } ++ else if (active) + { + video_preview.hide (); +- +- if (effects_grids.length () == 0) +- { +- error_layer.text = _("No effects found"); +- error_layer.show (); +- } +- else +- { +- current_effects_grid.show (); +- activate_effects_page ((int)current_effects_page); +- } ++ current_effects_grid.show (); ++ activate_effects_page ((int)current_effects_page); + } + else + { +- if (effects_grids.length () == 0) +- { +- error_layer.hide (); +- } +- else +- { +- current_effects_grid.hide (); +- } ++ current_effects_grid.hide (); + video_preview.show (); + } + +@@ -1315,6 +1328,7 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + */ + public void camera_state_change_playing () + { ++ show_error (null); + toggle_camera_actions_sensitivities (true); + + Effect effect = effects_manager.get_effect (settings.get_string ("selected-effect")); +-- +1.8.2.1 + diff --git a/SOURCES/0042-cheese-preferences-Add-camera_changed-method.patch b/SOURCES/0042-cheese-preferences-Add-camera_changed-method.patch new file mode 100644 index 0000000..5785abd --- /dev/null +++ b/SOURCES/0042-cheese-preferences-Add-camera_changed-method.patch @@ -0,0 +1,86 @@ +From f1bb1e32b7f08396a22076bace60002b2282d700 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 11:14:16 +0200 +Subject: [PATCH 42/50] cheese-preferences: Add camera_changed () method + +Signed-off-by: Hans de Goede +--- + src/cheese-preferences.vala | 34 +++++++++++++++++++++++++--------- + 1 file changed, 25 insertions(+), 9 deletions(-) + +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index e078cbb..be104a6 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -128,6 +128,28 @@ public class Cheese.PreferencesDialog : GLib.Object + } + + /** ++ * Update resolution list and save the current camera to settings. ++ */ ++ private void camera_changed () ++ { ++ Cheese.CameraDevice device, iter_device; ++ TreeIter iter; ++ ++ device = camera.get_selected_device (); ++ if (device == null) ++ return; ++ settings.set_string ("camera", device.get_device_node ()); ++ setup_resolutions_for_device (device); ++ ++ for (bool next = camera_model.get_iter_first (out iter); next; ++ next = camera_model.iter_next (ref iter)) { ++ camera_model.get (iter, 1, out iter_device, -1); ++ if (iter_device == device) ++ source_combo.set_active_iter (iter); ++ } ++ } ++ ++ /** + * Initialize and populate the camera device combo box model. + */ + private void initialize_camera_devices () +@@ -140,8 +162,7 @@ public class Cheese.PreferencesDialog : GLib.Object + + devices.foreach(add_camera_device); + +- settings.set_string ("camera", camera.get_selected_device ().get_device_node ()); +- setup_resolutions_for_device (camera.get_selected_device ()); ++ camera_changed (); + } + + /** +@@ -227,8 +248,7 @@ public class Cheese.PreferencesDialog : GLib.Object + combo.model.get (iter, 1, out dev); + camera.set_device_by_device_node (dev.get_device_node ()); + camera.switch_camera_device (); +- setup_resolutions_for_device (camera.get_selected_device ()); +- settings.set_string ("camera", dev.get_device_node ()); ++ camera_changed (); + } + + /** +@@ -474,8 +494,7 @@ public class Cheese.PreferencesDialog : GLib.Object + } + } + +- settings.set_string ("camera", camera.get_selected_device ().get_device_node ()); +- setup_resolutions_for_device (camera.get_selected_device ()); ++ camera_changed (); + } + + /** +@@ -496,9 +515,6 @@ public class Cheese.PreferencesDialog : GLib.Object + 0, dev.get_name () + " (" + dev.get_device_node () + ")", + 1, dev); + +- 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; + } +-- +1.8.2.1 + diff --git a/SOURCES/0043-cheese_camera_get_camera_devices-Allow-calling-befor.patch b/SOURCES/0043-cheese_camera_get_camera_devices-Allow-calling-befor.patch new file mode 100644 index 0000000..7447824 --- /dev/null +++ b/SOURCES/0043-cheese_camera_get_camera_devices-Allow-calling-befor.patch @@ -0,0 +1,44 @@ +From 3d43b99268481346669804e8863938e4b6523985 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 11:38:05 +0200 +Subject: [PATCH 43/50] cheese_camera_get_camera_devices: Allow calling before + cheese_camera_setup() + +Signed-off-by: Hans de Goede +--- + libcheese/cheese-camera.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c +index fab9b03..c4d4253 100644 +--- a/libcheese/cheese-camera.c ++++ b/libcheese/cheese-camera.c +@@ -360,6 +360,9 @@ cheese_camera_detect_camera_devices (CheeseCamera *camera) + { + CheeseCameraPrivate *priv = camera->priv; + ++ if (priv->monitor) ++ return; /* Camera devices already detected */ ++ + priv->num_camera_devices = 0; + priv->camera_devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + +@@ -1636,13 +1639,11 @@ cheese_camera_setup (CheeseCamera *camera, const gchar *uuid, GError **error) + GPtrArray * + cheese_camera_get_camera_devices (CheeseCamera *camera) + { +- CheeseCameraPrivate *priv; +- + g_return_val_if_fail (CHEESE_IS_CAMERA (camera), NULL); + +- priv = camera->priv; ++ cheese_camera_detect_camera_devices (camera); + +- return g_ptr_array_ref (priv->camera_devices); ++ return g_ptr_array_ref (camera->priv->camera_devices); + } + + /** +-- +1.8.2.1 + diff --git a/SOURCES/0044-cheese-Move-camera_setup-to-cheese-preferences.patch b/SOURCES/0044-cheese-Move-camera_setup-to-cheese-preferences.patch new file mode 100644 index 0000000..e1e44cc --- /dev/null +++ b/SOURCES/0044-cheese-Move-camera_setup-to-cheese-preferences.patch @@ -0,0 +1,145 @@ +From f1dbd7629b18f8078567e34cf3981bfbdc70b5ef Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 11:40:41 +0200 +Subject: [PATCH 44/50] cheese: Move camera_setup to cheese-preferences + +Since cheese-preferences already tracks how many cameras we have, it can also +properly do delayed camera setup when going from 0 -> 1 devices while cheese +is running, and thus is the best place to do the camera setup. + +As an added bonus this patch uses the new show_error function to properly +show an error to the user when no devices are found. + +Signed-off-by: Hans de Goede +--- + src/cheese-main.vala | 28 ++++++++++------------------ + src/cheese-preferences.vala | 24 ++++++++++++++++++++++-- + src/vapi/cheese-common.vapi | 2 +- + 3 files changed, 33 insertions(+), 21 deletions(-) + +diff --git a/src/cheese-main.vala b/src/cheese-main.vala +index b5ac6cb..761f1b5 100644 +--- a/src/cheese-main.vala ++++ b/src/cheese-main.vala +@@ -62,6 +62,12 @@ public class Cheese.Main : Gtk.Application + GLib.Object (application_id: app_id, flags: flags); + } + ++ private void on_camera_error (string? error) ++ { ++ main_window.toggle_camera_actions_sensitivities (false); ++ main_window.show_error (error); ++ } ++ + /** + * Present the existing main window, or create a new one. + */ +@@ -147,8 +153,10 @@ public class Cheese.Main : Gtk.Application + main_window.key_press_event.connect (on_webcam_key_pressed); + + main_window.show (); +- setup_camera (device); ++ create_camera (device); + preferences_dialog = new PreferencesDialog (camera); ++ preferences_dialog.camera_error.connect (on_camera_error); ++ preferences_dialog.setup_camera (); + } + } + +@@ -157,7 +165,7 @@ public class Cheese.Main : Gtk.Application + * + * @param uri the uri of the device node to setup, or null + */ +- public void setup_camera (string? uri) ++ public void create_camera (string? uri) + { + var settings = new GLib.Settings ("org.gnome.Cheese"); + string device; +@@ -177,21 +185,6 @@ public class Cheese.Main : Gtk.Application + settings.get_int ("photo-x-resolution"), + settings.get_int ("photo-y-resolution")); + +- try +- { +- camera.setup (device); +- } +- catch (Error err) +- { +- video_preview.hide (); +- warning ("Error: %s\n", err.message); +- //error_layer.text = err.message; +- //error_layer.show (); +- +- //toggle_camera_actions_sensitivities (false); +- return; +- } +- + value = settings.get_double ("brightness"); + if (value != 0.0) + { +@@ -218,7 +211,6 @@ public class Cheese.Main : Gtk.Application + + camera.state_flags_changed.connect (on_camera_state_flags_changed); + main_window.set_camera (camera); +- camera.play (); + } + + /** +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index be104a6..30b3d65 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -111,6 +111,28 @@ public class Cheese.PreferencesDialog : GLib.Object + } + + /** ++ * Signal raised when there is an error with the camera device ++ */ ++ public signal void camera_error (string? error); ++ ++ /** ++ * Setup the camera device ++ */ ++ public void setup_camera () ++ { ++ try ++ { ++ camera.setup (null); ++ camera.play (); ++ camera_changed (); ++ } ++ catch (Error err) ++ { ++ camera_error (err.message); ++ } ++ } ++ ++ /** + * Set up combo box cell renderers. + */ + private void setup_combo_box_models () +@@ -161,8 +183,6 @@ public class Cheese.PreferencesDialog : GLib.Object + source_combo.sensitive = false; + + devices.foreach(add_camera_device); +- +- camera_changed (); + } + + /** +diff --git a/src/vapi/cheese-common.vapi b/src/vapi/cheese-common.vapi +index e4d4bec..88f47f7 100644 +--- a/src/vapi/cheese-common.vapi ++++ b/src/vapi/cheese-common.vapi +@@ -63,7 +63,7 @@ namespace Cheese + public void toggle_effects_pipeline (bool active); + public void connect_effect_texture (Cheese.Effect effect, Clutter.Texture texture); + public void set_video_format (Cheese.VideoFormat format); +- public void setup (string udi) throws GLib.Error; ++ public void setup (string? udi) throws GLib.Error; + public void start_video_recording (string filename); + public void stop (); + public void stop_video_recording (); +-- +1.8.2.1 + diff --git a/SOURCES/0045-cheese-Properly-deal-with-going-from-0-1-devices.patch b/SOURCES/0045-cheese-Properly-deal-with-going-from-0-1-devices.patch new file mode 100644 index 0000000..ef6c3e2 --- /dev/null +++ b/SOURCES/0045-cheese-Properly-deal-with-going-from-0-1-devices.patch @@ -0,0 +1,56 @@ +From 937f79bdf0867f9319d53ca51c3f1437e1d8bb3a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 11:59:55 +0200 +Subject: [PATCH 45/50] cheese: Properly deal with going from 0 -> 1 devices + +Before this patch cheese showed a "No device found" message when started +without any devices connected, and would keep showing this after the user +plugged in a webcam. The new cam also could not be selected from the +preferences dialog. + +After this patch cheese will automatically switch to showing video from a +newly plugged in webcam (when it had no devices before). + +Signed-off-by: Hans de Goede +--- + src/cheese-preferences.vala | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index 30b3d65..4ec4937 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -24,6 +24,7 @@ using Gtk; + public class Cheese.PreferencesDialog : GLib.Object + { + private Cheese.Camera camera; ++ private bool camera_needs_setup; + + private GLib.Settings settings; + +@@ -125,10 +126,12 @@ public class Cheese.PreferencesDialog : GLib.Object + camera.setup (null); + camera.play (); + camera_changed (); ++ camera_needs_setup = false; + } + catch (Error err) + { + camera_error (err.message); ++ camera_needs_setup = true; + } + } + +@@ -537,6 +540,9 @@ public class Cheese.PreferencesDialog : GLib.Object + + if (camera_model.iter_n_children (null) > 1) + source_combo.sensitive = true; ++ ++ if (camera_needs_setup) ++ setup_camera (); + } + + /** +-- +1.8.2.1 + diff --git a/SOURCES/0046-cheese-Avoid-unnecessary-calls-to-switch_camera_devi.patch b/SOURCES/0046-cheese-Avoid-unnecessary-calls-to-switch_camera_devi.patch new file mode 100644 index 0000000..a8fb0b3 --- /dev/null +++ b/SOURCES/0046-cheese-Avoid-unnecessary-calls-to-switch_camera_devi.patch @@ -0,0 +1,56 @@ +From 1b4092c56022eb913ddc4f4c90db41ea5868a16d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 13:45:38 +0200 +Subject: [PATCH 46/50] cheese: Avoid unnecessary calls to + switch_camera_device() + +And thus avoid stopping and restarting the stream for no reason. + +Signed-off-by: Hans de Goede +--- + src/cheese-preferences.vala | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index 4ec4937..1971a69 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -25,6 +25,7 @@ public class Cheese.PreferencesDialog : GLib.Object + { + private Cheese.Camera camera; + private bool camera_needs_setup; ++ private string camera_device_node; + + private GLib.Settings settings; + +@@ -163,7 +164,8 @@ public class Cheese.PreferencesDialog : GLib.Object + device = camera.get_selected_device (); + if (device == null) + return; +- settings.set_string ("camera", device.get_device_node ()); ++ camera_device_node = device.get_device_node (); ++ settings.set_string ("camera", camera_device_node); + setup_resolutions_for_device (device); + + for (bool next = camera_model.get_iter_first (out iter); next; +@@ -266,10 +268,16 @@ public class Cheese.PreferencesDialog : GLib.Object + + TreeIter iter; + Cheese.CameraDevice dev; ++ string dev_node; + + combo.get_active_iter (out iter); + combo.model.get (iter, 1, out dev); +- camera.set_device_by_device_node (dev.get_device_node ()); ++ dev_node = dev.get_device_node (); ++ ++ if (dev_node == camera_device_node) ++ return; ++ ++ camera.set_device_by_device_node (dev_node); + camera.switch_camera_device (); + camera_changed (); + } +-- +1.8.2.1 + diff --git a/SOURCES/0047-on_camera_update_num_camera_devices-Remove-unnecessa.patch b/SOURCES/0047-on_camera_update_num_camera_devices-Remove-unnecessa.patch new file mode 100644 index 0000000..bb9ce72 --- /dev/null +++ b/SOURCES/0047-on_camera_update_num_camera_devices-Remove-unnecessa.patch @@ -0,0 +1,30 @@ +From fa3ebcbd5891d422aae86c2852070b235cf3768d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 18 Jun 2013 14:01:45 +0200 +Subject: [PATCH 47/50] on_camera_update_num_camera_devices: Remove unnecessary + camera_changed() call + +If the camera is actually changed then camera_changed already gets called +from either setup_camera() or on_source_change(). + +Signed-off-by: Hans de Goede +--- + src/cheese-preferences.vala | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index 1971a69..219c685 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -524,8 +524,6 @@ public class Cheese.PreferencesDialog : GLib.Object + remove_camera_device (iter, old_device, active_device); + } + } +- +- camera_changed (); + } + + /** +-- +1.8.2.1 + diff --git a/SOURCES/0048-cheese-preferences-Simplify-remove_camera_device.patch b/SOURCES/0048-cheese-preferences-Simplify-remove_camera_device.patch new file mode 100644 index 0000000..94a5f2f --- /dev/null +++ b/SOURCES/0048-cheese-preferences-Simplify-remove_camera_device.patch @@ -0,0 +1,72 @@ +From 4684d5a009f1bf3b4c7d2fc92456fc506ba1f254 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 19 Jun 2013 16:47:41 +0200 +Subject: [PATCH 48/50] cheese-preferences: Simplify remove_camera_device + +Now that we cache the device-node for the active camera, remove_camera_device +and its callers can be simplified. + +Signed-off-by: Hans de Goede +--- + src/cheese-preferences.vala | 19 ++++++------------- + 1 file changed, 6 insertions(+), 13 deletions(-) + +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index 219c685..a1316f9 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -491,12 +491,6 @@ public class Cheese.PreferencesDialog : GLib.Object + TreeIter iter; + camera_model.get_iter_first (out iter); + +- // Combobox active element. +- TreeIter active_iter; +- Cheese.CameraDevice active_device; +- source_combo.get_active_iter (out active_iter); +- camera_model.get (active_iter, 1, out active_device, -1); +- + // Find which device was removed. + bool device_removed = false; + devices.foreach ((device) => +@@ -508,7 +502,7 @@ public class Cheese.PreferencesDialog : GLib.Object + // Found the device that was removed. + if (strcmp (old_device.device_node, new_device.device_node) != 0) + { +- remove_camera_device (iter, new_device, active_device); ++ remove_camera_device (iter, new_device); + device_removed = true; + // Remember, this is from the anonymous function! + return; +@@ -521,7 +515,7 @@ public class Cheese.PreferencesDialog : GLib.Object + { + Cheese.CameraDevice old_device; + camera_model.get (iter, 1, out old_device, -1); +- remove_camera_device (iter, old_device, active_device); ++ remove_camera_device (iter, old_device); + } + } + } +@@ -555,16 +549,15 @@ public class Cheese.PreferencesDialog : GLib.Object + * Remove the supplied camera device from the device combo box model. + * + * @param iter the iterator of the device to remove +- * @param device_node the device to remove from the combo box model +- * @param active_device_node the currently-active camera device ++ * @param device the device to remove from the combo box model + */ +- private void remove_camera_device (TreeIter iter, Cheese.CameraDevice device_node, +- Cheese.CameraDevice active_device_node) ++ private void remove_camera_device (TreeIter iter, ++ Cheese.CameraDevice device) + { + unowned GLib.PtrArray devices = camera.get_camera_devices (); + + // Check if the camera that we want to remove, is the active one +- if (strcmp (device_node.device_node, active_device_node.device_node) == 0) ++ if (device.device_node == camera_device_node) + { + if (devices.len > 0) + set_new_available_camera_device (iter); +-- +1.8.2.1 + diff --git a/SOURCES/0049-cheese-preferences-Cleanly-handle-going-from-1-0-dev.patch b/SOURCES/0049-cheese-preferences-Cleanly-handle-going-from-1-0-dev.patch new file mode 100644 index 0000000..5571762 --- /dev/null +++ b/SOURCES/0049-cheese-preferences-Cleanly-handle-going-from-1-0-dev.patch @@ -0,0 +1,86 @@ +From 490d8d832b588d7194d6be38d7152b97ea3fe572 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Wed, 19 Jun 2013 17:29:28 +0200 +Subject: [PATCH 49/50] cheese-preferences: Cleanly handle going from 1 -> 0 + devices + +Cleanly handle going from 1 -> 0 devices and going from 1 -> 0 -> 1 devices. + +Also use camera_model.iter_n_children consistently to get the number of +available devices, rather then mixing and matching it with num_camera_devices +and devices.len. + +Signed-off-by: Hans de Goede +--- + src/cheese-preferences.vala | 28 +++++++++++++++++----------- + 1 file changed, 17 insertions(+), 11 deletions(-) + +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index a1316f9..df2ded2 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -263,13 +263,13 @@ public class Cheese.PreferencesDialog : GLib.Object + [CCode (instance_pos = -1)] + public void on_source_change (Gtk.ComboBox combo) + { +- // TODO: Handle going from 1 to 0 devices, cleanly! +- return_if_fail (camera.num_camera_devices > 0); +- + TreeIter iter; + Cheese.CameraDevice dev; + string dev_node; + ++ if (combo.get_active () == -1) ++ return; ++ + combo.get_active_iter (out iter); + combo.model.get (iter, 1, out dev); + dev_node = dev.get_device_node (); +@@ -532,6 +532,7 @@ public class Cheese.PreferencesDialog : GLib.Object + { + TreeIter iter; + Cheese.CameraDevice dev = (Cheese.CameraDevice) device; ++ bool was_empty = camera_model.iter_n_children (null) == 0; + + camera_model.append (out iter); + camera_model.set (iter, +@@ -543,6 +544,8 @@ public class Cheese.PreferencesDialog : GLib.Object + + if (camera_needs_setup) + setup_camera (); ++ else if (was_empty) ++ source_combo.set_active_iter (iter); + } + + /** +@@ -554,16 +557,19 @@ public class Cheese.PreferencesDialog : GLib.Object + private void remove_camera_device (TreeIter iter, + Cheese.CameraDevice device) + { +- unowned GLib.PtrArray devices = camera.get_camera_devices (); +- +- // Check if the camera that we want to remove, is the active one +- if (device.device_node == camera_device_node) ++ if (camera.num_camera_devices == 0) /* Last camera gone? */ + { +- if (devices.len > 0) +- set_new_available_camera_device (iter); +- else +- this.dialog.hide(); ++ ListStore resolution_model = new ListStore (2, typeof (string), ++ typeof (Cheese.VideoFormat)); ++ photo_resolution_combo.model = resolution_model; ++ video_resolution_combo.model = resolution_model; ++ camera_error(_("No device found")); + } ++ else if (device.device_node == camera_device_node) ++ { ++ set_new_available_camera_device (iter); ++ } ++ + camera_model.remove (iter); + + if (camera_model.iter_n_children (null) <= 1) +-- +1.8.2.1 + diff --git a/SOURCES/0050-cheese-Don-t-allow-changing-the-camera-and-or-its-re.patch b/SOURCES/0050-cheese-Don-t-allow-changing-the-camera-and-or-its-re.patch new file mode 100644 index 0000000..3478c9a --- /dev/null +++ b/SOURCES/0050-cheese-Don-t-allow-changing-the-camera-and-or-its-re.patch @@ -0,0 +1,125 @@ +From b6eb2f95f6dfac8d0f332c3fb7fca8c711f68ad6 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 20 Jun 2013 16:53:22 +0200 +Subject: [PATCH 50/50] cheese: Don't allow changing the camera and/or its + resolution while recording + +Signed-off-by: Hans de Goede + +Conflicts: + src/cheese-window.vala +--- + src/cheese-main.vala | 1 + + src/cheese-preferences.vala | 16 +++++++++++++++- + src/cheese-window.vala | 16 ++++++++++++++++ + 3 files changed, 32 insertions(+), 1 deletion(-) + +diff --git a/src/cheese-main.vala b/src/cheese-main.vala +index 761f1b5..a62f8d0 100644 +--- a/src/cheese-main.vala ++++ b/src/cheese-main.vala +@@ -155,6 +155,7 @@ public class Cheese.Main : Gtk.Application + main_window.show (); + create_camera (device); + preferences_dialog = new PreferencesDialog (camera); ++ main_window.set_preferences_dialog (preferences_dialog); + preferences_dialog.camera_error.connect (on_camera_error); + preferences_dialog.setup_camera (); + } +diff --git a/src/cheese-preferences.vala b/src/cheese-preferences.vala +index df2ded2..d16930a 100644 +--- a/src/cheese-preferences.vala ++++ b/src/cheese-preferences.vala +@@ -25,6 +25,7 @@ public class Cheese.PreferencesDialog : GLib.Object + { + private Cheese.Camera camera; + private bool camera_needs_setup; ++ private bool camera_controls_sensitive; + private string camera_device_node; + + private GLib.Settings settings; +@@ -58,6 +59,7 @@ public class Cheese.PreferencesDialog : GLib.Object + public PreferencesDialog (Cheese.Camera camera) + { + this.camera = camera; ++ this.camera_controls_sensitive = true; + + settings = new GLib.Settings ("org.gnome.Cheese"); + +@@ -539,7 +541,7 @@ public class Cheese.PreferencesDialog : GLib.Object + 0, dev.get_name () + " (" + dev.get_device_node () + ")", + 1, dev); + +- if (camera_model.iter_n_children (null) > 1) ++ if (camera_model.iter_n_children (null) > 1 && camera_controls_sensitive) + source_combo.sensitive = true; + + if (camera_needs_setup) +@@ -595,6 +597,18 @@ public class Cheese.PreferencesDialog : GLib.Object + } + + /** ++ * Set camera controls sensitivity ++ */ ++ public void set_camera_controls_sensitivities (bool sensitive) ++ { ++ camera_controls_sensitive = sensitive; ++ photo_resolution_combo.sensitive = sensitive; ++ video_resolution_combo.sensitive = sensitive; ++ if (camera_model.iter_n_children (null) > 1) ++ source_combo.sensitive = sensitive; ++ } ++ ++ /** + * Show the dialog. + */ + public void show () +diff --git a/src/cheese-window.vala b/src/cheese-window.vala +index 77efd32..fc38850 100644 +--- a/src/cheese-window.vala ++++ b/src/cheese-window.vala +@@ -104,6 +104,8 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + + private Cheese.ShareableMedia shareable_media; + ++ private PreferencesDialog preferences_dialog; ++ + /** + * Responses from the delete files confirmation dialog. + * +@@ -501,6 +503,8 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + + var effects = this.application.lookup_action ("effects") as SimpleAction; + effects.set_enabled (true); ++ ++ preferences_dialog.set_camera_controls_sensitivities (true); + } + + /** +@@ -521,6 +525,8 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + effects_toggle_button.set_active (false); + } + } ++ ++ preferences_dialog.set_camera_controls_sensitivities (false); + } + + /** +@@ -1504,4 +1510,14 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + { + this.camera = camera; + } ++ ++ /** ++ * Set the preferences-dialog. ++ * ++ * @param preferences_dialog the preferences-dialog to set ++ */ ++ public void set_preferences_dialog (PreferencesDialog preferences_dialog) ++ { ++ this.preferences_dialog = preferences_dialog; ++ } + } +-- +1.8.2.1 + diff --git a/SOURCES/0051-cheese-Leave-shoot-button-disabled-when-the-effects-.patch b/SOURCES/0051-cheese-Leave-shoot-button-disabled-when-the-effects-.patch new file mode 100644 index 0000000..194bfc9 --- /dev/null +++ b/SOURCES/0051-cheese-Leave-shoot-button-disabled-when-the-effects-.patch @@ -0,0 +1,45 @@ +From fdf136b10de78b84e0ae9843e2eb8f71194ab43c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 20 Jun 2013 19:31:06 +0200 +Subject: [PATCH 51/51] cheese: Leave shoot button disabled when the effects + selector is showing + +Before this patch the shoot button would get re-enabled when changing +resolution (or device) at the effects selector. + +Signed-off-by: Hans de Goede +--- + src/cheese-window.vala | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/src/cheese-window.vala b/src/cheese-window.vala +index fc38850..a1a645c 100644 +--- a/src/cheese-window.vala ++++ b/src/cheese-window.vala +@@ -1313,13 +1313,20 @@ public class Cheese.MainWindow : Gtk.ApplicationWindow + */ + public void toggle_camera_actions_sensitivities (bool active) + { +- string [] actions = { "shoot", "mode", "effects" }; ++ string [] actions = { "mode", "effects" }; + +- /* If inactive, hide the effects selector, stop recording, etc. */ +- if (!active) { ++ if (active) ++ { ++ /* Use update_shoot_enabled, so as to not adversely enable it */ ++ update_shoot_enabled (); ++ } ++ else ++ { ++ /* Inactive, hide the effects selector, stop recording, etc. */ + if (is_effects_selector_active) + effects_toggle_button.set_active (false); + cancel_running_action (); ++ actions += "shoot"; + } + + foreach (string name in actions) +-- +1.8.2.1 + diff --git a/SPECS/cheese.spec b/SPECS/cheese.spec new file mode 100644 index 0000000..62888b8 --- /dev/null +++ b/SPECS/cheese.spec @@ -0,0 +1,661 @@ +Name: cheese +Epoch: 2 +Version: 3.8.2 +Release: 5%{?dist} +Summary: Application for taking pictures and movies from a webcam + +Group: Amusements/Graphics +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 +Patch36: 0036-cheese-camera-Set-the-effects-valve-to-closed-when-c.patch +Patch37: 0037-cheese-Move-disabling-of-shoot-button-to-cheese-wind.patch +Patch38: 0038-cheese-Use-shoot-action-for-webcam-button.patch +Patch39: 0039-cheese-window-Add-cancel_running_action-method.patch +Patch40: 0040-cheese-window-Fix-toggle_camera_actions_sensitivitie.patch +Patch41: 0041-cheese-window-Add-show_error-method.patch +Patch42: 0042-cheese-preferences-Add-camera_changed-method.patch +Patch43: 0043-cheese_camera_get_camera_devices-Allow-calling-befor.patch +Patch44: 0044-cheese-Move-camera_setup-to-cheese-preferences.patch +Patch45: 0045-cheese-Properly-deal-with-going-from-0-1-devices.patch +Patch46: 0046-cheese-Avoid-unnecessary-calls-to-switch_camera_devi.patch +Patch47: 0047-on_camera_update_num_camera_devices-Remove-unnecessa.patch +Patch48: 0048-cheese-preferences-Simplify-remove_camera_device.patch +Patch49: 0049-cheese-preferences-Cleanly-handle-going-from-1-0-dev.patch +Patch50: 0050-cheese-Don-t-allow-changing-the-camera-and-or-its-re.patch +Patch51: 0051-cheese-Leave-shoot-button-disabled-when-the-effects-.patch + +# https://bugzilla.gnome.org/show_bug.cgi?id=678447 +# Patch2: 0002-Setup-vp8enc-in-a-way-suitable-for-realtime-encoding.patch + +BuildRequires: gtk3-devel >= 3.0.0 +BuildRequires: gstreamer1-devel +BuildRequires: gstreamer1-plugins-bad-free-devel +BuildRequires: gstreamer1-plugins-base-devel +BuildRequires: cairo-devel >= 1.4.0 +BuildRequires: librsvg2-devel >= 2.18.0 +BuildRequires: evolution-data-server-devel +BuildRequires: libXxf86vm-devel +BuildRequires: libXtst-devel +BuildRequires: desktop-file-utils +BuildRequires: gettext +BuildRequires: intltool +BuildRequires: libgudev1-devel +BuildRequires: libcanberra-devel +BuildRequires: clutter-devel +BuildRequires: clutter-gtk-devel +BuildRequires: clutter-gst2-devel +BuildRequires: libmx-devel +BuildRequires: vala-devel +BuildRequires: pkgconfig(gee-1.0) +BuildRequires: gnome-video-effects +BuildRequires: gnome-desktop3-devel +BuildRequires: chrpath +BuildRequires: itstool +# 3.8.2 tarball misses man page +BuildRequires: libxslt +BuildRequires: docbook-style-xsl +BuildRequires: /usr/bin/convert + +Requires: %{name}-libs%{?_isa} = %{epoch}:%{version}-%{release} +Requires: gstreamer1-plugins-good +Requires: gstreamer1-plugins-bad-free +Requires: gnome-video-effects + +%description +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+ + +%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%{?_isa} = %{epoch}:%{version}-%{release} + +%description libs-devel +This package contains the libraries and header files that are needed +for writing applications that require a webcam display widget. + +%prep +%setup -q +%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 +%patch36 -p1 +%patch37 -p1 +%patch38 -p1 +%patch39 -p1 +%patch40 -p1 +%patch41 -p1 +%patch42 -p1 +%patch43 -p1 +%patch44 -p1 +%patch45 -p1 +%patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 +%patch50 -p1 +%patch51 -p1 + + +%build +%configure --disable-static --enable-man +make %{?_smp_mflags} + + +%install +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 + +%find_lang %{name} --with-gnome + +chrpath --delete $RPM_BUILD_ROOT%{_bindir}/cheese +chrpath --delete $RPM_BUILD_ROOT%{_libdir}/libcheese-gtk.so.* + +%post +touch --no-create %{_datadir}/icons/hicolor >&/dev/null || : + + +%postun +if [ $1 -eq 0 ]; then + touch --no-create %{_datadir}/icons/hicolor >&/dev/null || : + gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : +fi + +%posttrans +gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || : + +%post libs +/sbin/ldconfig +if [ $1 -eq 1 ] ; then + glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : +fi + +%postun libs +/sbin/ldconfig +glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : + +%files +%doc AUTHORS README +%{_bindir}/cheese +%{_datadir}/applications/cheese.desktop +%{_datadir}/cheese +%{_datadir}/icons/hicolor/*/apps/cheese.png +%{_datadir}/icons/hicolor/*/actions/*.png +%{_datadir}/icons/hicolor/scalable/actions/*.svg +%{_mandir}/man1/cheese.1.gz + +%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 +%{_libdir}/libcheese.so +%{_libdir}/libcheese-gtk.so +%{_includedir}/cheese/ +%{_datadir}/gtk-doc/ +%{_libdir}/pkgconfig/cheese.pc +%{_libdir}/pkgconfig/cheese-gtk.pc +%{_datadir}/gir-1.0/Cheese-3.0.gir + +%changelog +* Tue Jul 16 2013 Matthias Clasen - 2:3.8.2-5 +- Remove live image hack that causes multilib problems + +* Thu Jun 20 2013 Hans de Goede - 2:3.8.2-4 +- Fix misbehavior when started without a camera +- Don't crash when the (last) camera gets unplugged +- Automatically use a newly plugged camera when going from 0 to 1 cameras +- Misc. other bugfixes + +* Mon Jun 17 2013 Hans de Goede - 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 - 2:3.8.2-2 +- Conserve space by shrinking images + +* Mon May 13 2013 Matthias Clasen - 2:3.8.2-1 +- Update to 3.8.2 + +* Mon Apr 15 2013 Kalev Lember - 2:3.8.1-1 +- Update to 3.8.1 + +* Tue Mar 26 2013 Kalev Lember - 2:3.8.0-1 +- Update to 3.8.0 + +* Wed Mar 20 2013 Kalev Lember - 2:3.7.92-2 +- Rebuilt for clutter-gtk soname bump + +* Wed Mar 20 2013 Richard Hughes - 2:3.7.92-1 +- Update to 3.7.92 + +* Wed Mar 6 2013 Matthias Clasen - 2:3.7.91-1 +- Update to 3.7.91 + +* Thu Feb 21 2013 Kalev Lember - 2:3.7.90-3 +- Rebuilt for cogl soname bump + +* Wed Feb 20 2013 Kalev Lember - 2:3.7.90-2 +- Rebuilt for libgnome-desktop soname bump + +* Tue Feb 19 2013 Richard Hughes - 2:3.7.90-1 +- Update to 3.7.90 + +* Fri Jan 25 2013 Peter Robinson 2:3.7.4-2 +- Rebuild for new cogl + +* Wed Jan 16 2013 Richard Hughes - 2:3.7.4-1 +- Update to 3.7.4 + +* Thu Dec 20 2012 Kalev Lember - 2:3.7.3-1 +- Update to 3.7.3 + +* Tue Nov 13 2012 Kalev Lember - 2:3.6.2-1 +- Update to 3.6.2 + +* Wed Oct 17 2012 Kalev Lember - 2:3.6.1-1 +- Update to 3.6.1 + +* Tue Sep 25 2012 Richard Hughes - 2:3.6.0-1 +- Update to 3.6.0 + +* Wed Sep 19 2012 Richard Hughes - 2:3.5.92-1 +- Update to 3.5.92 + +* Thu Sep 6 2012 Matthias Clasen - 2:3.5.91-1 +- Update to 3.5.91 +- Drop upstreamed patches + +* Tue Aug 28 2012 Matthias Clasen - 2:3.5.5-2 +- Rebuild against new cogl/clutter + +* Wed Aug 22 2012 Hans de Goede - 2:3.5.5-1 +- New upstream release 3.5.5 +- Fix cheese crashing on tvcards which report they can capture 0x0 as + minimum resolution (rhbz#850505) + +* Tue Aug 21 2012 Brian Pepple - 2:3.5.2-6 +- Rebuild for new libcogl. + +* Fri Jul 27 2012 Fedora Release Engineering - 2:3.5.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jun 19 2012 Hans de Goede - 2:3.4.2-3 +- Reduce camerabin pipeline creation time (rhbz#797188, gnome#677731) +- Don't add 0 byte sized files to the thumb-view (rhbz#830166, gnome#677735) +- Fix sizing of horizontal thumbnail list (rhbz#829957) +- Optimize encoding parameters (rhbz#572169) + +* Wed Jun 13 2012 Owen Taylor - 2:3.5.2-3 +- Require matching version of cheese-libs for cheese + +* Thu Jun 07 2012 Matthias Clasen - 2:3.5.2-2 +- Rebuild against new gnome-desktop + +* Thu Jun 07 2012 Richard Hughes - 2:3.5.2-1 +- Update to 3.5.2 + +* Tue Jun 5 2012 Hans de Goede - 2:3.5.1-2 +- Fix missing images on buttons, also fixes the "Gtk-WARNING **: Attempting to + add a widget with type GtkImage to a GtkButton ..." warnings (gnome#677543) +- Fix cheese crashing when started on machines with v4l2 radio or vbi devices + (rhbz#810429, gnome#677544) + +* Sun May 06 2012 Kalev Lember - 2:3.5.1-1 +- Update to 3.5.1 + +* Tue Apr 17 2012 Kalev Lember - 2:3.4.1-1 +- Update to 3.4.1 + +* Tue Mar 27 2012 Richard Hughes - 2:3.4.0-1 +- Update to 3.4.0 + +* Wed Mar 14 2012 Brian Pepple - 2:3.3.5-2 +- Rebuild for new cogl + +* Tue Feb 7 2012 Matthias Clasen - 2:3.3.5-1 +- Update to 3.3.5 + +* Tue Jan 17 2012 Matthias Clasen - 2:3.3.4-1 +- Update to 3.3.4 + +* Mon Jan 16 2012 Matthias Clasen - 2:3.3.3-3 +- Add a BuildRequires for itstool + +* Thu Jan 12 2012 Fedora Release Engineering - 2:3.3.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Dec 21 2011 Matthias Clasen - 2:3.3.3-1 +- Update to 3.3.3 + +* Thu Nov 24 2011 Matthias Clasen - 1:3.3.2-2 +- Rebuild against new clutter + +* Tue Nov 22 2011 Tomas Bzatek - 1:3.3.2-1 +- Update to 3.3.2 + +* Wed Nov 2 2011 Matthias Clasen - 1:3.3.1-1 +- Update to 3.3.1-1 + +* Wed Oct 26 2011 Fedora Release Engineering - 1:3.2.1-2 +- Rebuilt for glibc bug#747377 + +* Tue Oct 18 2011 Matthias Clasen - 1:3.2.1-1 +- Update to 3.2.1 + +* Thu Sep 29 2011 Hans de Goede - 1:3.2.0-2 +- Add Requires: gstreamer-plugins-bad-free for the camerabin element (#717872) + +* Tue Sep 27 2011 Ray - 1:3.2.0-1 +- Update to 3.2.0 + +* Wed Sep 21 2011 Brian Pepple - 1:3.1.92-2 +- Rebuld for new libcogl. +- Use old libgee api. + +* Tue Sep 20 2011 Matthias Clasen - 1:3.1.92-1 +- Update to 3.1.92 + +* Tue Sep 6 2011 Matthias Clasen - 1:3.1.91.1-1 +- Update to 3.1.91.1 + +* Tue Jul 26 2011 Matthias Clasen - 1:3.0.2-2 +- Rebuild + +* Mon Jul 25 2011 Matthias Clasen - 1:3.0.2-1 +- Update to 3.0.2 + +* Wed Jun 29 2011 Julian Sikorski - 1:3.0.1-3 +- Removed RPATHS (RH #703636) + +* Wed Jun 15 2011 Bastien Nocera 3.0.1-2 +- Rebuild against newest gnome-desktop3 + +* Tue Apr 26 2011 Matthias Clasen 1:3.0.1-1 +- Update to 3.0.1 + +* Tue Apr 5 2011 Matthias Clasen 1:3.0.0-2 +- Add newer icons from upstream + +* Mon Apr 4 2011 Christopher Aillon 1:3.0.0-1 +- Update to 3.0 + +* Wed Mar 30 2011 Alexander Larsson - 1:2.91.93-3 +- Move gsettings schema to cheese-libs, fixes control-center crash (#691667) +- Move typelib to cheese-libs + +* Mon Mar 28 2011 Bastien Nocera 2.91.93-2 +- Add missing gnome-video-effects dependency + +* Fri Mar 25 2011 Bastien Nocera 2.91.93-1 +- Update to 2.91.93 + +* Tue Mar 22 2011 Matthias Clasen 1:2.91.92-1 +- Update to 2.91.92 + +* Sat Mar 12 2011 Bastien Nocera 2.91.91.1-1 +- Update to 2.91.91.1 + +* Tue Feb 08 2011 Fedora Release Engineering - 1:2.91.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Feb 2 2011 Christopher Aillon 1:2.91.4-1 +- Update to 2.91.4 + +* Mon Jan 10 2011 Matthias Clasen 1:2.91.3-1 +- Update to 2.91.3 + +* Thu Sep 30 2010 Matthias Clasen 1:2.32.0-1 +- Update to 2.32.0 + +* Tue Aug 31 2010 Matthias Clasen 1:2.31.91-1 +- Update to 2.31.91 + +* Mon Aug 23 2010 Matthias Clasen 1:2.31.90-2 +- Co-own /usr/share/gtk-doc + +* Thu Aug 19 2010 Matthias Clasen 1:2.31.90-1 +- Update to 2.31.90 + +* Wed Aug 11 2010 Matthias Clasen 1:2.31.1-2 +- Add an epoch to stay ahead of F14 + +* Fri Aug 6 2010 Matthias Clasen 2.31.1-1 +- Update to 2.31.1 + +* Tue Apr 27 2010 Matthias Clasen 2.30.1-1 +- Update to 2.30.1 +- Spec file cleanups + +* Mon Mar 29 2010 Matthias Clasen 2.30.0-1 +- Update to 2.30.0 + +* Wed Mar 24 2010 Bastien Nocera 2.29.92-4 +- Fix possible crasher when countdown reaches zero + +* Fri Mar 19 2010 Matthias Clasen 2.29.92-3 +- Fix text rendering issues on the effects tab + +* Tue Mar 16 2010 Matthias Clasen 2.29.92-2 +- Use an existing icon + +* Tue Mar 09 2010 Bastien Nocera 2.29.92-1 +- Update to 2.29.92 + +* Tue Feb 09 2010 Bastien Nocera 2.29.90-2 +- Fix include path, and missing requires for the pkg-config file + +* Tue Feb 09 2010 Bastien Nocera 2.29.90-1 +- Update to 2.29.90 + +* Sun Jan 17 2010 Matthias Clasen 2.29.5-2 +- Rebuild + +* Tue Jan 12 2010 Matthias Clasen 2.29.5-1 +- Update to 2.29.5 + +* Sun Sep 27 2009 Orcan Ogetbil 2.28.0-2 +- Update desktop file according to F-12 FedoraStudio feature + +* Mon Sep 21 2009 Matthias Clasen 2.28.0-1 +- Update to 2.28.0 + +* Mon Sep 7 2009 Matthias Clasen 2.27.92-1 +- Update to 2.27.92 + +* Mon Aug 24 2009 Matthias Clasen 2.27.91-1 +- Update to 2.27.91 + +* Sat Aug 22 2009 Matthias Clasen 2.27.90-3 +- Update sensitivity of menu items + +* Fri Aug 14 2009 Matthias Clasen 2.27.90-2 +- Fix schemas file syntax + +* Tue Aug 11 2009 Matthias Clasen 2.27.90-1 +- Update to 2.27.90 + +* Tue Jul 28 2009 Matthias Clasen 2.27.5-1 +- Update to 2.27.5 + +* Fri Jul 24 2009 Fedora Release Engineering - 2.27.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Jul 13 2009 Matthias Clasen 2.27.4-1 +- Update to 2.27.4 + +* Tue Jun 16 2009 Matthias Clasen 2.27.3-1 +- Update to 2.27.3 + +* Sun May 31 2009 Matthias Clasen 2.27.2-1 +- Update to 2.27.2 + +* Fri May 15 2009 Matthias Clasen 2.27.1-1 +- Update to 2.27.1 + +* Mon Mar 16 2009 Matthias Clasen 2.26.0-1 +- Update to 2.26.0 + +* Mon Mar 2 2009 Matthias Clasen 2.25.92-1 +- Update to 2.25.92 + +* Mon Feb 23 2009 Fedora Release Engineering - 2.25.91-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Feb 18 2009 Matthias Clasen 2.25.91-1 +- Update to 2.25.91 + +* Tue Feb 3 2009 Matthias Clasen 2.25.90-1 +- Update to 2.25.90 + +* Tue Jan 6 2009 Matthias Clasen 2.25.4-1 +- Update to 2.25.4 + +* Wed Dec 17 2008 Matthias Clasen 2.25.3-1 +- Update to 2.25.3 + +* Wed Dec 3 2008 Matthias Clasen 2.25.2-1 +- Update to 2.25.2 + +* Fri Nov 21 2008 Matthias Clasen 2.25.1-4 +- Better URL + +* Thu Nov 13 2008 Matthias Clasen 2.25.1-3 +- Update to 2.25.1 + +* Sun Nov 9 2008 Hans de Goede 2.24.1-2 +- Fix cams which only support 1 resolution not working (rh470698, gnome560032) + +* Mon Oct 20 2008 Matthias Clasen 2.24.1-1 +- Update to 2.24.1 + +* Wed Oct 8 2008 Matthias Clasen 2.24.0-2 +- Save space + +* Mon Sep 22 2008 Matthias Clasen 2.24.0-1 +- Update to 2.24.0 + +* Tue Sep 9 2008 Matthias Clasen 2.23.92-3 +- Update to 2.23.92 +- Drop upstreamed patches + +* Wed Sep 3 2008 Hans de Goede 2.23.91-2 +- Fix use with multiple v4l devices (rh 460956, gnome 546868, gnome 547144) + +* Tue Sep 2 2008 Matthias Clasen 2.23.91-1 +- Update to 2.23.91 + +* Fri Aug 22 2008 Matthias Clasen 2.23.90-1 +- Update to 2.23.90 + +* Tue Aug 5 2008 Matthias Clasen 2.23.6-1 +- Update to 2.23.6 + +* Tue Jul 22 2008 Matthias Clasen 2.23.5-1 +- Update to 2.23.5 + +* Wed Jun 18 2008 Matthias Clasen 2.23.4-1 +- Update to 2.23.4 + +* Tue Jun 3 2008 Matthias Clasen 2.23.3-1 +- Update to 2.23.3 + +* Tue May 13 2008 Matthias Clasen 2.23.2-1 +- Update to 2.23.2 + +* Fri Apr 25 2008 Matthias Clasen 2.23.1-1 +- Update to 2.23.1 + +* Tue Apr 22 2008 Matthias Clasen 2.22.1-2 +- Fix an invalid free + +* Mon Apr 7 2008 Matthias Clasen 2.22.1-1 +- Update to 2.22.1 + +* Mon Mar 10 2008 Matthias Clasen 2.22.0-1 +- Update to 2.22.0 + +* Tue Feb 26 2008 Matthias Clasen 2.21.92-1 +- Update to 2.21.92 + +* Fri Feb 15 2008 Matthias Clasen 2.21.91-3 +- Fix a locking problem that causes the UI to freeze + +* Fri Feb 8 2008 Matthias Clasen 2.21.91-2 +- Rebuild for gcc 4.3 + +* Tue Jan 29 2008 Matthias Clasen 2.21.91-1 +- Update to 2.21.91 + +* Mon Jan 14 2008 Matthias Clasen 2.21.5-1 +- Update to 2.21.5 + +* Mon Dec 24 2007 Matthias Clasen 0.3.0-1 +- Update to 0.3.0 + +* Fri Sep 7 2007 Matthias Clasen 0.2.4-2 +- package review feedback + +* Thu Sep 6 2007 Matthias Clasen 0.2.4-1 +- Initial packages