[cheese/capsrework: 3/9] Move caps retrieving stuff into CheeseCameraDevice



commit 277e0b97ef5a71f3dfae09c74b33cbb9382ef57c
Author: Filippo Argiolas <filippo argiolas gmail com>
Date:   Sun Dec 13 18:11:01 2009 +0100

    Move caps retrieving stuff into CheeseCameraDevice
    
    Caps are device specific so it makes sense to retrieve them directly in
    CheeseCameraDevice. Make CheeseCameraDevice string properties CONSTRUCT_ONLY.

 libcheese/cheese-camera-device-monitor.c |   13 ++--
 libcheese/cheese-camera-device.c         |  101 +++++++++++++++++-----
 libcheese/cheese-camera-device.h         |    2 +
 libcheese/cheese-camera.c                |  136 ++++++-----------------------
 libcheese/cheese-camera.h                |    2 +-
 5 files changed, 114 insertions(+), 140 deletions(-)
---
diff --git a/libcheese/cheese-camera-device-monitor.c b/libcheese/cheese-camera-device-monitor.c
index 0bb869a..6743407 100644
--- a/libcheese/cheese-camera-device-monitor.c
+++ b/libcheese/cheese-camera-device-monitor.c
@@ -152,13 +152,12 @@ cheese_camera_device_monitor_added (CheeseCameraDeviceMonitor *monitor,
 
   g_print ("\n");
 
-  device = cheese_camera_device_new ();
-  g_object_set (G_OBJECT (device),
-                "device-id", g_udev_device_get_property (udevice, "DEVPATH"),
-                "device-file", device_file,
-                "name", product_name,
-                "src", gstreamer_src,
-                NULL);
+  device = g_object_new (CHEESE_TYPE_CAMERA_DEVICE,
+                         "device-id", g_udev_device_get_property (udevice, "DEVPATH"),
+                         "device-file", device_file,
+                         "name", product_name,
+                         "src", gstreamer_src,
+                         NULL);
 
   g_signal_emit (monitor, monitor_signals[ADDED], 0, device);
 }
diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
index ac9a91f..a0afa8f 100644
--- a/libcheese/cheese-camera-device.c
+++ b/libcheese/cheese-camera-device.c
@@ -46,8 +46,7 @@ enum
   PROP_NAME,
   PROP_FILE,
   PROP_ID,
-  PROP_SRC,
-  PROP_CAPS
+  PROP_SRC
 };
 
 typedef struct
@@ -233,6 +232,75 @@ cheese_webcam_device_update_format_table (CheeseCameraDevice *device)
 }
 
 static void
+cheese_camera_device_get_caps (CheeseCameraDevice *device)
+{
+  CheeseCameraDevicePrivate *priv =
+    CHEESE_CAMERA_DEVICE_GET_PRIVATE (device);
+
+  gchar               *pipeline_desc;
+  GstElement          *pipeline;
+  GstStateChangeReturn ret;
+  GstMessage          *msg;
+  GstBus              *bus;
+  GError              *err = NULL;
+
+  pipeline_desc = g_strdup_printf ("%s name=source device=%s ! fakesink",
+                                   priv->src, priv->device);
+  pipeline = gst_parse_launch (pipeline_desc, &err);
+  if ((pipeline != NULL) && (err == NULL))
+  {
+    /* Start the pipeline and wait for max. 10 seconds for it to start up */
+    gst_element_set_state (pipeline, GST_STATE_READY);
+    ret = gst_element_get_state (pipeline, NULL, NULL, 10 * GST_SECOND);
+
+    /* Check if any error messages were posted on the bus */
+    bus = gst_element_get_bus (pipeline);
+    msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
+    gst_object_unref (bus);
+
+    if ((msg == NULL) && (ret == GST_STATE_CHANGE_SUCCESS))
+    {
+      GstElement *src;
+      GstPad     *pad;
+      char       *name;
+      GstCaps    *caps;
+
+      src = gst_bin_get_by_name (GST_BIN (pipeline), "source");
+
+      g_object_get (G_OBJECT (src), "device-name", &name, NULL);
+      if (name == NULL)
+        name = "Unknown";
+
+      g_print ("Device: %s (%s)\n", name, priv->device);
+      pad  = gst_element_get_pad (src, "src");
+      caps = gst_pad_get_caps (pad);
+      priv->caps = cheese_webcam_device_filter_caps (device, caps, supported_formats);
+      cheese_webcam_device_update_format_table (device);
+
+      gst_object_unref (pad);
+      gst_caps_unref (caps);
+    }
+    gst_element_set_state (pipeline, GST_STATE_NULL);
+    gst_object_unref (pipeline);
+  }
+
+  if (err)
+    g_error_free (err);
+
+  g_free (pipeline_desc);
+}
+
+static void
+cheese_camera_device_constructed (GObject *object)
+{
+  CheeseCameraDevice *device = CHEESE_CAMERA_DEVICE (object);
+
+  cheese_camera_device_get_caps (device);
+
+  G_OBJECT_CLASS (cheese_camera_device_parent_class)->finalize (object);
+}
+
+static void
 cheese_camera_device_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
   CheeseCameraDevice *device = CHEESE_CAMERA_DEVICE (object);
