From 0f2d27525bddf5b88593138d0c253fb2d4127b79 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Mon, 9 Jun 2008 08:52:04 +0000 Subject: [PATCH] sys/v4l2/gstv4l2src.c: Improve negotiation a bit more by picking the smallest possible resolution that is larger than... Original commit message from CVS: Patch by: Sjoerd Simons * sys/v4l2/gstv4l2src.c: (gst_v4l2src_negotiate): Improve negotiation a bit more by picking the smallest possible resolution that is larger than the resolution specified in the first caps entry of the peer caps. Fixes bug #536994. --- ChangeLog | 9 +++++++++ sys/v4l2/gstv4l2src.c | 45 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29170c69e9..1e49d31ba4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-06-09 Sebastian Dröge + + Patch by: Sjoerd Simons + + * sys/v4l2/gstv4l2src.c: (gst_v4l2src_negotiate): + Improve negotiation a bit more by picking the smallest possible + resolution that is larger than the resolution specified in the + first caps entry of the peer caps. Fixes bug #536994. + 2008-06-09 Sebastian Dröge Patch by: Bastien Nocera diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 88757400cc..140ea5e375 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -497,13 +497,48 @@ gst_v4l2src_negotiate (GstBaseSrc * basesrc) } GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, icaps); + if (icaps) { + /* If there are multiple intersections pick the one with the smallest + * resolution strictly bigger then the first peer caps */ + if (gst_caps_get_size (icaps) > 1) { + GstStructure *s = gst_caps_get_structure (peercaps, 0); + + int best = 0; + + int twidth, theight; + + int width = G_MAXINT, height = G_MAXINT; + + if (gst_structure_get_int (s, "width", &twidth) + && gst_structure_get_int (s, "height", &theight)) { + + /* Walk the structure backwards to get the first entry of the + * smallest resolution bigger (or equal to) the preferred resolution) + */ + for (i = gst_caps_get_size (icaps) - 1; i >= 0; i--) { + GstStructure *is = gst_caps_get_structure (icaps, i); + + int w, h; + + if (gst_structure_get_int (is, "width", &w) + && gst_structure_get_int (is, "height", &h)) { + if (w >= twidth && w <= width && h >= theight && h <= height) { + width = w; + height = h; + best = i; + } + } + } + } + + caps = gst_caps_copy_nth (icaps, best); + gst_caps_unref (icaps); + } else { + caps = icaps; + } + } gst_caps_unref (thiscaps); gst_caps_unref (peercaps); - if (icaps) { - /* take first (and best, since they are sorted) possibility */ - caps = gst_caps_copy_nth (icaps, 0); - gst_caps_unref (icaps); - } } else { /* no peer or peer have ANY caps, work with our own caps then */ caps = thiscaps;