diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-06-10 14:47:40 +0200 |
---|---|---|
committer | David King <amigadave@amigadave.com> | 2013-09-02 22:14:49 +0100 |
commit | 2f02b8c454ec565bda107e34493e6e0ecf3fa62b (patch) | |
tree | f6a96639e48230a7582cf6eef5f18d7fd3c220d9 | |
parent | 4cb89c66167a1945e936707b5d2d3e5b4c9f2871 (diff) |
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>
-rw-r--r-- | 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); |