@@ -252,9 +320,6 @@ cheese_camera_device_get_property (GObject *object, guint prop_id, GValue *value
   case PROP_SRC:
     g_value_set_string (value, priv->src);
     break;
-  case PROP_CAPS:
-    gst_value_set_caps (value, priv->caps);
-    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     break;
@@ -267,7 +332,6 @@ cheese_camera_device_set_property (GObject *object, guint prop_id, const GValue
   CheeseCameraDevice *device = CHEESE_CAMERA_DEVICE (object);
   CheeseCameraDevicePrivate *priv =
     CHEESE_CAMERA_DEVICE_GET_PRIVATE (device);
-  const GstCaps *new_caps;
 
   switch (prop_id) {
   case PROP_NAME:
@@ -286,14 +350,6 @@ cheese_camera_device_set_property (GObject *object, guint prop_id, const GValue
     g_free (priv->src);
     priv->src = g_value_dup_string (value);
     break;
-  case PROP_CAPS:
-    new_caps = gst_value_get_caps (value);
-    if (new_caps != NULL) {
-      gst_caps_unref (priv->caps);
-      priv->caps = cheese_webcam_device_filter_caps (device, new_caps, supported_formats);
-      cheese_webcam_device_update_format_table (device);
-    }
-    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     break;
@@ -314,6 +370,8 @@ cheese_camera_device_finalize (GObject *object)
 
   gst_caps_unref (priv->caps);
   free_format_list (device);
+
+  G_OBJECT_CLASS (cheese_camera_device_parent_class)->finalize (object);
 }
 
 static void
@@ -324,32 +382,27 @@ cheese_camera_device_class_init (CheeseCameraDeviceClass *klass)
   object_class->finalize     = cheese_camera_device_finalize;
   object_class->get_property = cheese_camera_device_get_property;
   object_class->set_property = cheese_camera_device_set_property;
+  object_class->constructed  = cheese_camera_device_constructed;
 
   g_object_class_install_property (object_class, PROP_NAME,
                                    g_param_spec_string ("name",
                                                         NULL, NULL, NULL,
-                                                        G_PARAM_READWRITE));
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
   g_object_class_install_property (object_class, PROP_FILE,
                                    g_param_spec_string ("device-file",
                                                         NULL, NULL, NULL,
-                                                        G_PARAM_READWRITE));
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
   g_object_class_install_property (object_class, PROP_ID,
                                    g_param_spec_string ("device-id",
                                                         NULL, NULL, NULL,
-                                                        G_PARAM_READWRITE));
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
   g_object_class_install_property (object_class, PROP_SRC,
                                    g_param_spec_string ("src",
                                                         NULL, NULL, NULL,
-                                                        G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_CAPS,
-                                   g_param_spec_boxed ("caps",
-                                                       NULL, NULL,
-                                                       GST_TYPE_CAPS,
-                                                       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
   g_type_class_add_private (klass, sizeof (CheeseCameraDevicePrivate));
 }
 
diff --git a/libcheese/cheese-camera-device.h b/libcheese/cheese-camera-device.h
index fedf547..444db3a 100644
--- a/libcheese/cheese-camera-device.h
+++ b/libcheese/cheese-camera-device.h
@@ -56,6 +56,8 @@ typedef struct
 
 GType cheese_video_format_get_type (void) G_GNUC_CONST;
 
+GType cheese_camera_device_get_type (void) G_GNUC_CONST;
+
 CheeseCameraDevice        *cheese_camera_device_new (void);
 GstCaps                   *cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
                                                                      CheeseVideoFormat *format);
diff --git a/libcheese/cheese-camera.c b/libcheese/cheese-camera.c
index aab40b9..6cbd846 100644
--- a/libcheese/cheese-camera.c
+++ b/libcheese/cheese-camera.c
@@ -42,8 +42,6 @@ G_DEFINE_TYPE (CheeseCamera, cheese_camera, G_TYPE_OBJECT)
 
 #define CHEESE_CAMERA_ERROR cheese_camera_error_quark ()
 
-#define MIN_DEFAULT_RATE 15.0
-
 enum CheeseCameraError
 {
   CHEESE_CAMERA_ERROR_UNKNOWN,
@@ -87,7 +85,7 @@ typedef struct
   int x_resolution;
   int y_resolution;
   int selected_device;
-  CheeseVideoFormat *current_format;
+  CheeseVideoFormat *default_format;
 
   guint eos_timeout_id;
 } CheeseCameraPrivate;
@@ -320,67 +318,6 @@ cheese_camera_get_video_devices_from_udev (CheeseCamera *camera)
 }
 
 static void
-cheese_camera_get_camera_device_data (CheeseCamera       *camera,
-                                      CheeseCameraDevice *device)
-{
-  char                *pipeline_desc;
-  GstElement          *pipeline;
-  GstStateChangeReturn ret;
-  GstMessage          *msg;
-  GstBus              *bus;
-  gchar               *src;
-  gchar               *devpath;
-  GError              *err = NULL;
-
-  g_object_get (G_OBJECT (device), "device-file", &devpath, "src", &src, NULL);
-
-  pipeline_desc = g_strdup_printf ("%s name=source device=%s ! fakesink",
-                                   src, devpath);
-  pipeline = gst_parse_launch (pipeline_desc, &err);
-  if ((pipeline != NULL) && (err == NULL))
-  {
-    /* Start the pipeline and wait for max. 10 seconds for it to start up */
-    gst_element_set_state (pipeline, GST_STATE_READY);
-    ret = gst_element_get_state (pipeline, NULL, NULL, 10 * GST_SECOND);
-
-    /* Check if any error messages were posted on the bus */
-    bus = gst_element_get_bus (pipeline);
-    msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
-    gst_object_unref (bus);
-
-    if ((msg == NULL) && (ret == GST_STATE_CHANGE_SUCCESS))
-    {
-      GstElement *src;
-      GstPad     *pad;
-      char       *name;
-      GstCaps    *caps;
-
-      src = gst_bin_get_by_name (GST_BIN (pipeline), "source");
-
-      g_object_get (G_OBJECT (src), "device-name", &name, NULL);
-      if (name == NULL)
-        name = "Unknown";
-
-      g_print ("Device: %s (%s)\n", name, devpath);
-      pad  = gst_element_get_pad (src, "src");
-      caps = gst_pad_get_caps (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);
-    gst_object_unref (pipeline);
-  }
-  if (err)
-    g_error_free (err);
-
-  g_free (pipeline_desc);
-  g_free (devpath);
-  g_free (src);
-}
-
-static void
 cheese_camera_create_fake_format (CheeseCamera *camera, CheeseCameraDevice *device)
 {
 //  CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
@@ -395,7 +332,7 @@ cheese_camera_create_fake_format (CheeseCamera *camera, CheeseCameraDevice *devi
                                        30, 1,
                                        NULL);
 
-  g_object_set (G_OBJECT (device), "caps", caps, NULL);
+//  g_object_set (G_OBJECT (device), "caps", caps, NULL);
 }
 
 static void
@@ -407,13 +344,6 @@ cheese_camera_detect_camera_devices (CheeseCamera *camera)
 
   cheese_camera_get_video_devices_from_udev (camera);
 
-  g_print ("Probing supported video formats...\n");
-  for (i = 0; i < priv->num_camera_devices; i++)
-  {
-    cheese_camera_get_camera_device_data (camera, g_ptr_array_index (priv->camera_devices, i));
-    g_print ("\n");
-  }
-
   if (priv->num_camera_devices == 0)
     cheese_camera_create_fake_format (camera, g_ptr_array_index (priv->camera_devices, 0));
 }
@@ -455,53 +385,28 @@ cheese_camera_create_camera_source_bin (CheeseCamera *camera)
       }
     }
 
-    /* Use the previously set resolution from gconf if it is set and the
-     * camera supports it. */
-    CheeseVideoFormat *format = g_new0 (CheeseVideoFormat, 1);
-    format->width = priv->x_resolution;
-    format->height = priv->y_resolution;
-    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);
-      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 (
       "%s name=video_source device=%s ! capsfilter name=capsfilter ! identity",
       cheese_camera_device_get_src (selected_camera),
       cheese_camera_device_get_device_file (selected_camera));
 
