From: Reynaldo H. Verdejo Pinochet Date: Sat, 2 Jul 2016 08:56:07 +0000 (-0700) Subject: v4l2: use opened device caps instead of physical device ones X-Git-Tag: 1.19.3~509^2~2648 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4b16b16aaf79c0556b06f04d192fe00a17ab2c24;p=platform%2Fupstream%2Fgstreamer.git v4l2: use opened device caps instead of physical device ones The same physical device can export multiple devices. In this case, the capabilities field now contains a union of all caps available from all exported V4L2 devices alongside a V4L2_CAP_DEVICE_CAPS flag that should be used to decide what capabilities to consider. In our case, we need the ones from the exported device we are using. https://bugzilla.gnome.org/show_bug.cgi?id=768195 --- diff --git a/sys/v4l2/gstv4l2.c b/sys/v4l2/gstv4l2.c index 83fcc98..d2b9a34 100644 --- a/sys/v4l2/gstv4l2.c +++ b/sys/v4l2/gstv4l2.c @@ -119,6 +119,7 @@ gst_v4l2_probe_and_register (GstPlugin * plugin) gint video_fd = -1; struct v4l2_capability vcap; gboolean ret = TRUE; + guint32 device_caps; it = gst_v4l2_iterator_new (); @@ -143,12 +144,16 @@ gst_v4l2_probe_and_register (GstPlugin * plugin) continue; } - if (!((vcap.capabilities & (V4L2_CAP_VIDEO_M2M | - V4L2_CAP_VIDEO_M2M_MPLANE)) || + if (vcap.capabilities & V4L2_CAP_DEVICE_CAPS) + device_caps = vcap.device_caps; + else + device_caps = vcap.capabilitites; + + if (!((device_caps & (V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE)) || /* But legacy driver may expose both CAPTURE and OUTPUT */ - ((vcap.capabilities & + ((device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) && - (vcap.capabilities & + (device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))))) continue; diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c index 3184bd8..bfcfbaa 100644 --- a/sys/v4l2/gstv4l2bufferpool.c +++ b/sys/v4l2/gstv4l2bufferpool.c @@ -716,7 +716,7 @@ gst_v4l2_buffer_pool_start (GstBufferPool * bpool) * poll before that will always fail. Doing an empty read, forces the * queue to be initialized now. We only do this if we have a streaming * driver. */ - if (obj->vcap.capabilities & V4L2_CAP_STREAMING) + if (obj->device_caps & V4L2_CAP_STREAMING) v4l2_read (obj->video_fd, NULL, 0); #endif break; diff --git a/sys/v4l2/gstv4l2deviceprovider.c b/sys/v4l2/gstv4l2deviceprovider.c index d521838..68e0657 100644 --- a/sys/v4l2/gstv4l2deviceprovider.c +++ b/sys/v4l2/gstv4l2deviceprovider.c @@ -136,10 +136,10 @@ gst_v4l2_device_provider_probe_device (GstV4l2DeviceProvider * provider, gst_structure_set (props, "v4l2.device.device_caps", G_TYPE_UINT, v4l2obj->vcap.device_caps, NULL); - if (v4l2obj->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE) + if (v4l2obj->device_caps & V4L2_CAP_VIDEO_CAPTURE) type = GST_V4L2_DEVICE_TYPE_SOURCE; - if (v4l2obj->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT) { + if (v4l2obj->device_caps & V4L2_CAP_VIDEO_OUTPUT) { /* Morph it in case our initial guess was wrong */ v4l2obj->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c index d4acbf9..ab7e52f 100644 --- a/sys/v4l2/gstv4l2object.c +++ b/sys/v4l2/gstv4l2object.c @@ -700,17 +700,17 @@ gst_v4l2_object_get_property_helper (GstV4l2Object * v4l2object, guint flags = 0; if (GST_V4L2_IS_OPEN (v4l2object)) { - flags |= v4l2object->vcap.capabilities & + flags |= v4l2object->device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VBI_OUTPUT | V4L2_CAP_TUNER | V4L2_CAP_AUDIO); - if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) + if (v4l2object->device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) flags |= V4L2_CAP_VIDEO_CAPTURE; - if (v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE) + if (v4l2object->device_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) flags |= V4L2_CAP_VIDEO_OUTPUT; } g_value_set_flags (value, flags); @@ -873,6 +873,9 @@ gst_v4l2_object_close (GstV4l2Object * v4l2object) gst_caps_replace (&v4l2object->probed_caps, NULL); + /* reset our copy of the device caps */ + v4l2object->device_caps = 0; + if (v4l2object->formats) { gst_v4l2_object_clear_format_list (v4l2object); } @@ -2824,13 +2827,13 @@ gst_v4l2_object_setup_pool (GstV4l2Object * v4l2object, GstCaps * caps) /* find transport */ mode = v4l2object->req_mode; - if (v4l2object->vcap.capabilities & V4L2_CAP_READWRITE) { + if (v4l2object->device_caps & V4L2_CAP_READWRITE) { if (v4l2object->req_mode == GST_V4L2_IO_AUTO) mode = GST_V4L2_IO_RW; } else if (v4l2object->req_mode == GST_V4L2_IO_RW) goto method_not_supported; - if (v4l2object->vcap.capabilities & V4L2_CAP_STREAMING) { + if (v4l2object->device_caps & V4L2_CAP_STREAMING) { if (v4l2object->req_mode == GST_V4L2_IO_AUTO) mode = GST_V4L2_IO_MMAP; } else if (v4l2object->req_mode == GST_V4L2_IO_MMAP) diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index 7117d43..5fff161 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -133,6 +133,8 @@ struct _GstV4l2Object { /* the video device's capabilities */ struct v4l2_capability vcap; + /* opened device specific capabilities */ + guint32 device_caps; /* the video device's window properties */ struct v4l2_window vwin; diff --git a/sys/v4l2/gstv4l2radio.c b/sys/v4l2/gstv4l2radio.c index 7a6463c..5d74e7e 100644 --- a/sys/v4l2/gstv4l2radio.c +++ b/sys/v4l2/gstv4l2radio.c @@ -90,7 +90,12 @@ gst_v4l2radio_fill_channel_list (GstV4l2Radio * radio) if (res < 0) goto caps_failed; - if (!(vc.capabilities & V4L2_CAP_TUNER)) + if (vc.capabilities & V4L2_CAP_DEVICE_CAPS) + v4l2object->device_caps = vc.device_caps; + else + v4l2object->device_caps = vc.capabilities; + + if (!(v4l2object->device_caps & V4L2_CAP_TUNER)) goto not_a_tuner; /* getting audio input */ diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c index ae4a3c2..b5f34eb 100644 --- a/sys/v4l2/gstv4l2sink.c +++ b/sys/v4l2/gstv4l2sink.c @@ -250,10 +250,10 @@ gst_v4l2sink_sync_overlay_fields (GstV4l2Sink * v4l2sink) struct v4l2_format format; memset (&format, 0x00, sizeof (struct v4l2_format)); - if ( v4l2sink->v4l2object->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY ) - format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY; - else - format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + if (v4l2sink->v4l2object->device_caps & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) + format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY; + else + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; if (v4l2_ioctl (fd, VIDIOC_G_FMT, &format) < 0) { GST_WARNING_OBJECT (v4l2sink, "VIDIOC_G_FMT failed"); diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index bfb6557..8d8337e 100644 --- a/sys/v4l2/v4l2_calls.c +++ b/sys/v4l2/v4l2_calls.c @@ -74,11 +74,16 @@ gst_v4l2_get_capabilities (GstV4l2Object * v4l2object) if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCAP, &v4l2object->vcap) < 0) goto cap_failed; + if (v4l2object->vcap.capabilities & V4L2_CAP_DEVICE_CAPS) + v4l2object->device_caps = v4l2object->vcap.device_caps; + else + v4l2object->device_caps = v4l2object->vcap.capabilities; + GST_LOG_OBJECT (e, "driver: '%s'", v4l2object->vcap.driver); GST_LOG_OBJECT (e, "card: '%s'", v4l2object->vcap.card); GST_LOG_OBJECT (e, "bus_info: '%s'", v4l2object->vcap.bus_info); GST_LOG_OBJECT (e, "version: %08x", v4l2object->vcap.version); - GST_LOG_OBJECT (e, "capabilites: %08x", v4l2object->vcap.capabilities); + GST_LOG_OBJECT (e, "capabilites: %08x", v4l2object->device_caps); return TRUE; @@ -487,13 +492,13 @@ gst_v4l2_adjust_buf_type (GstV4l2Object * v4l2object) #define CHECK_CAPS (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_M2M_MPLANE) switch (v4l2object->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT: - if (v4l2object->vcap.capabilities & CHECK_CAPS) { + if (v4l2object->device_caps & CHECK_CAPS) { GST_DEBUG ("adjust type to multi-planar output"); v4l2object->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; } break; case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (v4l2object->vcap.capabilities & CHECK_CAPS) { + if (v4l2object->device_caps & CHECK_CAPS) { GST_DEBUG ("adjust type to multi-planar capture"); v4l2object->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; } @@ -556,23 +561,23 @@ gst_v4l2_open (GstV4l2Object * v4l2object) /* do we need to be a capture device? */ if (GST_IS_V4L2SRC (v4l2object->element) && - !(v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_CAPTURE | + !(v4l2object->device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE))) goto not_capture; if (GST_IS_V4L2SINK (v4l2object->element) && - !(v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_OUTPUT | + !(v4l2object->device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) goto not_output; if (GST_IS_V4L2_VIDEO_DEC (v4l2object->element) && /* Today's M2M device only expose M2M */ - !((v4l2object->vcap.capabilities & (V4L2_CAP_VIDEO_M2M | + !((v4l2object->device_caps & (V4L2_CAP_VIDEO_M2M | V4L2_CAP_VIDEO_M2M_MPLANE)) || /* But legacy driver may expose both CAPTURE and OUTPUT */ - ((v4l2object->vcap.capabilities & + ((v4l2object->device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) && - (v4l2object->vcap.capabilities & + (v4l2object->device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))))) goto not_m2m; @@ -625,7 +630,7 @@ not_capture: GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a capture device."), v4l2object->videodev), - ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); + ("Capabilities: 0x%x", v4l2object->device_caps)); goto error; } not_output: @@ -633,7 +638,7 @@ not_output: GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a output device."), v4l2object->videodev), - ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); + ("Capabilities: 0x%x", v4l2object->device_caps)); goto error; } not_m2m: @@ -641,7 +646,7 @@ not_m2m: GST_ELEMENT_ERROR (v4l2object->element, RESOURCE, NOT_FOUND, (_("Device '%s' is not a M2M device."), v4l2object->videodev), - ("Capabilities: 0x%x", v4l2object->vcap.capabilities)); + ("Capabilities: 0x%x", v4l2object->device_caps)); goto error; } error: @@ -1034,7 +1039,7 @@ gst_v4l2_get_input (GstV4l2Object * v4l2object, gint * input) /* ERRORS */ input_failed: - if (v4l2object->vcap.capabilities & V4L2_CAP_TUNER) { + if (v4l2object->device_caps & V4L2_CAP_TUNER) { /* only give a warning message if driver actually claims to have tuner * support */ @@ -1059,7 +1064,7 @@ gst_v4l2_set_input (GstV4l2Object * v4l2object, gint input) /* ERRORS */ input_failed: - if (v4l2object->vcap.capabilities & V4L2_CAP_TUNER) { + if (v4l2object->device_caps & V4L2_CAP_TUNER) { /* only give a warning message if driver actually claims to have tuner * support */ @@ -1091,7 +1096,7 @@ gst_v4l2_get_output (GstV4l2Object * v4l2object, gint * output) /* ERRORS */ output_failed: - if (v4l2object->vcap.capabilities & V4L2_CAP_TUNER) { + if (v4l2object->device_caps & V4L2_CAP_TUNER) { /* only give a warning message if driver actually claims to have tuner * support */ @@ -1116,7 +1121,7 @@ gst_v4l2_set_output (GstV4l2Object * v4l2object, gint output) /* ERRORS */ output_failed: - if (v4l2object->vcap.capabilities & V4L2_CAP_TUNER) { + if (v4l2object->device_caps & V4L2_CAP_TUNER) { /* only give a warning message if driver actually claims to have tuner * support */