v4l2: simplify setting the capture format
authorWim Taymans <wim.taymans@collabora.co.uk>
Tue, 12 Jul 2011 18:03:32 +0000 (19:03 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 12 Jul 2011 18:03:32 +0000 (19:03 +0100)
Pass the caps to the set_format function and make _set_format parse the caps.
Also keep the parsed values in the v4l2object so that we can refer to them when
we want.

sys/v4l2/gstv4l2object.c
sys/v4l2/gstv4l2object.h
sys/v4l2/gstv4l2sink.c
sys/v4l2/gstv4l2src.c
sys/v4l2/v4l2src_calls.c
sys/v4l2/v4l2src_calls.h

index ee8ad9c..62bb7d5 100644 (file)
@@ -1331,9 +1331,9 @@ gst_v4l2_object_get_all_caps (void)
  * @fps_n/@fps_d: location for framerate
  * @size: location for expected size of the frame or 0 if unknown
  */
-gboolean
+static gboolean
 gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
-    struct v4l2_fmtdesc ** format, gint * w, gint * h,
+    struct v4l2_fmtdesc **format, gint * w, gint * h,
     gboolean * interlaced, guint * fps_n, guint * fps_d, guint * size)
 {
   GstStructure *structure;
@@ -2060,12 +2060,30 @@ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
 
 
 gboolean
-gst_v4l2_object_set_format (GstV4l2Object * v4l2object, guint32 pixelformat,
-    guint32 width, guint32 height, gboolean interlaced)
+gst_v4l2_object_set_format (GstV4l2Object * v4l2object, GstCaps * caps)
 {
   gint fd = v4l2object->video_fd;
   struct v4l2_format *format;
   enum v4l2_field field;
+  guint32 pixelformat;
+  gint width;
+  gint height;
+  gboolean interlaced;
+  struct v4l2_fmtdesc *fmtdesc;
+  guint fps_n, fps_d;
+  guint size;
+
+  if (!gst_v4l2_object_get_caps_info (v4l2object, caps,
+          &fmtdesc, &width, &height, &interlaced, &fps_n, &fps_d, &size))
+    goto invalid_caps;
+
+  v4l2object->fps_n = fps_n;
+  v4l2object->fps_d = fps_d;
+  v4l2object->size = size;
+  v4l2object->width = width;
+  v4l2object->height = height;
+
+  pixelformat = fmtdesc->pixelformat;
 
   if (interlaced) {
     GST_DEBUG_OBJECT (v4l2object->element, "interlaced video");
@@ -2146,6 +2164,12 @@ gst_v4l2_object_set_format (GstV4l2Object * v4l2object, guint32 pixelformat,
   return TRUE;
 
   /* ERRORS */
+invalid_caps:
+  {
+    GST_DEBUG_OBJECT (v4l2object->element, "can't parse caps %" GST_PTR_FORMAT,
+        caps);
+    return FALSE;
+  }
 get_fmt_failed:
   {
     GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, SETTINGS,
index f1c003a..693c038 100644 (file)
@@ -93,6 +93,9 @@ struct _GstV4l2Object {
 
   /* the current format */
   struct v4l2_format format;
+  guint width, height;
+  guint fps_n, fps_d;
+  guint size;
 
   /* the video device's capabilities */
   struct v4l2_capability vcap;
@@ -182,18 +185,13 @@ GValueArray* gst_v4l2_probe_get_values      (GstPropertyProbe * probe, guint pro
 GstCaps*      gst_v4l2_object_probe_caps_for_format (GstV4l2Object *v4l2object, guint32 pixelformat,
                                              const GstStructure * template);
 
-gboolean      gst_v4l2_object_get_caps_info (GstV4l2Object *v4l2object, GstCaps *caps,
-                                             struct v4l2_fmtdesc **format, gint *w, gint *h,
-                                             gboolean * interlaced, guint *fps_n, guint *fps_d, guint *size);
-
-
 GSList*       gst_v4l2_object_get_format_list  (GstV4l2Object *v4l2object);
 
 GstCaps*      gst_v4l2_object_get_all_caps (void);
 
 GstStructure* gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
 
-gboolean      gst_v4l2_object_set_format (GstV4l2Object *v4l2object, guint32 pixelformat, guint32 width, guint32 height, gboolean interlaced);
+gboolean      gst_v4l2_object_set_format (GstV4l2Object *v4l2object, GstCaps * caps);
 
 gboolean      gst_v4l2_object_start_streaming (GstV4l2Object *v4l2object);
 gboolean      gst_v4l2_object_stop_streaming (GstV4l2Object *v4l2object);
index 5ea4c15..7c1555d 100644 (file)
@@ -617,11 +617,6 @@ static gboolean
 gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
 {
   GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
-  gint w = 0, h = 0;
-  gboolean interlaced;
-  struct v4l2_fmtdesc *format;
-  guint fps_n, fps_d;
-  guint size;
   GstV4l2BufferPool *newpool;
 
   LOG_CAPS (v4l2sink, caps);
@@ -641,11 +636,6 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
     GST_DEBUG_OBJECT (v4l2sink, "no they aren't!");
   }
 
-  /* we want our own v4l2 type of fourcc codes */
-  if (!gst_v4l2_object_get_caps_info (v4l2sink->v4l2object, caps,
-          &format, &w, &h, &interlaced, &fps_n, &fps_d, &size))
-    goto invalid_caps;
-
   if (v4l2sink->pool) {
     /* we have a pool already, stop and destroy the old pool */
     if (v4l2sink->state == STATE_STREAMING) {
@@ -658,8 +648,7 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
     v4l2sink->pool = NULL;
   }
 
-  if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, format->pixelformat,
-          w, h, interlaced))
+  if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, caps))
     goto invalid_format;
 
   if (!(v4l2sink->v4l2object->vcap.capabilities & V4L2_CAP_STREAMING))
@@ -688,26 +677,20 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
     g_object_notify (G_OBJECT (v4l2sink), "queue-size");
   }
 
-  v4l2sink->video_width = w;
-  v4l2sink->video_height = h;
+  v4l2sink->video_width = v4l2sink->v4l2object->width;
+  v4l2sink->video_height = v4l2sink->v4l2object->height;
 
   /* TODO: videosink width/height should be scaled according to
    * pixel-aspect-ratio
    */
-  GST_VIDEO_SINK_WIDTH (v4l2sink) = w;
-  GST_VIDEO_SINK_HEIGHT (v4l2sink) = h;
+  GST_VIDEO_SINK_WIDTH (v4l2sink) = v4l2sink->video_width;
+  GST_VIDEO_SINK_HEIGHT (v4l2sink) = v4l2sink->video_height;
 
   v4l2sink->current_caps = gst_caps_ref (caps);
 
   return TRUE;
 
   /* ERRORS */
-invalid_caps:
-  {
-    GST_DEBUG_OBJECT (v4l2sink,
-        "can't get capture format from caps %" GST_PTR_FORMAT, caps);
-    return FALSE;
-  }
 stop_failed:
   {
     GST_DEBUG_OBJECT (v4l2sink, "failed to stop streaming");
index d105e83..63df10b 100644 (file)
@@ -515,11 +515,6 @@ static gboolean
 gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
 {
   GstV4l2Src *v4l2src;
-  gint w = 0, h = 0;
-  gboolean interlaced;
-  struct v4l2_fmtdesc *format;
-  guint fps_n, fps_d;
-  guint size;
 
   v4l2src = GST_V4L2SRC (src);
 
@@ -536,19 +531,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
       return FALSE;
   }
 
-  /* we want our own v4l2 type of fourcc codes */
-  if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format, &w,
-          &h, &interlaced, &fps_n, &fps_d, &size)) {
-    GST_INFO_OBJECT (v4l2src,
-        "can't get capture format from caps %" GST_PTR_FORMAT, caps);
-    return FALSE;
-  }
-
-  GST_DEBUG_OBJECT (v4l2src, "trying to set_capture %dx%d at %d/%d fps, "
-      "format %s", w, h, fps_n, fps_d, format->description);
-
-  if (!gst_v4l2src_set_capture (v4l2src, format->pixelformat, w, h,
-          interlaced, fps_n, fps_d))
+  if (!gst_v4l2src_set_capture (v4l2src, caps))
     /* error already posted */
     return FALSE;
 
@@ -565,7 +548,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
     return FALSE;
 
   /* now store the expected output size */
-  v4l2src->frame_byte_size = size;
+  v4l2src->frame_byte_size = v4l2src->v4l2object->size;
 
   return TRUE;
 }
index 3157842..ca3439e 100644 (file)
@@ -213,21 +213,18 @@ too_many_trials:
  * return value: TRUE on success, FALSE on error
  ******************************************************/
 gboolean
-gst_v4l2src_set_capture (GstV4l2Src * v4l2src, guint32 pixelformat,
-    guint32 width, guint32 height, gboolean interlaced,
-    guint fps_n, guint fps_d)
+gst_v4l2src_set_capture (GstV4l2Src * v4l2src, GstCaps * caps)
 {
   gint fd = v4l2src->v4l2object->video_fd;
   struct v4l2_streamparm stream;
+  guint fps_n, fps_d;
 
-  if (pixelformat == GST_MAKE_FOURCC ('M', 'P', 'E', 'G'))
-    return TRUE;
-
-  if (!gst_v4l2_object_set_format (v4l2src->v4l2object, pixelformat, width,
-          height, interlaced)) {
+  if (!gst_v4l2_object_set_format (v4l2src->v4l2object, caps))
     /* error already reported */
     return FALSE;
-  }
+
+  fps_n = v4l2src->v4l2object->fps_n;
+  fps_d = v4l2src->v4l2object->fps_d;
 
   /* Is there a reason we require the caller to always specify a framerate? */
   GST_DEBUG_OBJECT (v4l2src, "Desired framerate: %u/%u", fps_n, fps_d);
index 8cec750..396e2db 100644 (file)
 #include "gstv4l2src.h"
 #include "v4l2_calls.h"
 
-gboolean   gst_v4l2src_set_capture       (GstV4l2Src * v4l2src,
-                                          guint32 pixelformat,
-                                          guint32 width, guint32 height,
-                                          gboolean interlaced,
-                                          guint32 fps_n, guint32 fps_d);
+gboolean   gst_v4l2src_set_capture       (GstV4l2Src * v4l2src, GstCaps *caps);
 
 gboolean   gst_v4l2src_capture_init      (GstV4l2Src * v4l2src);
 gboolean   gst_v4l2src_capture_start     (GstV4l2Src * v4l2src);