-    g_print ("%s\n", camera_input);
-
     priv->camera_source_bin = gst_parse_bin_from_description (camera_input,
                                                               TRUE, &err);
-
     g_free (camera_input);
 
     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");
-    g_object_set (G_OBJECT (priv->capsfilter), "caps", caps, NULL);
-    gst_caps_unref (caps);
-
   }
 
   return TRUE;
 
+
+/* FIXME: get rid of videotest stuff and set problem page when
+ * something fails, see cheese-video-widget */
 fallback:
   if (err != NULL)
   {
@@ -1122,7 +1027,7 @@ cheese_camera_set_property (GObject *object, guint prop_id, const GValue *value,
       priv->device_name = g_value_dup_string (value);
       break;
     case PROP_FORMAT:
-      cheese_camera_set_video_format (self, g_value_get_boxed (value));
+      cheese_camera_set_video_format (self, g_value_dup_boxed (value));
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -1217,6 +1122,7 @@ cheese_camera_init (CheeseCamera *camera)
   priv->camera_devices          = NULL;
   priv->device_name             = NULL;
   priv->photo_handler_signal_id = 0;
+  priv->current_format          = NULL;
 }
 
 CheeseCamera *
@@ -1346,11 +1252,11 @@ cheese_camera_is_playing (CheeseCamera *camera)
   return priv->pipeline_is_playing;
 }
 
