[cheese] Some other step towards better cap handling
- From: Filippo Argiolas <fargiolas src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [cheese] Some other step towards better cap handling
- Date: Wed, 23 Dec 2009 08:08:12 +0000 (UTC)
commit 7a54c29574f5f3a756d8e2e5d20818204ab3be68
Author: Filippo Argiolas <filippo argiolas gmail com>
Date: Sun Dec 13 12:26:27 2009 +0100
Some other step towards better cap handling
Boxify CheeseVideoFormat. Add some convenience method for getting caps
from formats.
libcheese/cheese-camera-device.c | 44 ++++++++++++++++++-
libcheese/cheese-camera-device.h | 6 ++-
libcheese/cheese-camera.c | 87 ++++++++++++++++++++++++++++----------
libcheese/cheese-camera.h | 2 +-
4 files changed, 111 insertions(+), 28 deletions(-)
---
diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
index 4fb5f18..ac9a91f 100644
--- a/libcheese/cheese-camera-device.c
+++ b/libcheese/cheese-camera-device.c
@@ -19,6 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+
#ifdef HAVE_CONFIG_H
#include <cheese-config.h>
#endif
@@ -61,6 +62,37 @@ typedef struct
GList *formats;
} CheeseCameraDevicePrivate;
+
+/* CheeseVideoFormat */
+
+static CheeseVideoFormat*
+cheese_video_format_copy (const CheeseVideoFormat *format)
+{
+ return g_slice_dup (CheeseVideoFormat, format);
+}
+
+static void
+cheese_video_format_free (CheeseVideoFormat *format)
+{
+ if (G_LIKELY (format != NULL))
+ g_slice_free (CheeseVideoFormat, format);
+}
+
+GType
+cheese_video_format_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (G_UNLIKELY (our_type == 0))
+ our_type =
+ g_boxed_type_register_static ("CheeseVideoFormat",
+ (GBoxedCopyFunc) cheese_video_format_copy,
+ (GBoxedFreeFunc) cheese_video_format_free);
+ return our_type;
+}
+
+/* the rest */
+
static gint
compare_formats (gconstpointer a, gconstpointer b)
{
@@ -104,7 +136,7 @@ cheese_camera_device_add_format (CheeseCameraDevice *device, CheeseVideoFormat *
}
static void
-free_formats_list (CheeseCameraDevice *device)
+free_format_list (CheeseCameraDevice *device)
{
CheeseCameraDevicePrivate *priv =
CHEESE_CAMERA_DEVICE_GET_PRIVATE (device);
@@ -130,7 +162,7 @@ cheese_webcam_device_update_format_table (CheeseCameraDevice *device)
* merely perceivable refresh reate gain. I'd say let's throw away
* everything over 30/1 */
- free_formats_list (device);
+ free_format_list (device);
num_structures = gst_caps_get_size (priv->caps);
for (i = 0; i < num_structures; i++)
@@ -280,7 +312,8 @@ cheese_camera_device_finalize (GObject *object)
g_free (priv->src);
g_free (priv->name);
- // free_formats_list (priv->formats);
+ gst_caps_unref (priv->caps);
+ free_format_list (device);
}
static void
@@ -379,6 +412,11 @@ const gchar *cheese_camera_device_get_device_file (CheeseCameraDevice *device)
return priv->device;
}
+CheeseVideoFormat *cheese_camera_device_get_best_format (CheeseCameraDevice *device)
+{
+ return (CheeseVideoFormat *) cheese_camera_device_get_format_list (device)->data;
+}
+
GstCaps *cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
CheeseVideoFormat *format)
{
diff --git a/libcheese/cheese-camera-device.h b/libcheese/cheese-camera-device.h
index ec9fcc4..fedf547 100644
--- a/libcheese/cheese-camera-device.h
+++ b/libcheese/cheese-camera-device.h
@@ -46,17 +46,21 @@ typedef struct
GObjectClass parent_class;
} CheeseCameraDeviceClass;
+#define CHEESE_TYPE_VIDEO_FORMAT (cheese_video_format_get_type ())
+
typedef struct
{
int width;
int height;
} CheeseVideoFormat;
+GType cheese_video_format_get_type (void) G_GNUC_CONST;
+
CheeseCameraDevice *cheese_camera_device_new (void);
GstCaps *cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
CheeseVideoFormat *format);
+CheeseVideoFormat *cheese_camera_device_get_best_format (CheeseCameraDevice *device);
-GList *cheese_camera_device_get_readable_format_list (CheeseCameraDevice *device);
const gchar *cheese_camera_device_get_name (CheeseCameraDevice *device);
const gchar *cheese_camera_device_get_src (CheeseCameraDevice *device);
const gchar *cheese_camera_device_get_id (CheeseCameraDevice *device);
diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
index 9a567eb..aab40b9 100644
--- a/libcheese/cheese-camera.c
+++ b/libcheese/cheese-camera.c
@@ -97,6 +97,7 @@ enum
PROP_0,
PROP_VIDEO_WINDOW,
PROP_DEVICE_NAME,
+ PROP_FORMAT,
PROP_X_RESOLUTION,
PROP_Y_RESOLUTION
};
@@ -363,8 +364,9 @@ cheese_camera_get_camera_device_data (CheeseCamera *camera,
g_print ("Device: %s (%s)\n", name, devpath);
pad = gst_element_get_pad (src, "src");
caps = gst_pad_get_caps (pad);
- gst_object_unref (pad);
g_object_set (G_OBJECT (device), "caps", caps, NULL);
+
+ gst_object_unref (pad);
gst_caps_unref (caps);
}
gst_element_set_state (pipeline, GST_STATE_NULL);
@@ -424,14 +426,14 @@ cheese_camera_create_camera_source_bin (CheeseCamera *camera)
GError *err = NULL;
char *camera_input;
- GstCaps *caps;
-
if (priv->num_camera_devices == 0)
{
priv->camera_source_bin = gst_parse_bin_from_description (
"videotestsrc name=video_source ! capsfilter name=capsfilter ! identity",
TRUE,
&err);
+ priv->video_source = gst_bin_get_by_name (GST_BIN (priv->camera_source_bin), "video_source");
+ priv->capsfilter = gst_bin_get_by_name (GST_BIN (priv->camera_source_bin), "capsfilter");
}
else
{
@@ -458,12 +460,20 @@ cheese_camera_create_camera_source_bin (CheeseCamera *camera)
CheeseVideoFormat *format = g_new0 (CheeseVideoFormat, 1);
format->width = priv->x_resolution;
format->height = priv->y_resolution;
- caps = cheese_camera_device_get_caps_for_format (selected_camera, format);
+ GstCaps *caps = cheese_camera_device_get_caps_for_format (selected_camera, format);
+ g_free (format);
if (gst_caps_is_empty (caps))
{
+ g_warning ("CAPS_ARE_EMPTY");
gst_caps_unref (caps);
- g_object_get (G_OBJECT (selected_camera), "caps", &caps, NULL);
+ format = cheese_camera_device_get_best_format (selected_camera);
+ caps = cheese_camera_device_get_caps_for_format (selected_camera, format);
+ if (gst_caps_is_empty (caps)) {
+ g_warning ("CAPS_ARE_STILL_EMPTY");
+ gst_caps_unref (caps);
+ goto fallback;
+ }
}
camera_input = g_strdup_printf (
@@ -475,19 +485,20 @@ cheese_camera_create_camera_source_bin (CheeseCamera *camera)
priv->camera_source_bin = gst_parse_bin_from_description (camera_input,
TRUE, &err);
+
g_free (camera_input);
- if (priv->camera_source_bin == NULL)
+ if (priv->camera_source_bin == NULL) {
+ gst_caps_unref (caps);
goto fallback;
- }
-
- priv->video_source = gst_bin_get_by_name (GST_BIN (priv->camera_source_bin), "video_source");
- priv->capsfilter = gst_bin_get_by_name (GST_BIN (priv->camera_source_bin), "capsfilter");
+ }
- GST_ERROR ("caps are %" GST_PTR_FORMAT, caps);
+ priv->video_source = gst_bin_get_by_name (GST_BIN (priv->camera_source_bin), "video_source");
+ priv->capsfilter = gst_bin_get_by_name (GST_BIN (priv->camera_source_bin), "capsfilter");
+ g_object_set (G_OBJECT (priv->capsfilter), "caps", caps, NULL);
+ gst_caps_unref (caps);
- g_object_set (G_OBJECT (priv->capsfilter), "caps", caps, NULL);
- gst_caps_unref (caps);
+ }
return TRUE;
@@ -1075,6 +1086,9 @@ cheese_camera_get_property (GObject *object, guint prop_id, GValue *value,
case PROP_DEVICE_NAME:
g_value_set_string (value, priv->device_name);
break;
+ case PROP_FORMAT:
+ g_value_set_boxed (value, priv->current_format);
+ break;
case PROP_X_RESOLUTION:
g_value_set_int (value, priv->x_resolution);
break;
@@ -1107,11 +1121,8 @@ cheese_camera_set_property (GObject *object, guint prop_id, const GValue *value,
g_free (priv->device_name);
priv->device_name = g_value_dup_string (value);
break;
- case PROP_X_RESOLUTION:
- priv->x_resolution = g_value_get_int (value);
- break;
- case PROP_Y_RESOLUTION:
- priv->y_resolution = g_value_get_int (value);
+ case PROP_FORMAT:
+ cheese_camera_set_video_format (self, g_value_get_boxed (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1163,6 +1174,14 @@ cheese_camera_class_init (CheeseCameraClass *klass)
"",
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class, PROP_FORMAT,
+ g_param_spec_boxed ("format",
+ NULL,
+ NULL,
+ CHEESE_TYPE_VIDEO_FORMAT,
+ G_PARAM_READWRITE));
+
+
g_object_class_install_property (object_class, PROP_X_RESOLUTION,
g_param_spec_int ("x-resolution",
NULL,
@@ -1320,21 +1339,43 @@ cheese_camera_get_video_formats (CheeseCamera *camera)
// return cheese_camera_device_get_readable_format_list (device);
}
+gboolean
+cheese_camera_is_playing (CheeseCamera *camera)
+{
+ CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
+ return priv->pipeline_is_playing;
+}
+
void
cheese_camera_set_video_format (CheeseCamera *camera, CheeseVideoFormat *format)
{
#if 0
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
+ GstCaps *caps;
- GstCaps *caps = cheese_camera_device_get_caps_for_format (priv->selected_camera, format);
+ if ((format->width == priv->current_format->width) &&
+ (format->height == priv->current_format->height)) {
+ goto out;
+ }
- cheese_camera_stop (camera);
- g_object_set (priv->capsfilter, "caps", caps, NULL);
- cheese_camera_play (camera);
+ caps = cheese_camera_device_get_caps_for_format (selected_camera, format);
+
+ if (cheese_camera_is_playing (camera)) {
+ /* shouldn't this be done async? */
+ cheese_camera_stop (camera);
+ g_object_set (priv->capsfilter, "caps", caps, NULL);
+ cheese_camera_play (camera);
+ } else {
+ g_object_set (priv->capsfilter, "caps", caps, NULL);
+ }
+out:
+ if (G_LIKELY (priv->current_format) != NULL) {
+ g_free (priv->current_format);
+ }
#endif
}
-CheeseVideoFormat *
+const CheeseVideoFormat *
cheese_camera_get_current_video_format (CheeseCamera *camera)
{
CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
diff --git a/libcheese/cheese-camera.h b/libcheese/cheese-camera.h
index f7f15cf..3ed45d0 100644
--- a/libcheese/cheese-camera.h
+++ b/libcheese/cheese-camera.h
@@ -74,7 +74,7 @@ CheeseCamera *cheese_camera_new (GtkWidget *video_window,
int x_resolution,
int y_resolution);
-CheeseVideoFormat *cheese_camera_get_current_video_format (CheeseCamera *camera);
+const CheeseVideoFormat *cheese_camera_get_current_video_format (CheeseCamera *camera);
void cheese_camera_setup (CheeseCamera *camera, char *udi, GError **error);
void cheese_camera_play (CheeseCamera *camera);
void cheese_camera_stop (CheeseCamera *camera);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]