#include <string.h>
#include <errno.h>
#include <unistd.h>
+#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE
+#include <glob.h>
+#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */
#ifdef __sun
/* Needed on older Solaris Nevada builds (72 at least) */
#include <stropts.h>
#include "gst/gst-i18n-plugin.h"
+#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_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_AUTO_SCAN_DEVICE_NODE */
+
GST_DEBUG_CATEGORY_EXTERN (v4l2_debug);
#define GST_CAT_DEFAULT v4l2_debug
}
default:
GST_DEBUG_OBJECT (e,
- "Control type for '%s' not suppored for extra controls.",
+ "Control type for '%s' not supported for extra controls.",
control.name);
break;
}
case V4L2_CID_AUTOGAIN:
case V4L2_CID_GAIN:
case V4L2_CID_SHARPNESS:
+#ifdef TIZEN_FEATURE_V4L2_ADDITIONAL_CID_SUPPORT
+ case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
+ case V4L2_CID_EXPOSURE_AUTO:
+ case V4L2_CID_EXPOSURE_ABSOLUTE:
+ case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
+#endif /* TIZEN_FEATURE_V4L2_ADDITIONAL_CID_SUPPORT */
/* we only handle these for now (why?) */
break;
case V4L2_CID_HFLIP:
{
struct stat st;
int libv4l2_fd = -1;
+#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));
+ if (!v4l2object) {
+ GST_ERROR ("v4l2object is NULL");
+ return FALSE;
+ }
+#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Trying to open device %s",
v4l2object->videodev);
if (!v4l2object->videodev)
v4l2object->videodev = g_strdup ("/dev/video");
+#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE
+ if (!v4l2object->videodev) {
+ GST_ERROR_OBJECT (v4l2object->element, "videodev is NULL");
+ return FALSE;
+ }
+
+CHECK_AGAIN:
+ /* check if it is a device */
+ if (stat (v4l2object->videodev, &st) == -1) {
+ error_type = V4L2_OPEN_ERROR_STAT_FAILED;
+ goto pre_error_check;
+ }
+
+ if (!S_ISCHR (st.st_mode)) {
+ error_type = V4L2_OPEN_ERROR_NO_DEVICE;
+ goto pre_error_check;
+ }
+#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_AUTO_SCAN_DEVICE_NODE */
/* open the device */
v4l2object->video_fd =
open (v4l2object->videodev, O_RDWR /* | O_NONBLOCK */ );
+#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_AUTO_SCAN_DEVICE_NODE */
if (!GST_V4L2_IS_OPEN (v4l2object))
goto not_open;
+#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */
#ifdef HAVE_LIBV4L2
if (v4l2object->fd_open)
v4l2object->video_fd = libv4l2_fd;
/* get capabilities, error will be posted */
+#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE
+ if (!gst_v4l2_get_capabilities (v4l2object)) {
+ error_type = V4L2_OPEN_ERROR;
+ goto pre_error_check;
+ }
+
+ 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;
+ }
+
+ 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_AUTO_SCAN_DEVICE_NODE */
if (!gst_v4l2_get_capabilities (v4l2object))
goto error;
!(v4l2object->device_caps & (V4L2_CAP_VIDEO_OUTPUT |
V4L2_CAP_VIDEO_OUTPUT_MPLANE)))
goto not_output;
+#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */
if (GST_IS_V4L2_VIDEO_DEC (v4l2object->element) &&
- /* Today's M2M device only expose M2M */
- !((v4l2object->device_caps & (V4L2_CAP_VIDEO_M2M |
- V4L2_CAP_VIDEO_M2M_MPLANE)) ||
- /* But legacy driver may expose both CAPTURE and OUTPUT */
- ((v4l2object->device_caps &
- (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) &&
- (v4l2object->device_caps &
- (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE)))))
+ !GST_V4L2_IS_M2M (v4l2object->device_caps))
goto not_m2m;
gst_v4l2_adjust_buf_type (v4l2object);
/* create enumerations, posts errors. */
+#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_AUTO_SCAN_DEVICE_NODE */
if (!gst_v4l2_fill_lists (v4l2object))
goto error;
+#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */
GST_INFO_OBJECT (v4l2object->dbg_obj,
"Opened device '%s' (%s) successfully",
if (v4l2object->extra_controls)
gst_v4l2_set_controls (v4l2object, v4l2object->extra_controls);
+#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
*/
return TRUE;
+#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE
+pre_error_check:
+ {
+ if (v4l2object->auto_scan_device == FALSE) {
+ GST_WARNING_OBJECT (v4l2object->element, "auto scan device disabled");
+ goto error;
+ }
+
+ GST_ERROR_OBJECT (v4l2object->element, "device[%s] failed, error[%d]",
+ v4l2object->videodev, error_type);
+
+ 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 = 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]);
+ }
+ }
+
+ 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_AUTO_SCAN_DEVICE_NODE */
+
/* ERRORS */
stat_failed:
{
/* empty lists */
gst_v4l2_empty_lists (v4l2object);
+#ifdef TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE
+ globfree (&glob_buf);
+#endif /* TIZEN_FEATURE_V4L2SRC_AUTO_SCAN_DEVICE_NODE */
+
return FALSE;
}
}
v4l2object->vcap.card, v4l2object->videodev);
v4l2object->never_interlaced = other->never_interlaced;
+ v4l2object->no_initial_format = other->no_initial_format;
return TRUE;