X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=sys%2Fv4l2%2Fv4l2_calls.c;fp=sys%2Fv4l2%2Fv4l2_calls.c;h=b99bcc6a51c73da37d8f8554a4f1c867b91ff814;hb=f05e14ba316d67b9cdf1440d9b2129da03625a30;hp=8909b6afbf80e26c4ba41f7eaf4fe7cce8335f9a;hpb=ce0723527aa37d5f4d19ef8021c0b2eb8f83b08d;p=platform%2Fupstream%2Fgst-plugins-good.git diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index 8909b6a..b99bcc6 100644 --- a/sys/v4l2/v4l2_calls.c +++ b/sys/v4l2/v4l2_calls.c @@ -33,6 +33,9 @@ #include #include #include +#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +#include +#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ #ifdef __sun /* Needed on older Solaris Nevada builds (72 at least) */ #include @@ -48,6 +51,17 @@ #include "gst/gst-i18n-plugin.h" +#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +enum { + V4L2_OPEN_ERROR = 0, + V4L2_OPEN_ERROR_STAT_FAILED, + V4L2_OPEN_ERROR_NO_DEVICE, + V4L2_OPEN_ERROR_NOT_OPEN, + V4L2_OPEN_ERROR_NOT_CAPTURE, + V4L2_OPEN_ERROR_NOT_OUTPUT +}; +#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ + GST_DEBUG_CATEGORY_EXTERN (v4l2_debug); #define GST_CAT_DEFAULT v4l2_debug @@ -519,7 +533,18 @@ gst_v4l2_open (GstV4l2Object * v4l2object) { struct stat st; int libv4l2_fd = -1; +#ifdef TIZEN_FEATURE_V4L2SRC_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)); + if (!v4l2object) { + GST_ERROR("v4l2object is NULL"); + return FALSE; + } +#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying to open device %s", v4l2object->videodev); @@ -530,19 +555,48 @@ gst_v4l2_open (GstV4l2Object * v4l2object) if (!v4l2object->videodev) v4l2object->videodev = g_strdup ("/dev/video"); +#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE + if (!v4l2object->videodev) { + 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 */ if (!S_ISCHR (st.st_mode)) goto no_device; +#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ /* open the device */ v4l2object->video_fd = open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ ); +#ifdef TIZEN_FEATURE_V4L2SRC_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 */ if (!GST_V4L2_IS_OPEN (v4l2object)) goto not_open; +#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ #ifdef HAVE_LIBV4L2 if (v4l2object->fd_open) @@ -560,19 +614,45 @@ gst_v4l2_open (GstV4l2Object * v4l2object) v4l2object->video_fd = libv4l2_fd; /* get capabilities, error will be posted */ +#ifdef TIZEN_FEATURE_V4L2SRC_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); + 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 */ 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 */ if (GST_IS_V4L2_VIDEO_DEC (v4l2object->element) && !GST_V4L2_IS_M2M (v4l2object->device_caps)) @@ -581,8 +661,15 @@ gst_v4l2_open (GstV4l2Object * v4l2object) gst_v4l2_adjust_buf_type (v4l2object); /* create enumerations, posts errors. */ +#ifdef TIZEN_FEATURE_V4L2SRC_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 */ if (!gst_v4l2_fill_lists (v4l2object)) goto error; +#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ GST_INFO_OBJECT (v4l2object->dbg_obj, "Opened device '%s' (%s) successfully", @@ -591,6 +678,10 @@ gst_v4l2_open (GstV4l2Object * v4l2object) 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 */ + /* 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 */ @@ -601,6 +692,60 @@ gst_v4l2_open (GstV4l2Object * v4l2object) return TRUE; +#ifdef TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE +pre_error_check: + { + 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"); + } + } + + 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) { + device_index++; + GST_INFO_OBJECT(v4l2object->element, "check device [%s]", + v4l2object->videodev); + + if (GST_V4L2_IS_OPEN (v4l2object)) { + /* close device */ + v4l2_close (v4l2object->video_fd); + v4l2object->video_fd = -1; + } + /* empty lists */ + gst_v4l2_empty_lists (v4l2object); + + goto CHECK_AGAIN; + } else { + 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); + + switch (error_type) { + case V4L2_OPEN_ERROR_STAT_FAILED: + goto stat_failed; + case V4L2_OPEN_ERROR_NO_DEVICE: + goto no_device; + case V4L2_OPEN_ERROR_NOT_OPEN: + goto not_open; + case V4L2_OPEN_ERROR_NOT_CAPTURE: + goto not_capture; + case V4L2_OPEN_ERROR_NOT_OUTPUT: + goto not_output; + default: + goto error; + } + } +#endif /* TIZEN_FEATURE_V4L2SRC_SCAN_DEVICE_NODE */ + /* ERRORS */ stat_failed: { @@ -657,6 +802,10 @@ 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 */ + return FALSE; } }