From 99f8db82856180acc427259c612aba30f91438c2 Mon Sep 17 00:00:00 2001 From: Jeongmo Yang Date: Wed, 2 Sep 2020 20:17:53 +0900 Subject: [PATCH] v4l2src: Add new property for auto scan device feature [Version] 1.16.2-9 [Issue Type] Update Change-Id: I81d2ee3b62a99ffe55d44c06d4c589ae5e0a8a31 Signed-off-by: Jeongmo Yang --- packaging/gst-plugins-good.spec | 4 +- sys/v4l2/gstv4l2object.h | 5 ++ sys/v4l2/gstv4l2src.c | 30 +++++++++- sys/v4l2/v4l2_calls.c | 123 ++++++++++++++++++++-------------------- 4 files changed, 97 insertions(+), 65 deletions(-) diff --git a/packaging/gst-plugins-good.spec b/packaging/gst-plugins-good.spec index c48cd44..fd50d7a 100644 --- a/packaging/gst-plugins-good.spec +++ b/packaging/gst-plugins-good.spec @@ -3,7 +3,7 @@ Name: gst-plugins-good Version: 1.16.2 -Release: 8 +Release: 9 License: LGPL-2.1+ Summary: GStreamer Streaming-Media Framework Plug-Ins Url: http://gstreamer.freedesktop.org/ @@ -72,7 +72,7 @@ plugins not included in official Tizen images, which may be used for development export V=1 NOCONFIGURE=1 ./autogen.sh export CFLAGS+=" \ - -DTIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE\ + -DTIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE\ -DTIZEN_FEATURE_V4L2SRC_SUPPORT_CAMERA_ID\ -DTIZEN_FEATURE_V4L2VIDEO_ADJ_RANK\ -DTIZEN_FEATURE_WAVPARSE_MODIFICATION\ diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h index eaaff58..c12ff09 100644 --- a/sys/v4l2/gstv4l2object.h +++ b/sys/v4l2/gstv4l2object.h @@ -127,6 +127,11 @@ struct _GstV4l2Object { /* the video device */ char *videodev; +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + /* auto scan device */ + gboolean auto_scan_device; +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ + /* the video-device's file descriptor */ gint video_fd; GstV4l2IOMode mode; diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c index 0b55b5d..36a7fa0 100644 --- a/sys/v4l2/gstv4l2src.c +++ b/sys/v4l2/gstv4l2src.c @@ -75,6 +75,9 @@ enum #ifdef TIZEN_FEATURE_V4L2SRC_SUPPORT_CAMERA_ID PROP_CAMERA_ID, #endif /* TIZEN_FEATURE_V4L2SRC_SUPPORT_CAMERA_ID */ +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + PROP_AUTO_SCAN_DEVICE, +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ PROP_LAST }; @@ -163,6 +166,16 @@ gst_v4l2src_class_init (GstV4l2SrcClass * klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); #endif /* TIZEN_FEATURE_V4L2SRC_SUPPORT_CAMERA_ID */ +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + /** + * GstV4l2Src:auto-scan-device: + */ + g_object_class_install_property (gobject_class, PROP_AUTO_SCAN_DEVICE, + g_param_spec_boolean ("auto-scan-device", "Scan device automatically", + "Scan all device nodes automatically until device open success.", + TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ + /** * GstV4l2Src::prepare-format: * @v4l2src: the v4l2src instance @@ -218,6 +231,9 @@ gst_v4l2src_init (GstV4l2Src * v4l2src) /* Avoid the slow probes */ v4l2src->v4l2object->skip_try_fmt_probes = TRUE; +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + v4l2src->v4l2object->auto_scan_device = TRUE; +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ gst_base_src_set_format (GST_BASE_SRC (v4l2src), GST_FORMAT_TIME); gst_base_src_set_live (GST_BASE_SRC (v4l2src), TRUE); @@ -249,9 +265,15 @@ gst_v4l2src_set_property (GObject * object, v4l2src->camera_id = g_value_get_uint (value); v4l2src->v4l2object->videodev = g_strdup_printf ("/dev/video%u", v4l2src->camera_id); - GST_INFO_OBJECT(v4l2src, "videodev [%s]", v4l2src->v4l2object->videodev); + GST_INFO_OBJECT (v4l2src, "videodev [%s]", v4l2src->v4l2object->videodev); break; #endif /* TIZEN_FEATURE_V4L2SRC_SUPPORT_CAMERA_ID */ +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + case PROP_AUTO_SCAN_DEVICE: + v4l2src->v4l2object->auto_scan_device = g_value_get_boolean (value); + GST_INFO_OBJECT (v4l2src, "auto scan device [%d]", v4l2src->v4l2object->auto_scan_device); + break; +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -273,6 +295,12 @@ gst_v4l2src_get_property (GObject * object, g_value_set_uint (value, v4l2src->camera_id); break; #endif /* TIZEN_FEATURE_V4L2SRC_SUPPORT_CAMERA_ID */ +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + case PROP_AUTO_SCAN_DEVICE: + GST_INFO_OBJECT (v4l2src, "auto scan device [%d]", v4l2src->v4l2object->auto_scan_device); + g_value_set_boolean (value, v4l2src->v4l2object->auto_scan_device); + break; +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index b99bcc6..137f399 100644 --- a/sys/v4l2/v4l2_calls.c +++ b/sys/v4l2/v4l2_calls.c @@ -33,9 +33,9 @@ #include #include #include -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE #include -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ #ifdef __sun /* Needed on older Solaris Nevada builds (72 at least) */ #include @@ -51,7 +51,7 @@ #include "gst/gst-i18n-plugin.h" -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE enum { V4L2_OPEN_ERROR = 0, V4L2_OPEN_ERROR_STAT_FAILED, @@ -60,7 +60,7 @@ enum { V4L2_OPEN_ERROR_NOT_CAPTURE, V4L2_OPEN_ERROR_NOT_OUTPUT }; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ GST_DEBUG_CATEGORY_EXTERN (v4l2_debug); #define GST_CAT_DEFAULT v4l2_debug @@ -533,18 +533,18 @@ gst_v4l2_open (GstV4l2Object * v4l2object) { struct stat st; int libv4l2_fd = -1; -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE int error_type = V4L2_OPEN_ERROR_STAT_FAILED; int device_index = 0; glob_t glob_buf; - memset(&glob_buf, 0x0, sizeof(glob_t)); + memset (&glob_buf, 0x0, sizeof(glob_t)); if (!v4l2object) { - GST_ERROR("v4l2object is NULL"); + GST_ERROR ("v4l2object is NULL"); return FALSE; } -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying to open device %s", v4l2object->videodev); @@ -555,48 +555,45 @@ gst_v4l2_open (GstV4l2Object * v4l2object) if (!v4l2object->videodev) v4l2object->videodev = g_strdup ("/dev/video"); -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE if (!v4l2object->videodev) { - GST_ERROR_OBJECT(v4l2object->element, "videodev is NULL"); + GST_ERROR_OBJECT (v4l2object->element, "videodev is NULL"); return FALSE; } CHECK_AGAIN: -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ /* check if it is a device */ -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE if (stat (v4l2object->videodev, &st) == -1) { error_type = V4L2_OPEN_ERROR_STAT_FAILED; goto pre_error_check; } -#else /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ - if (stat (v4l2object->videodev, &st) == -1) - goto stat_failed; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE if (!S_ISCHR (st.st_mode)) { error_type = V4L2_OPEN_ERROR_NO_DEVICE; goto pre_error_check; } -#else /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#else /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ + /* check if it is a device */ + if (stat (v4l2object->videodev, &st) == -1) + goto stat_failed; + if (!S_ISCHR (st.st_mode)) goto no_device; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ /* open the device */ v4l2object->video_fd = open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ ); -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE if (!GST_V4L2_IS_OPEN (v4l2object)) { error_type = V4L2_OPEN_ERROR_NOT_OPEN; goto pre_error_check; } -#else /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#else /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ if (!GST_V4L2_IS_OPEN (v4l2object)) goto not_open; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ #ifdef HAVE_LIBV4L2 if (v4l2object->fd_open) @@ -614,45 +611,42 @@ CHECK_AGAIN: v4l2object->video_fd = libv4l2_fd; /* get capabilities, error will be posted */ -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE if (!gst_v4l2_get_capabilities (v4l2object)) { error_type = V4L2_OPEN_ERROR; goto pre_error_check; } -#else /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ - if (!gst_v4l2_get_capabilities (v4l2object)) - goto error; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ - /* do we need to be a capture device? */ -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE - GST_INFO_OBJECT(v4l2object->element, "device_caps 0x%x", v4l2object->device_caps); + GST_INFO_OBJECT (v4l2object->element, "device_caps 0x%x", v4l2object->device_caps); + if (GST_IS_V4L2SRC (v4l2object->element) && (!(v4l2object->device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) || (v4l2object->device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE)))) { error_type = V4L2_OPEN_ERROR_NOT_CAPTURE; goto pre_error_check; } -#else /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ - if (GST_IS_V4L2SRC (v4l2object->element) && - !(v4l2object->device_caps & (V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_VIDEO_CAPTURE_MPLANE))) - goto not_capture; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE if (GST_IS_V4L2SINK (v4l2object->element) && !(v4l2object->device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) { error_type = V4L2_OPEN_ERROR_NOT_OUTPUT; goto pre_error_check; } -#else /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#else /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ + if (!gst_v4l2_get_capabilities (v4l2object)) + goto error; + + /* do we need to be a capture device? */ + if (GST_IS_V4L2SRC (v4l2object->element) && + !(v4l2object->device_caps & (V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_VIDEO_CAPTURE_MPLANE))) + goto not_capture; + if (GST_IS_V4L2SINK (v4l2object->element) && !(v4l2object->device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) goto not_output; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ if (GST_IS_V4L2_VIDEO_DEC (v4l2object->element) && !GST_V4L2_IS_M2M (v4l2object->device_caps)) @@ -661,15 +655,15 @@ CHECK_AGAIN: gst_v4l2_adjust_buf_type (v4l2object); /* create enumerations, posts errors. */ -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE if (!gst_v4l2_fill_lists (v4l2object)) { error_type = V4L2_OPEN_ERROR; goto pre_error_check; } -#else /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#else /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ if (!gst_v4l2_fill_lists (v4l2object)) goto error; -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ GST_INFO_OBJECT (v4l2object->dbg_obj, "Opened device '%s' (%s) successfully", @@ -678,9 +672,9 @@ CHECK_AGAIN: if (v4l2object->extra_controls) gst_v4l2_set_controls (v4l2object, v4l2object->extra_controls); -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE - globfree(&glob_buf); -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + globfree (&glob_buf); +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ /* UVC devices are never interlaced, and doing VIDIOC_TRY_FMT on them * causes expensive and slow USB IO, so don't probe them for interlaced @@ -692,25 +686,30 @@ CHECK_AGAIN: return TRUE; -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE pre_error_check: { - if (GST_IS_V4L2SRC(v4l2object->element) && glob_buf.gl_pathc == 0) { + if (v4l2object->auto_scan_device == FALSE) { + GST_WARNING_OBJECT (v4l2object->element, "auto scan device disabled"); + goto error; + } + + if (GST_IS_V4L2SRC (v4l2object->element) && glob_buf.gl_pathc == 0) { if (glob("/dev/video*", 0, 0, &glob_buf) != 0) { - GST_WARNING_OBJECT(v4l2object->element, "glob failed"); + GST_WARNING_OBJECT (v4l2object->element, "glob failed"); } } if (glob_buf.gl_pathc > 0 && device_index < glob_buf.gl_pathc) { - if (v4l2object->videodev) { - g_free(v4l2object->videodev); - v4l2object->videodev = NULL; - } - v4l2object->videodev = g_strdup(glob_buf.gl_pathv[device_index]); + if (v4l2object->videodev) + g_free (v4l2object->videodev); + + v4l2object->videodev = g_strdup (glob_buf.gl_pathv[device_index]); if (v4l2object->videodev) { device_index++; - GST_INFO_OBJECT(v4l2object->element, "check device [%s]", - v4l2object->videodev); + + GST_INFO_OBJECT (v4l2object->element, "check device [%s]", + v4l2object->videodev); if (GST_V4L2_IS_OPEN (v4l2object)) { /* close device */ @@ -722,12 +721,12 @@ pre_error_check: goto CHECK_AGAIN; } else { - GST_WARNING_OBJECT(v4l2object->element, "g_strdup failed [%s]", - glob_buf.gl_pathv[device_index]); + GST_WARNING_OBJECT (v4l2object->element, "g_strdup failed [%s]", + glob_buf.gl_pathv[device_index]); } } - GST_WARNING_OBJECT(v4l2object->element, "error type : %d", error_type); + GST_WARNING_OBJECT (v4l2object->element, "error type : %d", error_type); switch (error_type) { case V4L2_OPEN_ERROR_STAT_FAILED: @@ -744,7 +743,7 @@ pre_error_check: goto error; } } -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ /* ERRORS */ stat_failed: @@ -802,9 +801,9 @@ error: /* empty lists */ gst_v4l2_empty_lists (v4l2object); -#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE - globfree(&glob_buf); -#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ +#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE + globfree (&glob_buf); +#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */ return FALSE; } -- 2.7.4