rpms/cheese/devel cheese-2.23.90-only-list-resolutions-once.patch, NONE, 1.1 cheese-2.23.90-sort-resolutions.patch, NONE, 1.1 cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch, NONE, 1.1 cheese-2.23.91-dont-use-non-capture-devices.patch, NONE, 1.1 cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch, NONE, 1.1 cheese-2.23.91-supported-resolutions-per-device.patch, NONE, 1.1 cheese.spec, 1.30, 1.31

Hans de Goede jwrdegoede at fedoraproject.org
Wed Sep 3 20:50:35 UTC 2008


Author: jwrdegoede

Update of /cvs/extras/rpms/cheese/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv8179

Modified Files:
	cheese.spec 
Added Files:
	cheese-2.23.90-only-list-resolutions-once.patch 
	cheese-2.23.90-sort-resolutions.patch 
	cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch 
	cheese-2.23.91-dont-use-non-capture-devices.patch 
	cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch 
	cheese-2.23.91-supported-resolutions-per-device.patch 
Log Message:
* Wed Sep  3 2008 Hans de Goede <hdegoede at redhat.com> 2.23.91-2
- Fix use with multiple v4l devices (rh 460956, gnome 546868, gnome 547144)


cheese-2.23.90-only-list-resolutions-once.patch:

--- NEW FILE cheese-2.23.90-only-list-resolutions-once.patch ---
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++;

cheese-2.23.90-sort-resolutions.patch:

--- NEW FILE cheese-2.23.90-sort-resolutions.patch ---
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

cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch:

--- NEW FILE cheese-2.23.91-cheese_webcam_get_supported_video_formats-shuffle.patch ---
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

cheese-2.23.91-dont-use-non-capture-devices.patch:

--- NEW FILE cheese-2.23.91-dont-use-non-capture-devices.patch ---
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 <gdk-pixbuf/gdk-pixbuf.h>
 #include <X11/Xlib.h>
 #include <libhal.h>
+/* for ioctl query */
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/videodev.h>
 
 #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++)
   {

cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch:

--- NEW FILE cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch ---
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);

cheese-2.23.91-supported-resolutions-per-device.patch:

--- NEW FILE cheese-2.23.91-supported-resolutions-per-device.patch ---
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


Index: cheese.spec
===================================================================
RCS file: /cvs/extras/rpms/cheese/devel/cheese.spec,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- cheese.spec	2 Sep 2008 23:44:19 -0000	1.30
+++ cheese.spec	3 Sep 2008 20:50:35 -0000	1.31
@@ -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 @@
 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 @@
 %{_datadir}/dbus-1/services/org.gnome.Cheese.service
 
 %changelog
+* Wed Sep  3 2008 Hans de Goede <hdegoede at redhat.com> 2.23.91-2
+- Fix use with multiple v4l devices (rh 460956, gnome 546868, gnome 547144)
+
 * Tue Sep  2 2008 Matthias Clasen  <mclasen at redhat.com> 2.23.91-1
 - Update to 2.23.91
 




More information about the fedora-extras-commits mailing list