-void
+gboolean
 cheese_camera_set_video_format (CheeseCamera *camera, CheeseVideoFormat *format)
 {
-#if 0
   CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
+  CheeseCameraDevice  *device = g_ptr_array_index (priv->camera_devices, priv->selected_device);
   GstCaps *caps;
 
   if ((format->width == priv->current_format->width) &&
@@ -1358,7 +1264,21 @@ cheese_camera_set_video_format (CheeseCamera *camera, CheeseVideoFormat *format)
     goto out;
   }
 
-  caps = cheese_camera_device_get_caps_for_format (selected_camera, format);
+  caps = cheese_camera_device_get_caps_for_format (device, format);
+
+  if (gst_caps_is_empty (caps))
+  {
+    g_warning ("CAPS_ARE_EMPTY");
+    gst_caps_unref (caps);
+    format = g_slice_new (CheeseVideoFormat);
+    format = cheese_camera_device_get_best_format (device);
+    caps = cheese_camera_device_get_caps_for_format (device, format);
+    if (gst_caps_is_empty (caps)) {
+      g_warning ("CAPS_ARE_STILL_EMPTY");
+      gst_caps_unref (caps);
+      return FALSE;
+    }
+  }
 
   if (cheese_camera_is_playing (camera)) {
     /* shouldn't this be done async? */
@@ -1368,11 +1288,11 @@ cheese_camera_set_video_format (CheeseCamera *camera, CheeseVideoFormat *format)
   } else {
     g_object_set (priv->capsfilter, "caps", caps, NULL);
   }
+
 out:
-  if (G_LIKELY (priv->current_format) != NULL) {
-    g_free (priv->current_format);
-  }
-#endif
+  g_boxed_free (CHEESE_TYPE_VIDEO_FORMAT, priv->current_format);
+  priv->current_format = format;
+  return TRUE;
 }
 
 const CheeseVideoFormat *
diff --git a/libcheese/cheese-camera.h b/libcheese/cheese-camera.h
index 3ed45d0..60cbc87 100644
--- a/libcheese/cheese-camera.h
+++ b/libcheese/cheese-camera.h
@@ -91,7 +91,7 @@ void               cheese_camera_set_device_by_dev_file (CheeseCamera *camera, c
 void               cheese_camera_set_device_by_dev_udi (CheeseCamera *camera, char *udi);
 gboolean           cheese_camera_switch_camera_device (CheeseCamera *camera);
 GList     *        cheese_camera_get_video_formats (CheeseCamera *camera);
-void               cheese_camera_set_video_format (CheeseCamera      *camera,
+gboolean           cheese_camera_set_video_format (CheeseCamera      *camera,
                                                    CheeseVideoFormat *format);
 void cheese_camera_get_balance_property_range (CheeseCamera *camera,
                                                gchar *property,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]