workaround: Add libv4l2 dependency for compatibility 24/317624/1 accepted/tizen_unified_dev accepted/tizen_unified_toolchain accepted/tizen/9.0/unified/20241030.233706 accepted/tizen/unified/20240913.042634 accepted/tizen/unified/dev/20240919.040411 accepted/tizen/unified/toolchain/20241004.102039 accepted/tizen/unified/x/20240913.062836 accepted/tizen/unified/x/asan/20241014.000441 tizen_9.0_m2_release
authorJeongmo Yang <jm80.yang@samsung.com>
Thu, 12 Sep 2024 08:52:19 +0000 (17:52 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Thu, 12 Sep 2024 09:13:47 +0000 (18:13 +0900)
- The I420 format is needed for some TC,
  but it's not supported when libv4l2 dependency is removed with Logitech C920 webcam.
  So, libv4l2 dependency is added for temporary,
  and it will be removed later.

[Version] 1.3.2
[Issue Type] Compatibility

Change-Id: Ife16b7ac3fdec0ce9bc4aa32799bff438dbde738
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
configure.ac
packaging/hal-backend-camera-v4l2.spec
src/Makefile.am
src/hal_backend_camera_v4l2.c
src/hal_backend_camera_v4l2_private.h

index fe7779d5300d60056fb60d375e7cefb7c09ef03f..9bdd6e8923b9036188836eea6c4e333307d3c191 100644 (file)
@@ -23,9 +23,38 @@ AC_HEADER_TIME
 AC_PROG_GCC_TRADITIONAL
 AC_PROG_LIBTOOL
 
-PKG_CHECK_MODULES(HAL_ROOTSTRAP, hal-rootstrap)
-AC_SUBST(HAL_ROOTSTRAP_CFLAGS)
-AC_SUBST(HAL_ROOTSTRAP_LIBS)
+PKG_CHECK_MODULES(GLIB, glib-2.0)
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+PKG_CHECK_MODULES(TBM, libtbm)
+AC_SUBST(TBM_CFLAGS)
+AC_SUBST(TBM_LIBS)
+
+PKG_CHECK_MODULES(DLOG, dlog)
+AC_SUBST(DLOG_CFLAGS)
+AC_SUBST(DLOG_LIBS)
+
+PKG_CHECK_MODULES(HAL_API_COMMON, hal-api-common)
+AC_SUBST(HAL_API_COMMON_CFLAGS)
+
+PKG_CHECK_MODULES(HAL_API_CAMERA, hal-api-camera)
+AC_SUBST(HAL_API_CAMERA_CFLAGS)
+
+AC_ARG_ENABLE(libv4l2, AC_HELP_STRING([--enable-libv4l2], [enable libv4l2]),
+[
+  case "${enableval}" in
+    yes) HAVE_LIBV4L2=yes ;;
+    no)  HAVE_LIBV4L2=no ;;
+    *) AC_MSG_ERROR(bad value ${enableval} for --enable-libv4l2) ;;
+  esac
+],[HAVE_LIBV4L2=no])
+if test "x$HAVE_LIBV4L2" = "xyes"; then
+PKG_CHECK_MODULES(LIBV4L2, libv4l2)
+AC_SUBST(LIBV4L2_CFLAGS)
+AC_SUBST(LIBV4L2_LIBS)
+fi
+AM_CONDITIONAL([HAVE_LIBV4L2], [test "x$HAVE_LIBV4L2" = "xyes"])
 
 # Checks for header files.
 AC_HEADER_STDC
index d7ef1d3554b4caca3bc7098ce7678ca301f901b6..5f298f7db0f4809fd46b4043c82f3b2e2a4d537e 100644 (file)
@@ -1,13 +1,21 @@
+%define disable_hal_rootstrap_checker 1
 %define enable_zero_copy 0
 
 Name:       hal-backend-camera-v4l2
 Summary:    Tizen Camera Hal using generic V4L2 interface
-Version:    1.3.1
+Version:    1.3.2
 Release:    0
 Group:      Multimedia/Libraries
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
-BuildRequires:  pkgconfig(hal-rootstrap)
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(libtbm)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(hal-api-common)
+BuildRequires:  pkgconfig(hal-api-camera)
+BuildRequires:  pkgconfig(libv4l2)
 
 %description
 Tizen Camera Hal using generic V4L2 interface.
