[cheese] Limit caps to the maximum framerate



commit 2f02b8c454ec565bda107e34493e6e0ecf3fa62b
Author: Hans de Goede <hdegoede redhat com>
Date:   Mon Jun 10 14:47:40 2013 +0200

    Limit caps to the maximum framerate
    
    Limit the caps returned by cheese_camera_device_get_caps_for_format() to
    the maximum framerate supported at the requested resolution. This is
    necessary because GStreamer first selects a format and then a framerate,
    resulting in it picking for 1280x720 as an example, YUYV @ 15 FPS,
    instead of MJPEG @ 30 FPS (which will be converted to i420 by the
    videoconvert element in camerabin2), or at 1600x1200 YUYV @ 5 fps
    instead of MJPEG @ 10 fps.
    
    Signed-off-by: Hans de Goede <hdegoede redhat com>

 libcheese/cheese-camera-device.c |   50 ++++++++++++++++++++++++++++----------
 1 files changed, 37 insertions(+), 13 deletions(-)
---
diff --git a/libcheese/cheese-camera-device.c b/libcheese/cheese-camera-device.c
index 9997f55..c6faebd 100644
--- a/libcheese/cheese-camera-device.c
+++ b/libcheese/cheese-camera-device.c
@@ -955,6 +955,26 @@ cheese_camera_device_get_best_format (CheeseCameraDevice *device)
   return format;
 }
 
+static GstCaps *
+cheese_camera_device_format_to_caps (const char *media_type,
+                                     CheeseVideoFormatFull *format)
+{
+  if (format->fr_numerator != 0 && format->fr_denominator != 0)
+  {
+    return gst_caps_new_simple (media_type,
+                                "framerate", GST_TYPE_FRACTION,
+                                format->fr_numerator, format->fr_denominator,
+                                "width", G_TYPE_INT, format->width,
+                                "height", G_TYPE_INT, format->height, NULL);
+  }
+  else
+  {
+    return gst_caps_new_simple (media_type,
+                                "width", G_TYPE_INT, format->width,
+                                "height", G_TYPE_INT, format->height, NULL);
+  }
+}
+
 /**
  * cheese_camera_device_get_caps_for_format:
  * @device: a #CheeseCameraDevice
@@ -968,31 +988,35 @@ GstCaps *
 cheese_camera_device_get_caps_for_format (CheeseCameraDevice *device,
                                           CheeseVideoFormat  *format)
 {
+  CheeseVideoFormatFull *full_format;
   GstCaps *desired_caps;
   GstCaps *subset_caps;
   guint    i, length;
 
   g_return_val_if_fail (CHEESE_IS_CAMERA_DEVICE (device), NULL);
 
-  GST_INFO ("Getting caps for %dx%d", format->width, format->height);
+  full_format = cheese_camera_device_find_full_format (device, format);
+
+  if (!full_format)
+  {
+    GST_INFO ("Getting caps for %dx%d: no such format!",
+              format->width, format->height);
+    return gst_caps_new_empty ();
+  }
 
-  desired_caps = gst_caps_new_simple (supported_formats[0],
-                                      "width", G_TYPE_INT,
-                                      format->width,
-                                      "height", G_TYPE_INT,
-                                      format->height,
-                                      NULL);
+  GST_INFO ("Getting caps for %dx%d @ %d/%d fps",
+            full_format->width, full_format->height,
+            full_format->fr_numerator, full_format->fr_denominator);
 
+  desired_caps = cheese_camera_device_format_to_caps(supported_formats[0],
+                                                     full_format);
   length = g_strv_length (supported_formats);
+
   for (i = 1; i < length; i++)
   {
     gst_caps_append (desired_caps,
-                     gst_caps_new_simple (supported_formats[i],
-                                          "width", G_TYPE_INT,
-                                          format->width,
-                                          "height", G_TYPE_INT,
-                                          format->height,
-                                          NULL));
+                     cheese_camera_device_format_to_caps (supported_formats[i],
+                                                          full_format));
   }
 
   subset_caps = gst_caps_intersect (desired_caps, device->priv->caps);


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