(fourcc >> 24) & 0xff
static guint32 g_device_caps;
-static GMutex g_device_info_lock;
static int __vision_source_get_format(guint32 fourcc, int *pixel_format)
{
struct v4l2_capability v4l2_cap;
vision_source_device_info_list_s *device_info_list = NULL;
- g_mutex_lock(&g_device_info_lock);
-
device_info_list = g_new0(vision_source_device_info_list_s, 1);
if (!device_info_list) {
LOGE("failed to alloc device info structure");
device_count);
_GET_DEVICE_INFO_LIST_DONE:
- g_mutex_unlock(&g_device_info_lock);
LOGD("ret 0x%x", ret);
if (ret != VISION_SOURCE_ERROR_NONE)
return;
}
+static int __vision_source_v4l2_stream(int device_fd, int type, gboolean onoff)
+{
+ if (device_fd < 0) {
+ LOGE("invalid fd %d", device_fd);
+ return VISION_SOURCE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (v4l2_ioctl(device_fd, onoff ? VIDIOC_STREAMON : VIDIOC_STREAMOFF,
+ &type) < 0) {
+ LOGE("stream %d failed. [t:%d] errno %d", onoff, type, errno);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ LOGD("stream %d done [t:%d]", onoff, type);
+
+ return VISION_SOURCE_ERROR_NONE;
+}
+
+static int __vision_source_v4l2_reqbufs(int device_fd, int type, int memory,
+ uint32_t count, uint32_t *result_count)
+{
+ struct v4l2_requestbuffers v4l2_reqbuf;
+
+ if (device_fd < 0) {
+ LOGE("invalid fd %d", device_fd);
+ return VISION_SOURCE_ERROR_INVALID_PARAMETER;
+ }
+
+ if (!result_count) {
+ LOGE("NULL parameter");
+ return VISION_SOURCE_ERROR_INVALID_PARAMETER;
+ }
+
+ memset(&v4l2_reqbuf, 0x0, sizeof(struct v4l2_requestbuffers));
+
+ v4l2_reqbuf.type = type;
+ v4l2_reqbuf.memory = memory;
+ v4l2_reqbuf.count = count;
+
+ if (v4l2_ioctl(device_fd, VIDIOC_REQBUFS, &v4l2_reqbuf) < 0) {
+ LOGE("REQBUFS[count %d] failed. errno %d", count, errno);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ if (v4l2_reqbuf.count != count)
+ LOGW("different count [req:%d, result:%d]", count, v4l2_reqbuf.count);
+
+ *result_count = v4l2_reqbuf.count;
+
+ return VISION_SOURCE_ERROR_NONE;
+}
+
+static int __vision_source_stop_stream(vision_source_v4l2_s *handle,
+ uint32_t buffer_count)
+{
+ int i = 0;
+ int ret = VISION_SOURCE_ERROR_NONE;
+
+ if (!handle) {
+ LOGE("NULL handle");
+ return VISION_SOURCE_ERROR_INVALID_PARAMETER;
+ }
+
+ LOGD("buffer count[%d]", buffer_count);
+
+ /* stream off */
+ ret = __vision_source_v4l2_stream(handle->device_fd, handle->buffer_type,
+ FALSE);
+
+ LOGD("stream off : 0x%x", ret);
+
+ /* munmap */
+ for (i = 0; i < buffer_count; i++) {
+ if (handle->vision_source_buffers[i].planes[0].data != NULL) {
+ LOGW("munmap %p", handle->vision_source_buffers[i].planes[0].data);
+
+ v4l2_munmap(handle->vision_source_buffers[i].planes[0].data,
+ handle->vision_source_buffers[i].planes[0].size);
+
+ handle->vision_source_buffers[i].planes[0].data = 0;
+ handle->vision_source_buffers[i].planes[0].size = 0;
+ } else {
+ LOGW("NULL data [index %d]", i);
+ }
+ }
+
+ /* reqbufs 0 */
+ ret = __vision_source_v4l2_reqbufs(handle->device_fd, handle->buffer_type,
+ V4L2_MEMORY_MMAP, 0, &buffer_count);
+
+ LOGD("reqbufs 0 : 0x%x", ret);
+
+ return ret;
+}
+
int vision_source_v4l2_init(vision_source_h *handle)
{
LOGD("enter");
return VISION_SOURCE_ERROR_INTERNAL;
}
+ int ret = __vision_source_get_device_info_list(
+ &v4l2_handle->device_info_list);
+
+ if (ret != VISION_SOURCE_ERROR_NONE) {
+ g_free(v4l2_handle);
+ LOGE("get device info failed");
+ return ret;
+ }
+
g_mutex_init(&v4l2_handle->lock);
g_mutex_init(&v4l2_handle->buffer_lock);
g_cond_init(&v4l2_handle->buffer_cond);
- v4l2_handle->device_index = CAMERA_HAL_INITIAL_INDEX;
- v4l2_handle->device_fd = CAMERA_HAL_INITIAL_FD;
- v4l2_handle->buffer_thread = NULL;
- v4l2_handle->device_info_list = NULL;
-
*handle = v4l2_handle;
return VISION_SOURCE_ERROR_NONE;
VISION_SOURCE_NULL_ARG_CHECK(info_list);
vision_source_v4l2_s *v4l2_handle = (vision_source_v4l2_s *) handle;
- int ret;
- if (!v4l2_handle->device_info_list)
- ret = __vision_source_get_device_info_list(
+ if (!v4l2_handle->device_info_list) {
+ int ret = __vision_source_get_device_info_list(
&v4l2_handle->device_info_list);
- if (ret != VISION_SOURCE_ERROR_NONE) {
- LOGE("get device info failed");
- return ret;
+ if (ret != VISION_SOURCE_ERROR_NONE) {
+ LOGE("get device info failed");
+ return ret;
+ }
}
memcpy(info_list, v4l2_handle->device_info_list,
sizeof(vision_source_device_info_list_s));
+
+ return VISION_SOURCE_ERROR_NONE;
+}
+
+int vision_source_v4l2_open_device(vision_source_h handle, int device_index)
+{
+ VISION_SOURCE_NULL_ARG_CHECK(handle);
+
+ int device_fd = CAMERA_HAL_INITIAL_FD;
+#ifdef HAVE_LIBV4L2
+ int libv4l2_fd = CAMERA_HAL_INITIAL_FD;
+#endif /* HAVE_LIBV4L2 */
+ vision_source_v4l2_s *v4l2_handle = (vision_source_v4l2_s *) handle;
+
+ g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&v4l2_handle->lock);
+
+ if (!v4l2_handle->device_info_list) {
+ LOGE("NO DEVICE INFO");
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ if (device_index >= v4l2_handle->device_info_list->count) {
+ LOGE("invalid index %d [info:%d]", device_index,
+ v4l2_handle->device_info_list->count);
+ return VISION_SOURCE_ERROR_INVALID_PARAMETER;
+ }
+
+ char *node_path =
+ v4l2_handle->device_info_list->device_info[device_index].node_path;
+
+ device_fd = open(node_path, O_RDWR);
+ if (device_fd < 0) {
+ LOGE("open [%s] failed [errno %d]", node_path, errno);
+ return VISION_SOURCE_ERROR_INTERNAL;
+ }
+
+ if (g_device_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE)
+ v4l2_handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE_MPLANE;
+ else
+ v4l2_handle->buffer_type = V4L2_CAP_VIDEO_CAPTURE;
+
+#ifdef HAVE_LIBV4L2
+ libv4l2_fd = v4l2_fd_open(device_fd, V4L2_ENABLE_ENUM_FMT_EMULATION);
+
+ LOGI("device_fd[%d], libv4l2_fd[%d]", device_fd, libv4l2_fd);
+
+ if (libv4l2_fd != CAMERA_HAL_INITIAL_FD)
+ device_fd = libv4l2_fd;
+#endif /* HAVE_LIBV4L2 */
+
+ v4l2_handle->device_index = device_index;
+ v4l2_handle->device_fd = device_fd;
+
+ LOGD("[%d] device[%s] opened [fd %d, type %d]", device_index, node_path,
+ device_fd, v4l2_handle->buffer_type);
+
+ return VISION_SOURCE_ERROR_NONE;
+}
+
+int vision_source_v4l2_close_device(vision_source_h handle)
+{
+ VISION_SOURCE_NULL_ARG_CHECK(handle);
+ vision_source_v4l2_s *v4l2_handle = (vision_source_v4l2_s *) handle;
+
+ g_autoptr(GMutexLocker) locker = g_mutex_locker_new(&v4l2_handle->lock);
+
+ int ret =
+ __vision_source_stop_stream(v4l2_handle, v4l2_handle->buffer_count);
+ if (ret != VISION_SOURCE_ERROR_NONE) {
+ LOGE("failed to stop stream");
+ return ret;
+ }
+
+ if (v4l2_handle->device_fd >= 0) {
+ LOGD("close fd %d", v4l2_handle->device_fd);
+
+ v4l2_close(v4l2_handle->device_fd);
+ v4l2_handle->device_fd = CAMERA_HAL_INITIAL_FD;
+ } else {
+ LOGW("invalid fd %d", v4l2_handle->device_fd);
+ }
+
+ LOGD("device [%d] closed", v4l2_handle->device_index);
+
return VISION_SOURCE_ERROR_NONE;
}
funcp->init = vision_source_v4l2_init;
funcp->exit = vision_source_v4l2_exit;
funcp->enumerate_devices = vision_source_v4l2_enumerate_devices;
+ funcp->open_device = vision_source_v4l2_open_device;
+ funcp->close_device = vision_source_v4l2_close_device;
}
\ No newline at end of file