@@ -23,6 +31,7 @@ export CFLAGS+=" -DTIZEN_FEATURE_ZERO_COPY_SUPPORT"
 %endif
 ./autogen.sh
 %configure \
+       --enable-libv4l2\
        --disable-static\
        --libdir=%{_hal_libdir}
 make %{?jobs:-j%jobs}
index ca120853dccf79e0beab9cd05d592844001ea8e6..76ed725b49b7b67e4bff6e287215db0c09c693a5 100644 (file)
@@ -8,10 +8,21 @@ libhal_backend_camera_la_SOURCES = hal_backend_camera_v4l2.c
 
 libhal_backend_camera_la_CFLAGS = \
        -I$(srcdir)/include \
-       $(HAL_ROOTSTRAP_CFLAGS)
+       $(GLIB_CFLAGS) \
+       $(DLOG_CFLAGS) \
+       $(HAL_API_COMMON_CFLAGS) \
+       $(HAL_API_CAMERA_CFLAGS) \
+       $(TBM_CFLAGS)
 
 libhal_backend_camera_la_LIBADD = \
-       $(HAL_ROOTSTRAP_LIBS)
+       $(GLIB_LIBS) \
+       $(DLOG_LIBS) \
+       $(TBM_LIBS)
+
+if HAVE_LIBV4L2
+libhal_backend_camera_la_CFLAGS += $(LIBV4L2_CFLAGS) -DHAVE_LIBV4L2
+libhal_backend_camera_la_LIBADD += $(LIBV4L2_LIBS)
+endif
 
 libhal_backend_camera_la_CFLAGS += -fdata-sections -ffunction-sections -Wl,--gc-sections
 libhal_backend_camera_la_LDFLAGS = -Wl,--gc-sections -avoid-version
index fa407e8e419d063db5c3be4457eaa280a49ab275..e178c40cd8d42bb7345f9a53bb93c2e7887150ea 100644 (file)
 #endif /* LOG_TAG */
 #define LOG_TAG "CAMERA_HAL"
 
-#ifndef LOGV
-#define LOGV(fmt, arg...) dlog_print(DLOG_VERBOSE, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
-#endif
-#ifndef LOGD
-#define LOGD(fmt, arg...) dlog_print(DLOG_DEBUG, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
-#endif
-#ifndef LOGI
-#define LOGI(fmt, arg...) dlog_print(DLOG_INFO, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
-#endif
-#ifndef LOGW
-#define LOGW(fmt, arg...) dlog_print(DLOG_WARN, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
-#endif
-#ifndef LOGE
-#define LOGE(fmt, arg...) dlog_print(DLOG_ERROR, LOG_TAG, "%s (%d) %s : " fmt, __FILE__, __LINE__, __FUNCTION__, ##arg)
-#endif
-
 #define ENV_VIRTUAL_CAMERA      "VIRTUAL_CAMERA"
 #define VIRTUAL_CAMERA_FMT_MAX  2
 #define VIRTUAL_CAMERA_RES_MAX  3
@@ -349,7 +333,7 @@ static int __camera_v4l2_g_ctrl(int device_fd, int cid, int *value)
        ctrl.id = cid;
 
        if (!g_is_virtual_camera_mode)
-               ret = ioctl(device_fd, VIDIOC_G_CTRL, &ctrl);
+               ret = v4l2_ioctl(device_fd, VIDIOC_G_CTRL, &ctrl);
 
        if (ret == 0)
                *value = ctrl.value;
@@ -371,7 +355,7 @@ static int __camera_v4l2_s_ctrl(int device_fd, int cid, int value)
        ctrl.value = value;
 
        if (!g_is_virtual_camera_mode)
-               ret = ioctl(device_fd, VIDIOC_S_CTRL, &ctrl);
+               ret = v4l2_ioctl(device_fd, VIDIOC_S_CTRL, &ctrl);
 
        LOGD("S_CTRL id 0x%x, value %d, ret %d", cid, value, ret);
 
