diff --git a/cheese-2.23.90-only-list-resolutions-once.patch b/cheese-2.23.90-only-list-resolutions-once.patch new file mode 100644 index 0000000..f3b1090 --- /dev/null +++ b/cheese-2.23.90-only-list-resolutions-once.patch @@ -0,0 +1,49 @@ +diff -up cheese-2.23.90/src/cheese-webcam.c.qwerty cheese-2.23.90/src/cheese-webcam.c +--- cheese-2.23.90/src/cheese-webcam.c.qwerty 2008-09-02 17:14:30.000000000 +0200 ++++ cheese-2.23.90/src/cheese-webcam.c 2008-09-02 19:38:50.000000000 +0200 +@@ -442,6 +442,7 @@ cheese_webcam_add_video_format (CheeseWe + CheeseVideoFormat *video_format, GstStructure *format_structure) + { + int i; ++ gchar *resolution; + + cheese_webcam_get_supported_framerates (video_format, format_structure); + find_highest_framerate (video_format); +@@ -453,12 +454,33 @@ cheese_webcam_add_video_format (CheeseWe + g_print ("%d/%d ", video_format->framerates[i].numerator, + video_format->framerates[i].denominator); + } +- g_print ("\n"); ++ ++ resolution = g_strdup_printf ("%ix%i", video_format->width, ++ video_format->height); ++ i = GPOINTER_TO_INT(g_hash_table_lookup ( ++ webcam_device->supported_resolutions, ++ resolution)); ++ if (i) { /* Resolution already added ? */ ++ CheeseVideoFormat *curr_format = &g_array_index( ++ webcam_device->video_formats, ++ CheeseVideoFormat, i - 1); ++ float new_framerate = (float)video_format->highest_framerate.numerator / ++ video_format->highest_framerate.denominator; ++ float curr_framerate = (float)curr_format->highest_framerate.numerator / ++ curr_format->highest_framerate.denominator; ++ if (new_framerate > curr_framerate) { ++ g_print ("higher framerate replacing existing format\n"); ++ *curr_format = *video_format; ++ } ++ else ++ g_print ("already added, skipping\n"); ++ ++ g_free (resolution); ++ return; ++ } + + g_array_append_val (webcam_device->video_formats, *video_format); +- g_hash_table_insert (webcam_device->supported_resolutions, +- g_strdup_printf ("%ix%i", video_format->width, +- video_format->height), ++ g_hash_table_insert (webcam_device->supported_resolutions, resolution, + GINT_TO_POINTER(webcam_device->num_video_formats + 1)); + + webcam_device->num_video_formats++; diff --git a/cheese-2.23.90-sort-resolutions.patch b/cheese-2.23.90-sort-resolutions.patch new file mode 100644 index 0000000..0ebcabc --- /dev/null +++ b/cheese-2.23.90-sort-resolutions.patch @@ -0,0 +1,42 @@ +diff -up cheese-2.23.90/src/cheese-webcam.c.qwerty cheese-2.23.90/src/cheese-webcam.c +--- cheese-2.23.90/src/cheese-webcam.c.qwerty 2008-09-02 19:41:29.000000000 +0200 ++++ cheese-2.23.90/src/cheese-webcam.c 2008-09-02 20:01:33.000000000 +0200 +@@ -486,6 +486,17 @@ cheese_webcam_add_video_format (CheeseWe + webcam_device->num_video_formats++; + } + ++static gint cheese_resolution_compare(gconstpointer _a, gconstpointer _b) ++{ ++ const CheeseVideoFormat *a = _a; ++ const CheeseVideoFormat *b = _b; ++ ++ if (a->width == b->width) ++ return a->height - b->height; ++ ++ return a->width - b->width; ++} ++ + static void + cheese_webcam_get_supported_video_formats (CheeseWebcamDevice *webcam_device, GstCaps *caps) + { +@@ -564,6 +575,20 @@ cheese_webcam_get_supported_video_format + g_critical ("GValue type %s, cannot be handled for resolution width", G_VALUE_TYPE_NAME (width)); + } + } ++ ++ /* Sort the format array (so that it will show sorted in the resolution ++ selection GUI), and rebuild the hashtable (as that will be invalid after ++ the sorting) */ ++ g_array_sort (webcam_device->video_formats, cheese_resolution_compare); ++ g_hash_table_remove_all (webcam_device->supported_resolutions); ++ for (i = 0; i < webcam_device->num_video_formats; i++) { ++ CheeseVideoFormat *format = &g_array_index(webcam_device->video_formats, ++ CheeseVideoFormat, i); ++ g_hash_table_insert (webcam_device->supported_resolutions, ++ g_strdup_printf ("%ix%i", format->width, ++ format->height), ++ GINT_TO_POINTER(i + 1)); ++ } + } + + static void diff --git a/cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch b/cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch new file mode 100644 index 0000000..d1ca7c5 --- /dev/null +++ b/cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch @@ -0,0 +1,237 @@ +diff -up cheese-2.23.91/src/cheese-webcam.c.coocoo cheese-2.23.91/src/cheese-webcam.c +--- cheese-2.23.91/src/cheese-webcam.c.coocoo 2008-09-03 20:34:12.000000000 +0200 ++++ cheese-2.23.91/src/cheese-webcam.c 2008-09-03 22:36:43.000000000 +0200 +@@ -48,6 +48,8 @@ G_DEFINE_TYPE (CheeseWebcam, cheese_webc + + #define CHEESE_WEBCAM_ERROR cheese_webcam_error_quark () + ++static void find_highest_framerate (CheeseVideoFormat *format); ++ + enum CheeseWebcamError + { + CHEESE_WEBCAM_ERROR_UNKNOWN, +@@ -444,6 +446,33 @@ cheese_webcam_get_supported_framerates ( + } + + static void ++cheese_webcam_add_video_format (CheeseWebcamDevice *webcam_device, ++ CheeseVideoFormat *video_format, GstStructure *format_structure) ++{ ++ int i; ++ ++ cheese_webcam_get_supported_framerates (video_format, format_structure); ++ find_highest_framerate (video_format); ++ ++ g_print ("%s %d x %d num_framerates %d\n", video_format->mimetype, video_format->width, ++ video_format->height, video_format->num_framerates); ++ for (i = 0; i < video_format->num_framerates; i++) ++ { ++ g_print ("%d/%d ", video_format->framerates[i].numerator, ++ video_format->framerates[i].denominator); ++ } ++ g_print ("\n"); ++ ++ g_array_append_val (webcam_device->video_formats, *video_format); ++ g_hash_table_insert (webcam_device->supported_resolutions, ++ g_strdup_printf ("%ix%i", video_format->width, ++ video_format->height), ++ GINT_TO_POINTER(webcam_device->num_video_formats + 1)); ++ ++ webcam_device->num_video_formats++; ++} ++ ++static void + cheese_webcam_get_supported_video_formats (CheeseWebcamDevice *webcam_device, GstCaps *caps) + { + int i; +@@ -476,10 +505,7 @@ cheese_webcam_get_supported_video_format + video_format.mimetype = g_strdup (gst_structure_get_name (structure)); + gst_structure_get_int (structure, "width", &(video_format.width)); + gst_structure_get_int (structure, "height", &(video_format.height)); +- cheese_webcam_get_supported_framerates (&video_format, structure); +- +- g_array_append_val (webcam_device->video_formats, video_format); +- webcam_device->num_video_formats++; ++ cheese_webcam_add_video_format(webcam_device, &video_format, structure); + } + else if (GST_VALUE_HOLDS_INT_RANGE (width)) + { +@@ -500,9 +526,7 @@ cheese_webcam_get_supported_video_format + video_format.mimetype = g_strdup (gst_structure_get_name (structure)); + video_format.width = cur_width; + video_format.height = cur_height; +- cheese_webcam_get_supported_framerates (&video_format, structure); +- g_array_append_val (webcam_device->video_formats, video_format); +- webcam_device->num_video_formats++; ++ cheese_webcam_add_video_format(webcam_device, &video_format, structure); + cur_width *= 2; + cur_height *= 2; + } +@@ -516,9 +540,7 @@ cheese_webcam_get_supported_video_format + video_format.mimetype = g_strdup (gst_structure_get_name (structure)); + video_format.width = cur_width; + video_format.height = cur_height; +- cheese_webcam_get_supported_framerates (&video_format, structure); +- g_array_append_val (webcam_device->video_formats, video_format); +- webcam_device->num_video_formats++; ++ cheese_webcam_add_video_format(webcam_device, &video_format, structure); + cur_width /= 2; + cur_height /= 2; + } +@@ -540,7 +562,6 @@ cheese_webcam_get_webcam_device_data (Ch + GstStateChangeReturn ret; + GstMessage *msg; + GstBus *bus; +- int i, j; + + { + pipeline_desc = g_strdup_printf ("%s name=source device=%s ! fakesink", +@@ -575,6 +596,7 @@ cheese_webcam_get_webcam_device_data (Ch + name = "Unknown"; + + g_print ("Detected webcam: %s\n", name); ++ g_print ("device: %s\n", webcam_device->video_device); + pad = gst_element_get_pad (src, "src"); + caps = gst_pad_get_caps (pad); + gst_object_unref (pad); +@@ -589,27 +611,6 @@ cheese_webcam_get_webcam_device_data (Ch + + g_free (pipeline_desc); + } +- +- g_print ("device: %s\n", webcam_device->video_device); +- for (i = 0; i < webcam_device->num_video_formats; i++) +- { +- CheeseVideoFormat video_format; +- +- video_format = g_array_index (webcam_device->video_formats, CheeseVideoFormat, i); +- g_hash_table_insert (webcam_device->supported_resolutions, +- g_strdup_printf ("%ix%i", video_format.width, +- video_format.height), +- &g_array_index (webcam_device->video_formats, +- CheeseVideoFormat, i)); +- g_print ("%s %d x %d num_framerates %d\n", video_format.mimetype, video_format.width, +- video_format.height, video_format.num_framerates); +- for (j = 0; j < video_format.num_framerates; j++) +- { +- g_print ("%d/%d ", video_format.framerates[j].numerator, +- video_format.framerates[j].denominator); +- } +- g_print ("\n"); +- } + } + + static void +@@ -651,8 +652,7 @@ cheese_webcam_detect_webcam_devices (Che + } + + static void +-find_highest_framerate (CheeseVideoFormat *format, int *numerator, +- int *denominator) ++find_highest_framerate (CheeseVideoFormat *format) + { + int framerate_numerator; + int framerate_denominator; +@@ -672,8 +672,8 @@ find_highest_framerate (CheeseVideoForma + } + } + +- *numerator = framerate_numerator; +- *denominator = framerate_denominator; ++ format->highest_framerate.numerator = framerate_numerator; ++ format->highest_framerate.denominator = framerate_denominator; + } + + static gboolean +@@ -695,7 +695,6 @@ cheese_webcam_create_webcam_source_bin ( + { + CheeseVideoFormat *format; + int i; +- int framerate_numerator, framerate_denominator; + gchar *resolution; + + /* If we have a matching video device use that one, otherwise use the first */ +@@ -714,7 +713,12 @@ cheese_webcam_create_webcam_source_bin ( + /* Use the previously set resolution from gconf if it is set and the + * camera supports it. */ + if (priv->x_resolution != 0 && priv->y_resolution != 0) +- format = g_hash_table_lookup (selected_webcam->supported_resolutions, resolution); ++ { ++ i = GPOINTER_TO_INT(g_hash_table_lookup (selected_webcam->supported_resolutions, resolution)); ++ if (i) ++ format = &g_array_index (selected_webcam->video_formats, ++ CheeseVideoFormat, i - 1); ++ } + + if (!format) + { +@@ -738,21 +742,18 @@ cheese_webcam_create_webcam_source_bin ( + if (format == NULL) + goto fallback; + +- find_highest_framerate (format, &framerate_numerator, +- &framerate_denominator); +- + webcam_input = g_strdup_printf ( + "%s name=video_source device=%s ! capsfilter name=capsfilter caps=video/x-raw-rgb,width=%d,height=%d,framerate=%d/%d;video/x-raw-yuv,width=%d,height=%d,framerate=%d/%d ! identity", + selected_webcam->gstreamer_src, + selected_webcam->video_device, + format->width, + format->height, +- framerate_numerator, +- framerate_denominator, ++ format->highest_framerate.numerator, ++ format->highest_framerate.denominator, + format->width, + format->height, +- framerate_numerator, +- framerate_denominator); ++ format->highest_framerate.numerator, ++ format->highest_framerate.denominator); + g_print ("%s\n", webcam_input); + + priv->webcam_source_bin = gst_parse_bin_from_description (webcam_input, +@@ -1539,10 +1540,6 @@ cheese_webcam_set_video_format (CheeseWe + CheeseWebcamPrivate *priv = CHEESE_WEBCAM_GET_PRIVATE (webcam); + + GstCaps *new_caps; +- int framerate_numerator; +- int framerate_denominator; +- +- find_highest_framerate (format, &framerate_numerator, &framerate_denominator); + + new_caps = gst_caps_new_simple ("video/x-raw-rgb", + "width", G_TYPE_INT, +@@ -1550,8 +1547,8 @@ cheese_webcam_set_video_format (CheeseWe + "height", G_TYPE_INT, + format->height, + "framerate", GST_TYPE_FRACTION, +- framerate_numerator, +- framerate_denominator, ++ format->highest_framerate.numerator, ++ format->highest_framerate.denominator, + NULL); + + gst_caps_append(new_caps, gst_caps_new_simple ("video/x-raw-yuv", +@@ -1560,8 +1557,8 @@ cheese_webcam_set_video_format (CheeseWe + "height", G_TYPE_INT, + format->height, + "framerate", GST_TYPE_FRACTION, +- framerate_numerator, +- framerate_denominator, ++ format->highest_framerate.numerator, ++ format->highest_framerate.denominator, + NULL)); + + priv->current_format = format; +diff -up cheese-2.23.91/src/cheese-webcam.h.coocoo cheese-2.23.91/src/cheese-webcam.h +--- cheese-2.23.91/src/cheese-webcam.h.coocoo 2008-09-03 20:27:59.000000000 +0200 ++++ cheese-2.23.91/src/cheese-webcam.h 2008-09-03 22:31:42.000000000 +0200 +@@ -49,6 +49,7 @@ typedef struct + int height; + int num_framerates; + CheeseFramerate *framerates; ++ CheeseFramerate highest_framerate; + } CheeseVideoFormat; + + typedef struct diff --git a/cheese-2.23.91-dont-use-non-capture-devices.patch b/cheese-2.23.91-dont-use-non-capture-devices.patch new file mode 100644 index 0000000..3ddb84e --- /dev/null +++ b/cheese-2.23.91-dont-use-non-capture-devices.patch @@ -0,0 +1,242 @@ +diff -up cheese-2.23.91/src/cheese-webcam.c.orig cheese-2.23.91/src/cheese-webcam.c +--- cheese-2.23.91/src/cheese-webcam.c.orig 2008-09-01 20:47:10.000000000 +0200 ++++ cheese-2.23.91/src/cheese-webcam.c 2008-09-03 20:27:25.000000000 +0200 +@@ -33,6 +33,11 @@ + #include + #include + #include ++/* for ioctl query */ ++#include ++#include ++#include ++#include + + #include "cheese-webcam.h" + #include "cheese-flash.h" +@@ -235,16 +240,13 @@ cheese_webcam_get_video_devices_from_hal + { + CheeseWebcamPrivate *priv = CHEESE_WEBCAM_GET_PRIVATE (webcam); + +- int i; +- int num_udis; +- int num_devices; /* Devices we actually create formats for; can either be the +- * number of webcams detected, or 1 if none were. The one +- * refers to a fake device so that resolution changing still +- * works even if the computer doesn't have a webcam. */ ++ int i, fd, ok; ++ int num_udis = 0; + char **udis; + DBusError error; + LibHalContext *hal_ctx; + ++ priv->num_webcam_devices = 0; + + dbus_error_init (&error); + hal_ctx = libhal_ctx_new (); +@@ -252,14 +254,14 @@ cheese_webcam_get_video_devices_from_hal + { + g_error ("error: libhal_ctx_new"); + dbus_error_free (&error); +- return; ++ goto fallback; + } + + if (!libhal_ctx_set_dbus_connection (hal_ctx, dbus_bus_get (DBUS_BUS_SYSTEM, &error))) + { + g_error ("error: libhal_ctx_set_dbus_connection: %s: %s", error.name, error.message); + dbus_error_free (&error); +- return; ++ goto fallback; + } + + if (!libhal_ctx_init (hal_ctx, &error)) +@@ -271,53 +273,113 @@ cheese_webcam_get_video_devices_from_hal + } + g_error ("Could not initialise connection to hald.\n" + "Normally this means the HAL daemon (hald) is not running or not ready"); +- return; ++ goto fallback; + } + + udis = libhal_find_device_by_capability (hal_ctx, "video4linux", &num_udis, &error); + + if (dbus_error_is_set (&error)) + { +- g_error ("error: %s: %s\n", error.name, error.message); ++ g_error ("error: libhal_find_device_by_capability: %s: %s\n", error.name, error.message); + dbus_error_free (&error); +- return; ++ goto fallback; + } + + /* Initialize webcam structures */ ++ priv->webcam_devices = g_new0 (CheeseWebcamDevice, num_udis); + +- if (num_udis > 0) +- priv->num_webcam_devices = num_devices = num_udis; +- else +- { +- num_devices = 1; +- priv->num_webcam_devices = num_udis; /* We don't have any real cameras-- +- * this is important when we create +- * the pipeline. */ +- } +- +- priv->webcam_devices = g_new0 (CheeseWebcamDevice, num_devices); +- for (i = 0; i < num_devices; i++) +- { +- priv->webcam_devices[i].num_video_formats = 0; +- priv->webcam_devices[i].video_formats = g_array_new (FALSE, FALSE, sizeof (CheeseVideoFormat)); +- priv->webcam_devices[i].hal_udi = g_strdup (udis[i]); +- } +- +- for (i = 0; i < priv->num_webcam_devices; i++) ++ for (i = 0; i < num_udis; i++) + { + char *device; ++ char *gstreamer_src, *product_name; ++ struct v4l2_capability v2cap; ++ struct video_capability v1cap; + + device = libhal_device_get_property_string (hal_ctx, udis[i], "video4linux.device", &error); +- if (dbus_error_is_set (&error)) ++ if (dbus_error_is_set (&error)) + { +- g_error ("error: %s: %s\n", error.name, error.message); ++ g_error ("error geting device for %s: %s: %s\n", udis[i], error.name, error.message); + dbus_error_free (&error); +- return; ++ continue; ++ } ++ ++ /* vbi devices support capture capability too, but cannot be used, ++ so detect them by device name */ ++ if (strstr(device, "vbi")) ++ { ++ g_print ("Skipping vbi device: %s\n", device); ++ libhal_free_string (device); ++ continue; ++ } ++ ++ if ((fd = open(device, O_RDONLY | O_NONBLOCK)) < 0) ++ { ++ g_error ("Failed to open %s: %s\n", device, strerror(errno)); ++ libhal_free_string (device); ++ continue; ++ } ++ ok = ioctl (fd, VIDIOC_QUERYCAP, &v2cap); ++ if (ok < 0) { ++ ok = ioctl (fd, VIDIOCGCAP, &v1cap); ++ if (ok < 0) { ++ g_error ("Error while probing v4l capabilities for %s: %s\n", ++ device, strerror (errno)); ++ libhal_free_string (device); ++ close(fd); ++ continue; ++ } ++ g_print ("Detected v4l device: %s\n", v1cap.name); ++ g_print ("Device type: %d\n", v1cap.type); ++ gstreamer_src = "v4lsrc"; ++ product_name = v1cap.name; ++ } ++ else ++ { ++ guint cap = v2cap.capabilities; ++ g_print ("Detected v4l2 device: %s\n", v2cap.card); ++ g_print ("Driver: %s, version: %d\n", v2cap.driver, v2cap.version); ++ g_print ("Bus info: %s\n", v2cap.bus_info); ++ g_print ("Capabilities: 0x%08X\n", v2cap.capabilities); ++ if (!(cap & V4L2_CAP_VIDEO_CAPTURE)) ++ { ++ g_print ("Device %s seems to not have the capture capability, (radio tuner?)\n" ++ "Removing it from device list.\n", device); ++ libhal_free_string (device); ++ close(fd); ++ continue; ++ } ++ gstreamer_src = "v4l2src"; ++ product_name = (char *)v2cap.card; + } +- priv->webcam_devices[i].video_device = g_strdup (device); ++ ++ priv->webcam_devices[priv->num_webcam_devices].hal_udi = g_strdup (udis[i]); ++ priv->webcam_devices[priv->num_webcam_devices].video_device = g_strdup (device); ++ priv->webcam_devices[priv->num_webcam_devices].gstreamer_src = g_strdup (gstreamer_src); ++ priv->webcam_devices[priv->num_webcam_devices].product_name = g_strdup (product_name); ++ priv->webcam_devices[priv->num_webcam_devices].num_video_formats = 0; ++ priv->webcam_devices[priv->num_webcam_devices].video_formats = ++ g_array_new (FALSE, FALSE, sizeof (CheeseVideoFormat)); ++ priv->num_webcam_devices++; ++ + libhal_free_string (device); ++ close(fd); + } + libhal_free_string_array (udis); ++ ++ if (priv->num_webcam_devices == 0) ++ { ++ /* Create a fake device so that resolution changing stil works even if the ++ computer doesn't have a webcam. */ ++fallback: ++ if (num_udis == 0) ++ { ++ priv->webcam_devices = g_new0 (CheeseWebcamDevice, 1); ++ } ++ priv->webcam_devices[0].num_video_formats = 0; ++ priv->webcam_devices[0].video_formats = ++ g_array_new (FALSE, FALSE, sizeof (CheeseVideoFormat)); ++ priv->webcam_devices[0].hal_udi = g_strdup ("cheese_fake_videodevice"); ++ } + } + + static void +@@ -479,19 +541,11 @@ cheese_webcam_get_webcam_device_data (Ch + GstStateChangeReturn ret; + GstMessage *msg; + GstBus *bus; +- gboolean pipeline_works = FALSE; + int i, j; + +- static const char *GSTREAMER_VIDEO_SOURCES[] = { +- "v4l2src", +- "v4lsrc" +- }; +- +- i = 0; +- while (!pipeline_works && (i < G_N_ELEMENTS (GSTREAMER_VIDEO_SOURCES))) + { + pipeline_desc = g_strdup_printf ("%s name=source device=%s ! fakesink", +- GSTREAMER_VIDEO_SOURCES[i], ++ webcam_device->gstreamer_src, + webcam_device->video_device); + err = NULL; + pipeline = gst_parse_launch (pipeline_desc, &err); +@@ -513,10 +567,8 @@ cheese_webcam_get_webcam_device_data (Ch + char *name; + GstCaps *caps; + +- pipeline_works = TRUE; + gst_element_set_state (pipeline, GST_STATE_PAUSED); + +- webcam_device->gstreamer_src = g_strdup (GSTREAMER_VIDEO_SOURCES[i]); + src = gst_bin_get_by_name (GST_BIN (pipeline), "source"); + + g_object_get (G_OBJECT (src), "device-name", &name, NULL); +@@ -524,7 +576,6 @@ cheese_webcam_get_webcam_device_data (Ch + name = "Unknown"; + + g_print ("Detected webcam: %s\n", name); +- webcam_device->product_name = g_strdup (name); + pad = gst_element_get_pad (src, "src"); + caps = gst_pad_get_caps (pad); + gst_object_unref (pad); +@@ -538,8 +589,8 @@ cheese_webcam_get_webcam_device_data (Ch + g_error_free (err); + + g_free (pipeline_desc); +- i++; + } ++ + g_print ("device: %s\n", webcam_device->video_device); + for (i = 0; i < webcam_device->num_video_formats; i++) + { diff --git a/cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch b/cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch new file mode 100644 index 0000000..9f17f2a --- /dev/null +++ b/cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch @@ -0,0 +1,45 @@ +diff -up cheese-2.23.91/src/cheese-webcam.c.foo cheese-2.23.91/src/cheese-webcam.c +--- cheese-2.23.91/src/cheese-webcam.c.foo 2008-09-03 22:43:48.000000000 +0200 ++++ cheese-2.23.91/src/cheese-webcam.c 2008-09-03 22:44:46.000000000 +0200 +@@ -742,10 +742,13 @@ cheese_webcam_create_webcam_source_bin ( + &framerate_denominator); + + webcam_input = g_strdup_printf ( +- "%s name=video_source device=%s ! capsfilter name=capsfilter caps=%s,width=%d,height=%d,framerate=%d/%d ! identity", ++ "%s name=video_source device=%s ! capsfilter name=capsfilter caps=video/x-raw-rgb,width=%d,height=%d,framerate=%d/%d;video/x-raw-yuv,width=%d,height=%d,framerate=%d/%d ! identity", + selected_webcam->gstreamer_src, + selected_webcam->video_device, +- format->mimetype, ++ format->width, ++ format->height, ++ framerate_numerator, ++ framerate_denominator, + format->width, + format->height, + framerate_numerator, +@@ -1541,7 +1544,7 @@ cheese_webcam_set_video_format (CheeseWe + + find_highest_framerate (format, &framerate_numerator, &framerate_denominator); + +- new_caps = gst_caps_new_simple (format->mimetype, ++ new_caps = gst_caps_new_simple ("video/x-raw-rgb", + "width", G_TYPE_INT, + format->width, + "height", G_TYPE_INT, +@@ -1551,6 +1554,16 @@ cheese_webcam_set_video_format (CheeseWe + framerate_denominator, + NULL); + ++ gst_caps_append(new_caps, gst_caps_new_simple ("video/x-raw-yuv", ++ "width", G_TYPE_INT, ++ format->width, ++ "height", G_TYPE_INT, ++ format->height, ++ "framerate", GST_TYPE_FRACTION, ++ framerate_numerator, ++ framerate_denominator, ++ NULL)); ++ + priv->current_format = format; + + cheese_webcam_stop (webcam); diff --git a/cheese-2.23.91-supported-resolutions-per-device.patch b/cheese-2.23.91-supported-resolutions-per-device.patch new file mode 100644 index 0000000..3a95cba --- /dev/null +++ b/cheese-2.23.91-supported-resolutions-per-device.patch @@ -0,0 +1,88 @@ +diff -up cheese-2.23.91/src/cheese-webcam.c.foo cheese-2.23.91/src/cheese-webcam.c +--- cheese-2.23.91/src/cheese-webcam.c.foo 2008-09-03 20:27:25.000000000 +0200 ++++ cheese-2.23.91/src/cheese-webcam.c 2008-09-03 20:30:32.000000000 +0200 +@@ -90,7 +90,6 @@ typedef struct + int y_resolution; + int selected_device; + CheeseVideoFormat *current_format; +- GHashTable *supported_resolutions; + + CheeseFlash *flash; + } CheeseWebcamPrivate; +@@ -359,6 +358,8 @@ cheese_webcam_get_video_devices_from_hal + priv->webcam_devices[priv->num_webcam_devices].num_video_formats = 0; + priv->webcam_devices[priv->num_webcam_devices].video_formats = + g_array_new (FALSE, FALSE, sizeof (CheeseVideoFormat)); ++ priv->webcam_devices[priv->num_webcam_devices].supported_resolutions = ++ g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + priv->num_webcam_devices++; + + libhal_free_string (device); +@@ -533,8 +534,6 @@ static void + cheese_webcam_get_webcam_device_data (CheeseWebcam *webcam, + CheeseWebcamDevice *webcam_device) + { +- CheeseWebcamPrivate *priv = CHEESE_WEBCAM_GET_PRIVATE (webcam); +- + char *pipeline_desc; + GstElement *pipeline; + GError *err; +@@ -597,7 +596,7 @@ cheese_webcam_get_webcam_device_data (Ch + CheeseVideoFormat video_format; + + video_format = g_array_index (webcam_device->video_formats, CheeseVideoFormat, i); +- g_hash_table_insert (priv->supported_resolutions, ++ g_hash_table_insert (webcam_device->supported_resolutions, + g_strdup_printf ("%ix%i", video_format.width, + video_format.height), + &g_array_index (webcam_device->video_formats, +@@ -715,7 +714,7 @@ cheese_webcam_create_webcam_source_bin ( + /* Use the previously set resolution from gconf if it is set and the + * camera supports it. */ + if (priv->x_resolution != 0 && priv->y_resolution != 0) +- format = g_hash_table_lookup (priv->supported_resolutions, resolution); ++ format = g_hash_table_lookup (selected_webcam->supported_resolutions, resolution); + + if (!format) + { +@@ -1260,13 +1259,15 @@ cheese_webcam_finalize (GObject *object) + g_free (g_array_index (priv->webcam_devices[i].video_formats, CheeseVideoFormat, j).framerates); + g_free (g_array_index (priv->webcam_devices[i].video_formats, CheeseVideoFormat, j).mimetype); + } ++ g_free (priv->webcam_devices[i].video_device); + g_free (priv->webcam_devices[i].hal_udi); ++ g_free (priv->webcam_devices[i].gstreamer_src); ++ g_free (priv->webcam_devices[i].product_name); + g_array_free (priv->webcam_devices[i].video_formats, TRUE); ++ g_hash_table_destroy (priv->webcam_devices[i].supported_resolutions); + } + g_free (priv->webcam_devices); + +- g_hash_table_destroy (priv->supported_resolutions); +- + G_OBJECT_CLASS (cheese_webcam_parent_class)->finalize (object); + } + +@@ -1403,10 +1404,6 @@ cheese_webcam_init (CheeseWebcam *webcam + priv->webcam_devices = NULL; + priv->device_name = NULL; + +- priv->supported_resolutions = g_hash_table_new_full (g_str_hash, +- g_str_equal, +- g_free, NULL); +- + priv->flash = cheese_flash_new (); + } + +diff -up cheese-2.23.91/src/cheese-webcam.h.foo cheese-2.23.91/src/cheese-webcam.h +--- cheese-2.23.91/src/cheese-webcam.h.foo 2008-09-01 20:47:10.000000000 +0200 ++++ cheese-2.23.91/src/cheese-webcam.h 2008-09-03 20:27:59.000000000 +0200 +@@ -59,6 +59,8 @@ typedef struct + char *product_name; + int num_video_formats; + GArray *video_formats; ++ /* Hash table for resolution based lookup of video_formats */ ++ GHashTable *supported_resolutions; + } CheeseWebcamDevice; + + typedef enum diff --git a/cheese.spec b/cheese.spec index c9d8bd0..41de254 100644 --- a/cheese.spec +++ b/cheese.spec @@ -1,12 +1,22 @@ Name: cheese Version: 2.23.91 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A webcam application for snapshots and movies Group: Amusements/Graphics License: GPLv2+ URL: http://live.gnome.org/Cheese Source0: http://download.gnome.org/sources/cheese/2.23/%{name}-%{version}.tar.bz2 +# Following 3 patches reported upstream here: +# http://bugzilla.gnome.org/show_bug.cgi?id=546868 +Patch0: cheese-2.23.91-dont-use-non-capture-devices.patch +Patch1: cheese-2.23.91-supported-resolutions-per-device.patch +Patch2: cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch +# Following 3 patches reported upstream here: +# http://bugzilla.gnome.org/show_bug.cgi?id=547144 +Patch3: cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch +Patch4: cheese-2.23.90-only-list-resolutions-once.patch +Patch5: cheese-2.23.90-sort-resolutions.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: gtk2-devel >= 2.10.0 @@ -39,8 +49,16 @@ Cheese is a Photobooth-inspired GNOME application for taking pictures and videos from a webcam. It also includes fancy graphical effects based on the gstreamer-backend. + %prep %setup -q +%patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 + %build %configure @@ -108,6 +126,9 @@ fi %{_datadir}/dbus-1/services/org.gnome.Cheese.service %changelog +* 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