sys/v4l2/v4l2src_calls.c: Turns out we don't always get the frame sizes in a predefin...
authorTim-Philipp Müller <tim@centricular.net>
Mon, 17 Nov 2008 14:04:20 +0000 (14:04 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Mon, 17 Nov 2008 14:04:20 +0000 (14:04 +0000)
Original commit message from CVS:
* sys/v4l2/v4l2src_calls.c:
(gst_v4l2src_probe_caps_for_format_and_size), (sort_by_frame_size),
(gst_v4l2src_probe_caps_for_format):
Turns out we don't always get the frame sizes in a predefined
order from lowest to highest resolution, so let's just sort the
list by frame size once we've queried the possible resolutions
rather than assume any particular order. Fixes probed caps for
the camera in my HP2133 mini notebook and makes v4l2src default
to a decent size.

ChangeLog
sys/v4l2/v4l2src_calls.c

index b47dda6..0a7a1f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-11-17  Tim-Philipp Müller  <tim.muller at collabora co uk>
+
+       * sys/v4l2/v4l2src_calls.c:
+         (gst_v4l2src_probe_caps_for_format_and_size), (sort_by_frame_size),
+         (gst_v4l2src_probe_caps_for_format):
+         Turns out we don't always get the frame sizes in a predefined
+         order from lowest to highest resolution, so let's just sort the
+         list by frame size once we've queried the possible resolutions
+         rather than assume any particular order. Fixes probed caps for
+         the camera in my HP2133 mini notebook and makes v4l2src default
+         to a decent size.
+
 2008-11-16  Edward Hervey  <edward.hervey@collabora.co.uk>
 
        * gst/matroska/matroska-demux.c: (gst_matroska_demux_audio_caps):
index 6ff5945..c247c49 100644 (file)
@@ -771,6 +771,20 @@ unknown_type:
 }
 #endif /* defined VIDIOC_ENUM_FRAMEINTERVALS */
 
+static gint
+sort_by_frame_size (GstStructure * s1, GstStructure * s2)
+{
+  int w1, h1, w2, h2;
+
+  gst_structure_get_int (s1, "width", &w1);
+  gst_structure_get_int (s1, "height", &h1);
+  gst_structure_get_int (s2, "width", &w2);
+  gst_structure_get_int (s2, "height", &h2);
+
+  /* I think it's safe to assume that this won't overflow for a while */
+  return ((w2 * h2) - (w1 * h1));
+}
+
 GstCaps *
 gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat,
     const GstStructure * template)
@@ -804,8 +818,6 @@ gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat,
       tmp = gst_v4l2src_probe_caps_for_format_and_size (v4l2src, pixelformat,
           w, h, template);
 
-      /* we get low res to high res, but want high res to low res in caps, so
-       * prepend structs to results list, we'll reverse the order later then */
       if (tmp)
         results = g_list_prepend (results, tmp);
 
@@ -830,8 +842,6 @@ gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat,
       tmp = gst_v4l2src_probe_caps_for_format_and_size (v4l2src, pixelformat,
           w, h, template);
 
-      /* we get low res to high res, but want high res to low res in caps, so
-       * prepend structs to results list, we'll reverse the order later then */
       if (tmp)
         results = g_list_prepend (results, tmp);
     }
@@ -864,12 +874,12 @@ gst_v4l2src_probe_caps_for_format (GstV4l2Src * v4l2src, guint32 pixelformat,
     goto unknown_type;
   }
 
-  /* we use an intermediary list to store the results of the probing because
-   * we probe from lowest resolution to highest resolution, but want the caps
-   * to contain the results in reverse order starting with the highest
-   * resolution, as order in caps matters for things like fixation.  However,
-   * there's no gst_caps_prepend_structure(), so we use the list as helper to
-   * reverse the order */
+  /* we use an intermediary list to store and then sort the results of the
+   * probing because we can't make any assumptions about the order in which
+   * the driver will give us the sizes, but we want the final caps to contain
+   * the results starting with the highest resolution and having the lowest
+   * resolution last, since order in caps matters for things like fixation. */
+  results = g_list_sort (results, (GCompareFunc) sort_by_frame_size);
   while (results != NULL) {
     gst_caps_append_structure (ret, GST_STRUCTURE (results->data));
     results = g_list_delete_link (results, results);