@@ -387,7 +371,7 @@ static int __camera_v4l2_stream(int device_fd, int type, gboolean onoff)
        }
 
        if (!g_is_virtual_camera_mode) {
-               if (ioctl(device_fd, onoff ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type) < 0) {
+               if (v4l2_ioctl(device_fd, onoff ? VIDIOC_STREAMON : VIDIOC_STREAMOFF, &type) < 0) {
                        LOGE("stream %d failed. [t:%d] errno %d", onoff, type, errno);
                        return CAMERA_ERROR_INTERNAL;
                }
@@ -422,7 +406,7 @@ static int __camera_v4l2_reqbufs(int device_fd, int type, int memory, uint32_t c
        v4l2_reqbuf.count = count;
 
        if (!g_is_virtual_camera_mode) {
-               if (ioctl(device_fd, VIDIOC_REQBUFS, &v4l2_reqbuf) < 0) {
+               if (v4l2_ioctl(device_fd, VIDIOC_REQBUFS, &v4l2_reqbuf) < 0) {
                        LOGE("REQBUFS[count %d] failed. errno %d", count, errno);
                        return CAMERA_ERROR_INTERNAL;
                }
@@ -463,7 +447,7 @@ static int __camera_v4l2_qbuf(int device_fd, int type, int memory, int index, in
        }
 
        if (!g_is_virtual_camera_mode) {
-               if (ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) {
+               if (v4l2_ioctl(device_fd, VIDIOC_QBUF, &v4l2_buf) < 0) {
                        LOGE("qbuf failed.  [i: %d, t: %d, m: %d] errno %d",
                                index, type, memory, errno);
                        return CAMERA_ERROR_INTERNAL;
@@ -502,7 +486,7 @@ static int __camera_v4l2_dqbuf(int device_fd, int type, int memory, int *index,
        v4l2_buf.m.planes = v4l2_planes;
 
        if (!g_is_virtual_camera_mode) {
-               ret = ioctl(device_fd, VIDIOC_DQBUF, &v4l2_buf);
+               ret = v4l2_ioctl(device_fd, VIDIOC_DQBUF, &v4l2_buf);
                if (ret < 0) {
                        LOGE("dqbuf failed. [t: %d, m: %d] errno %d",
                                type, memory, errno);
@@ -657,7 +641,7 @@ static void __camera_get_fps_list(int device_fd, guint32 pixel_format, int width
        ival.width = width;
        ival.height = height;
 
-       while (ioctl(device_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0) {
+       while (v4l2_ioctl(device_fd, VIDIOC_ENUM_FRAMEINTERVALS, &ival) >= 0) {
                if (ival.type != V4L2_FRMIVAL_TYPE_DISCRETE) {
                        LOGE("NOT DISCRETE type[%u] for [%dx%d]", ival.type, width, height);
                        return;
@@ -753,7 +737,7 @@ static int __camera_get_device_info(int device_index, int device_fd, char *node_
                v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
                if (!g_is_virtual_camera_mode) {
-                       if (ioctl(device_fd, VIDIOC_ENUM_FMT, &v4l2_format) < 0) {
+                       if (v4l2_ioctl(device_fd, VIDIOC_ENUM_FMT, &v4l2_format) < 0) {
                                LOGW("\tformat : end of enumeration");
                                break;
                        }
@@ -788,7 +772,7 @@ static int __camera_get_device_info(int device_index, int device_fd, char *node_
                        v4l2_frame.pixel_format = v4l2_format.pixelformat;
 
                        if (!g_is_virtual_camera_mode) {
-                               if (ioctl(device_fd, VIDIOC_ENUM_FRAMESIZES, &v4l2_frame) < 0) {
+                               if (v4l2_ioctl(device_fd, VIDIOC_ENUM_FRAMESIZES, &v4l2_frame) < 0) {
                                        LOGW("\t\tframesize : end of enumeration");
                                        break;
                                }
@@ -943,6 +927,9 @@ static int __camera_get_device_info_list(void)
        int ret = CAMERA_ERROR_NONE;
        int device_count = 0;
        int device_fd = CAMERA_HAL_INITIAL_FD;
+#ifdef HAVE_LIBV4L2
+       int libv4l2_fd = CAMERA_HAL_INITIAL_FD;
+#endif /* HAVE_LIBV4L2 */
        glob_t glob_buf;
        struct v4l2_capability v4l2_cap;
        guint32 device_caps;
@@ -1020,11 +1007,20 @@ static int __camera_get_device_info_list(void)
                        continue;
                }
 
+#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 */
+
                memset(&v4l2_cap, 0x0, sizeof(struct v4l2_capability));
 
-               if (ioctl(device_fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0) {
+               if (v4l2_ioctl(device_fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0) {
                        LOGE("querycap failed. errno %d", errno);
-                       close(device_fd);
+                       v4l2_close(device_fd);
                        continue;
                }
 
@@ -1039,7 +1035,7 @@ static int __camera_get_device_info_list(void)
                if (!(device_caps & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE)) ||
                        (device_caps & (V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE))) {
                        LOGW("[%s] is not a capture device 0x%x", glob_buf.gl_pathv[i], device_caps);
-                       close(device_fd);
+                       v4l2_close(device_fd);
                        continue;
                }
 
@@ -1048,7 +1044,7 @@ static int __camera_get_device_info_list(void)
                        &device_info_list->device_info[device_count],
                        &device_capability_list->capability[device_count]);
 
-               close(device_fd);
+               v4l2_close(device_fd);
 
                if (ret == CAMERA_ERROR_NONE && device_capability_list->capability[device_count]) {
                        g_device_caps[device_count] = device_caps;
@@ -1133,7 +1129,7 @@ static int __camera_stop_stream(hal_camera_handle *handle, uint32_t buffer_count
                if (buffer->planes[0].data) {
 #ifndef TIZEN_FEATURE_ZERO_COPY_SUPPORT
                        LOGI("  munmap %p", buffer->planes[0].data);
-                       munmap(buffer->planes[0].data, buffer->planes[0].size);
+                       v4l2_munmap(buffer->planes[0].data, buffer->planes[0].size);
 #endif
                        buffer->planes[0].data = NULL;
                        buffer->planes[0].size = 0;
@@ -1200,7 +1196,7 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_
        }
 
        if (!g_is_virtual_camera_mode) {
-               if (ioctl(handle->device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
+               if (v4l2_ioctl(handle->device_fd, VIDIOC_S_FMT, &v4l2_fmt) < 0) {
                        LOGE("S_FMT failed. errno %d", errno);
                        return CAMERA_ERROR_INTERNAL;
                }
@@ -1240,7 +1236,7 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_
        v4l2_parm.type = handle->buffer_type;
 
        if (!g_is_virtual_camera_mode) {
-               if (ioctl(handle->device_fd, VIDIOC_G_PARM, &v4l2_parm) < 0) {
+               if (v4l2_ioctl(handle->device_fd, VIDIOC_G_PARM, &v4l2_parm) < 0) {
                        LOGE("G_PARM failed. errno %d", errno);
                        return CAMERA_ERROR_INTERNAL;
                }
@@ -1251,7 +1247,7 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_
        v4l2_parm.parm.capture.timeperframe.denominator = fps;
 
        if (!g_is_virtual_camera_mode) {
-               if (ioctl(handle->device_fd, VIDIOC_S_PARM, &v4l2_parm) < 0) {
+               if (v4l2_ioctl(handle->device_fd, VIDIOC_S_PARM, &v4l2_parm) < 0) {
                        LOGE("S_PARM failed. errno %d", errno);
                        return CAMERA_ERROR_INTERNAL;
                }
@@ -1325,7 +1321,7 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_
                v4l2_buf.m.planes = v4l2_planes;
                v4l2_buf.length = plane_num;
 
-               if (ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
+               if (v4l2_ioctl(handle->device_fd, VIDIOC_QUERYBUF, &v4l2_buf) < 0) {
                        LOGE("[%d] query buf failed. errno %d", i, errno);
                        ret = CAMERA_ERROR_INTERNAL;
                        goto _START_STREAM_FAILED;
@@ -1338,7 +1334,7 @@ static int __camera_start_stream(hal_camera_handle *handle, camera_pixel_format_
                buffer->total_size = v4l2_buf.length;
                buffer->num_planes = plane_num;
                buffer->planes[0].size = v4l2_buf.length;
-               buffer->planes[0].data = mmap(0,
+               buffer->planes[0].data = v4l2_mmap(0,
                        v4l2_buf.length,
                        PROT_READ | PROT_WRITE,
                        MAP_SHARED,
@@ -1836,6 +1832,12 @@ int camera_v4l2_init(void **camera_handle)
        for (i = 0 ; i < BUFFER_MAX ; i++)
                new_handle->tbm_buffers[i].dmabuf_fd = CAMERA_HAL_INITIAL_FD;
 
+#ifdef HAVE_LIBV4L2
+       LOGI("libv4l2 ENABLED");
+#else /* HAVE_LIBV4L2 */
+       LOGI("libv4l2 DISABLED");
+#endif /* HAVE_LIBV4L2 */
+
        *camera_handle = new_handle;
 
        LOGD("camera HAL handle %p", new_handle);
@@ -1899,6 +1901,9 @@ int camera_v4l2_open_device(void *camera_handle, int device_index)
 {
        int ret = CAMERA_ERROR_NONE;
        int device_fd = CAMERA_HAL_INITIAL_FD;
+#ifdef HAVE_LIBV4L2
+       int libv4l2_fd = CAMERA_HAL_INITIAL_FD;
+#endif /* HAVE_LIBV4L2 */
        char *node_path = NULL;
        hal_camera_handle *handle = (hal_camera_handle *)camera_handle;
 
@@ -1971,6 +1976,15 @@ int camera_v4l2_open_device(void *camera_handle, int device_index)
        handle->memory_type = V4L2_MEMORY_MMAP;
 #endif
 
+#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 */
+
 _OPEN_DEVICE_DONE:
        handle->state = CAMERA_STATE_OPENED;
        handle->device_index = device_index;
@@ -2013,7 +2027,7 @@ int camera_v4l2_close_device(void *camera_handle)
        if (!g_is_virtual_camera_mode) {
                if (handle->device_fd >= 0) {
                        LOGD("close fd %d", handle->device_fd);
-                       close(handle->device_fd);
+                       v4l2_close(handle->device_fd);
                        handle->device_fd = CAMERA_HAL_INITIAL_FD;
                } else {
                        LOGW("invalid fd %d", handle->device_fd);
@@ -3088,27 +3102,6 @@ int camera_v4l2_set_batch_command(void *camera_handle, camera_batch_command_cont
 }
 
 
-int camera_v4l2_get_device_capability_list(camera_device_capability_list_s *device_capability_list)
-{
-       int ret = 0;
-
-       if (!device_capability_list) {
-               LOGE("NULL pointer for device_capability_list");
-               return CAMERA_ERROR_INVALID_PARAMETER;
-       }
-
-       ret = __camera_get_device_info_list();
-       if (ret != CAMERA_ERROR_NONE) {
-               LOGE("get device info failed");
-               return ret;
-       }
-
-       memcpy(device_capability_list, g_device_capability_list, sizeof(camera_device_capability_list_s));
-
-       return CAMERA_ERROR_NONE;
-}
-
-
 static int camera_v4l2_backend_init(void **data)
 {
        hal_backend_camera_funcs *funcs = NULL;
@@ -3175,7 +3168,6 @@ static int camera_v4l2_backend_init(void **data)
        funcs->get_extra_preview_bitrate = camera_v4l2_get_extra_preview_bitrate;
        funcs->set_extra_preview_gop_interval = camera_v4l2_set_extra_preview_gop_interval;
        funcs->get_extra_preview_gop_interval = camera_v4l2_get_extra_preview_gop_interval;
-       funcs->get_device_capability_list = camera_v4l2_get_device_capability_list;
 
        g_is_virtual_camera_mode = getenv(ENV_VIRTUAL_CAMERA) ? TRUE : FALSE;
 
index 845e7926aa41afa083e3afdcf8d8b0357dfd8332..ac49c77b2b7f842f614a8913e6d948c7b68879b8 100644 (file)
 #include <hal/hal-common-interface.h>
 #include <hal/hal-camera-interface.h>
 
+#ifdef HAVE_LIBV4L2
+#include <libv4l2.h>
+#else
+#define v4l2_fd_open(fd, flags) (fd)
+#define v4l2_close              close
+#define v4l2_dup                dup
+#define v4l2_ioctl              ioctl
+#define v4l2_read               read
+#define v4l2_mmap               mmap
+#define v4l2_munmap             munmap
+#endif /* ENABLE_LIBV4L2 */
+
 #define CAMERA_HAL_INITIAL_INDEX    -1
 #define CAMERA_HAL_INITIAL_FD       -1
 #define MESSAGE_CALLBACK_MAX        10