- Fix use with multiple v4l devices (rh 460956, gnome 546868, gnome 547144)
This commit is contained in:
parent
15539e8e34
commit
fd29e9f92e
49
cheese-2.23.90-only-list-resolutions-once.patch
Normal file
49
cheese-2.23.90-only-list-resolutions-once.patch
Normal file
@ -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++;
|
42
cheese-2.23.90-sort-resolutions.patch
Normal file
42
cheese-2.23.90-sort-resolutions.patch
Normal file
@ -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
|
@ -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
|
242
cheese-2.23.91-dont-use-non-capture-devices.patch
Normal file
242
cheese-2.23.91-dont-use-non-capture-devices.patch
Normal file
@ -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 <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++)
|
||||||
|
{
|
45
cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch
Normal file
45
cheese-2.23.91-let-gstreamer-choose-yuv-or-rgb.patch
Normal file
@ -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);
|
88
cheese-2.23.91-supported-resolutions-per-device.patch
Normal file
88
cheese-2.23.91-supported-resolutions-per-device.patch
Normal file
@ -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
|
23
cheese.spec
23
cheese.spec
@ -1,12 +1,22 @@
|
|||||||
Name: cheese
|
Name: cheese
|
||||||
Version: 2.23.91
|
Version: 2.23.91
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
Summary: A webcam application for snapshots and movies
|
Summary: A webcam application for snapshots and movies
|
||||||
|
|
||||||
Group: Amusements/Graphics
|
Group: Amusements/Graphics
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: http://live.gnome.org/Cheese
|
URL: http://live.gnome.org/Cheese
|
||||||
Source0: http://download.gnome.org/sources/cheese/2.23/%{name}-%{version}.tar.bz2
|
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)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
|
|
||||||
BuildRequires: gtk2-devel >= 2.10.0
|
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
|
videos from a webcam. It also includes fancy graphical effects based on the
|
||||||
gstreamer-backend.
|
gstreamer-backend.
|
||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -q
|
%setup -q
|
||||||
|
%patch0 -p1
|
||||||
|
%patch1 -p1
|
||||||
|
%patch2 -p1
|
||||||
|
%patch3 -p1
|
||||||
|
%patch4 -p1
|
||||||
|
%patch5 -p1
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%configure
|
%configure
|
||||||
@ -108,6 +126,9 @@ fi
|
|||||||
%{_datadir}/dbus-1/services/org.gnome.Cheese.service
|
%{_datadir}/dbus-1/services/org.gnome.Cheese.service
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Sep 3 2008 Hans de Goede <hdegoede@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@redhat.com> 2.23.91-1
|
* Tue Sep 2 2008 Matthias Clasen <mclasen@redhat.com> 2.23.91-1
|
||||||
- Update to 2.23.91
|
- Update to 2.23.91
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user