From e8ae00f5fcd0ee53f500293781bce73820c50414 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 12 Jul 2011 19:03:32 +0100 Subject: [PATCH] v4l2: simplify setting the capture format 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 | 32 ++++++++++++++++++++++++++++---- sys/v4l2/gstv4l2object.h | 10 ++++------ sys/v4l2/gstv4l2sink.c | 27 +++++---------------------- sys/v4l2/gstv4l2src.c | 21 ++------------------- sys/v4l2/v4l2src_calls.c | 15 ++++++--------- sys/v4l2/v4l2src_calls.h | 6 +----- 6 files changed, 46 insertions(+), 65 deletions(-) diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index ee8ad9c..62bb7d5 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -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, diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index f1c003a..693c038 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -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); diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c index 5ea4c15..7c1555d 100644 --- a/sys/v4l2/gstv4l2sink.c +++ b/sys/v4l2/gstv4l2sink.c @@ -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"); diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index d105e83..63df10b 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -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; } diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c index 3157842..ca3439e 100644 --- a/sys/v4l2/v4l2src_calls.c +++ b/sys/v4l2/v4l2src_calls.c @@ -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); diff --git a/sys/v4l2/v4l2src_calls.h b/sys/v4l2/v4l2src_calls.h index 8cec750..396e2db 100644 --- a/sys/v4l2/v4l2src_calls.h +++ b/sys/v4l2/v4l2src_calls.h @@ -27,11 +27,7 @@ #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); -- 2.7.4