Add libuvc on macOS
This commit is contained in:
parent
50936ae612
commit
b81299cfa1
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
_build/
|
_build/
|
||||||
|
_install/
|
||||||
_output/
|
_output/
|
||||||
|
|
||||||
/doc/output/
|
/doc/output/
|
||||||
|
|
111
CMakeLists.txt
111
CMakeLists.txt
|
@ -27,6 +27,8 @@ message(STATUS "Found glog: ${glog_VERSION}")
|
||||||
|
|
||||||
LIST(APPEND CMAKE_MODULE_PATH cmake)
|
LIST(APPEND CMAKE_MODULE_PATH cmake)
|
||||||
|
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
# config
|
# config
|
||||||
|
|
||||||
set(MYNTEYE_NAMESPACE "mynteye")
|
set(MYNTEYE_NAMESPACE "mynteye")
|
||||||
|
@ -41,17 +43,116 @@ configure_file(
|
||||||
|
|
||||||
include(cmake/Common.cmake)
|
include(cmake/Common.cmake)
|
||||||
|
|
||||||
set(OUT_DIR "${PROJECT_SOURCE_DIR}/_output")
|
set(OUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/_output")
|
||||||
set_outdir(
|
set_outdir(
|
||||||
"${OUT_DIR}/lib"
|
"${OUT_DIR}/lib"
|
||||||
"${OUT_DIR}/lib"
|
"${OUT_DIR}/lib"
|
||||||
"${OUT_DIR}/bin"
|
"${OUT_DIR}/bin"
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
set(MYNTEYE_CMAKE_INCLUDE_DIR "${CMAKE_INSTALL_PREFIX}/include")
|
||||||
include
|
set(MYNTEYE_CMAKE_BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
|
||||||
${CMAKE_BINARY_DIR}/include
|
set(MYNTEYE_CMAKE_LIBDIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||||
)
|
set(MYNTEYE_CMAKE_INSTALLDIR "${MYNTEYE_CMAKE_LIBDIR}/cmake/${MYNTEYE_NAME}")
|
||||||
|
|
||||||
|
## main
|
||||||
|
|
||||||
add_executable(main src/main.cc)
|
add_executable(main src/main.cc)
|
||||||
target_link_libraries(main glog::glog)
|
target_link_libraries(main glog::glog)
|
||||||
|
target_include_directories(main PRIVATE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
## libmynteye
|
||||||
|
|
||||||
|
set(MYNTEYE_NAME ${PROJECT_NAME})
|
||||||
|
|
||||||
|
set(MYNTEYE_PUBLIC_H
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/include/mynteye/global.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/include/mynteye/mynteye.h
|
||||||
|
)
|
||||||
|
|
||||||
|
if(OS_WIN)
|
||||||
|
set(UVC_SRC src/uvc/uvc-wmf.cc)
|
||||||
|
elseif(OS_MAC)
|
||||||
|
set(UVC_SRC src/uvc/uvc-libuvc.cc)
|
||||||
|
|
||||||
|
find_package(libuvc REQUIRED)
|
||||||
|
set(UVC_LIB ${libuvc_LIBRARIES})
|
||||||
|
|
||||||
|
include_directories(${libuvc_INCLUDE_DIRS})
|
||||||
|
elseif(OS_LINUX)
|
||||||
|
set(UVC_SRC src/uvc/uvc-v4l2.cc)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported OS.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(MYNTEYE_SRCS
|
||||||
|
${UVC_SRC}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(MYNTEYE_LINKLIBS
|
||||||
|
glog::glog
|
||||||
|
${UVC_LIB}
|
||||||
|
)
|
||||||
|
#message(STATUS "MYNTEYE_LINKLIBS: ${MYNTEYE_LINKLIBS}")
|
||||||
|
|
||||||
|
add_library(${MYNTEYE_NAME} SHARED ${MYNTEYE_SRCS})
|
||||||
|
target_link_libraries(${MYNTEYE_NAME} ${MYNTEYE_LINKLIBS})
|
||||||
|
|
||||||
|
if(OS_WIN)
|
||||||
|
target_compile_definitions(${MYNTEYE_NAME}
|
||||||
|
PUBLIC GLOG_NO_ABBREVIATED_SEVERITIES
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(${MYNTEYE_NAME} PUBLIC
|
||||||
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||||
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
||||||
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
|
||||||
|
"$<INSTALL_INTERFACE:${MYNTEYE_CMAKE_INCLUDE_DIR}>"
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(${MYNTEYE_NAME} PROPERTIES
|
||||||
|
VERSION ${PROJECT_VERSION}
|
||||||
|
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||||
|
)
|
||||||
|
set_target_properties(${MYNTEYE_NAME} PROPERTIES
|
||||||
|
PUBLIC_HEADER "${MYNTEYE_PUBLIC_H}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# install
|
||||||
|
|
||||||
|
#message(STATUS "MYNTEYE_CMAKE_INCLUDE_DIR: ${MYNTEYE_CMAKE_INCLUDE_DIR}")
|
||||||
|
#message(STATUS "MYNTEYE_CMAKE_BINDIR: ${MYNTEYE_CMAKE_BINDIR}")
|
||||||
|
#message(STATUS "MYNTEYE_CMAKE_LIBDIR: ${MYNTEYE_CMAKE_LIBDIR}")
|
||||||
|
#message(STATUS "MYNTEYE_CMAKE_INSTALLDIR: ${MYNTEYE_CMAKE_INSTALLDIR}")
|
||||||
|
|
||||||
|
install(TARGETS ${MYNTEYE_NAME}
|
||||||
|
EXPORT ${MYNTEYE_NAME}-targets
|
||||||
|
PUBLIC_HEADER DESTINATION ${MYNTEYE_CMAKE_INCLUDE_DIR}/${MYNTEYE_NAME}
|
||||||
|
RUNTIME DESTINATION ${MYNTEYE_CMAKE_BINDIR}
|
||||||
|
LIBRARY DESTINATION ${MYNTEYE_CMAKE_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${MYNTEYE_CMAKE_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_package_config_file(mynteye-config.cmake.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/mynteye-config.cmake
|
||||||
|
INSTALL_DESTINATION ${MYNTEYE_CMAKE_INSTALLDIR}
|
||||||
|
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||||
|
)
|
||||||
|
|
||||||
|
write_basic_package_version_file(mynteye-config-version.cmake
|
||||||
|
VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/mynteye-config.cmake
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/mynteye-config-version.cmake
|
||||||
|
DESTINATION ${MYNTEYE_CMAKE_INSTALLDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(EXPORT ${MYNTEYE_NAME}-targets
|
||||||
|
DESTINATION ${MYNTEYE_CMAKE_INSTALLDIR}
|
||||||
|
)
|
||||||
|
|
|
@ -150,6 +150,7 @@ ifneq ($(MAKE),)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CMAKE_OPTIONS :=
|
CMAKE_OPTIONS :=
|
||||||
|
CMAKE_OPTIONS += -DCMAKE_INSTALL_PREFIX=$(shell pwd)/_install
|
||||||
# CMAKE_OPTIONS += -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
|
# CMAKE_OPTIONS += -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
|
||||||
CMAKE_OPTIONS_AFTER :=
|
CMAKE_OPTIONS_AFTER :=
|
||||||
|
|
||||||
|
|
28
Makefile
28
Makefile
|
@ -10,6 +10,7 @@ help:
|
||||||
@echo " make init init project"
|
@echo " make init init project"
|
||||||
@echo " make build build project"
|
@echo " make build build project"
|
||||||
@echo " make test build test and run"
|
@echo " make test build test and run"
|
||||||
|
@echo " make install install project"
|
||||||
@echo " make clean|cleanall clean generated or useless things"
|
@echo " make clean|cleanall clean generated or useless things"
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
|
@ -30,14 +31,6 @@ opendoc: apidoc
|
||||||
|
|
||||||
.PHONY: apidoc opendoc
|
.PHONY: apidoc opendoc
|
||||||
|
|
||||||
# init
|
|
||||||
|
|
||||||
init:
|
|
||||||
@$(call echo,Make $@)
|
|
||||||
@$(SH) ./scripts/init.sh
|
|
||||||
|
|
||||||
.PHONY: init
|
|
||||||
|
|
||||||
# deps
|
# deps
|
||||||
|
|
||||||
submodules:
|
submodules:
|
||||||
|
@ -50,6 +43,14 @@ third_party: submodules
|
||||||
|
|
||||||
.PHONY: submodules third_party
|
.PHONY: submodules third_party
|
||||||
|
|
||||||
|
# init
|
||||||
|
|
||||||
|
init: submodules
|
||||||
|
@$(call echo,Make $@)
|
||||||
|
@$(SH) ./scripts/init.sh
|
||||||
|
|
||||||
|
.PHONY: init
|
||||||
|
|
||||||
# build
|
# build
|
||||||
|
|
||||||
build: third_party
|
build: third_party
|
||||||
|
@ -67,12 +68,21 @@ test: submodules
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
|
|
||||||
|
# install
|
||||||
|
|
||||||
|
install: build
|
||||||
|
@$(call echo,Make $@)
|
||||||
|
@cd ./_build; make install
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
|
||||||
# clean
|
# clean
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@$(call echo,Make $@)
|
@$(call echo,Make $@)
|
||||||
@$(call rm,./_build/)
|
@$(call rm,./_build/)
|
||||||
@$(call rm,./_output/)
|
@$(call rm,./_output/)
|
||||||
|
@$(call rm,./_install/)
|
||||||
@$(MAKE) cleanlog
|
@$(MAKE) cleanlog
|
||||||
|
|
||||||
cleanall: clean
|
cleanall: clean
|
||||||
|
@ -107,7 +117,7 @@ host:
|
||||||
|
|
||||||
.PHONY: host
|
.PHONY: host
|
||||||
|
|
||||||
cpplint:
|
cpplint: submodules
|
||||||
@$(call echo,Make $@)
|
@$(call echo,Make $@)
|
||||||
@$(SH) ./scripts/$@.sh
|
@$(SH) ./scripts/$@.sh
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
include(CMakeParseArguments)
|
include(CMakeParseArguments)
|
||||||
|
|
||||||
|
if(MSVC OR MSYS OR MINGW)
|
||||||
|
set(OS_WIN TRUE)
|
||||||
|
elseif(APPLE)
|
||||||
|
set(OS_MAC TRUE)
|
||||||
|
elseif(UNIX)
|
||||||
|
set(OS_LINUX TRUE)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported OS.")
|
||||||
|
endif()
|
||||||
|
|
||||||
# set_outdir(ARCHIVE_OUTPUT_DIRECTORY
|
# set_outdir(ARCHIVE_OUTPUT_DIRECTORY
|
||||||
# LIBRARY_OUTPUT_DIRECTORY
|
# LIBRARY_OUTPUT_DIRECTORY
|
||||||
# RUNTIME_OUTPUT_DIRECTORY)
|
# RUNTIME_OUTPUT_DIRECTORY)
|
||||||
|
|
|
@ -66,6 +66,8 @@
|
||||||
Class(const Class &) = delete; \
|
Class(const Class &) = delete; \
|
||||||
Class &operator=(const Class &) = delete;
|
Class &operator=(const Class &) = delete;
|
||||||
|
|
||||||
|
#define UNUSED(x) (void)x;
|
||||||
|
|
||||||
template <typename... T>
|
template <typename... T>
|
||||||
void unused(T &&...) {}
|
void unused(T &&...) {}
|
||||||
|
|
||||||
|
|
3
mynteye-config.cmake.in
Normal file
3
mynteye-config.cmake.in
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/mynteye-targets.cmake")
|
|
@ -18,6 +18,16 @@ fi
|
||||||
_detect curl
|
_detect curl
|
||||||
_detect $PYTHON
|
_detect $PYTHON
|
||||||
|
|
||||||
|
if [ "$HOST_OS" = "Mac" ]; then
|
||||||
|
_detect_install() {
|
||||||
|
brew ls --versions "$1" > /dev/null
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_detect_install() {
|
||||||
|
_detect_cmd "$1"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
_install_deps() {
|
_install_deps() {
|
||||||
_cmd="$1"; shift; _deps_all=($@)
|
_cmd="$1"; shift; _deps_all=($@)
|
||||||
_echo "Install cmd: $_cmd"
|
_echo "Install cmd: $_cmd"
|
||||||
|
@ -29,7 +39,7 @@ _install_deps() {
|
||||||
fi
|
fi
|
||||||
_deps=()
|
_deps=()
|
||||||
for _dep in "${_deps_all[@]}"; do
|
for _dep in "${_deps_all[@]}"; do
|
||||||
_detect_cmd $_dep || _deps+=($_dep)
|
_detect_install $_dep || _deps+=($_dep)
|
||||||
done
|
done
|
||||||
if [ ${#_deps[@]} -eq 0 ]; then
|
if [ ${#_deps[@]} -eq 0 ]; then
|
||||||
_echo_i "All deps already exist"
|
_echo_i "All deps already exist"
|
||||||
|
@ -62,6 +72,7 @@ elif [ "$HOST_OS" = "Mac" ]; then
|
||||||
# link clang-format-diff (if not compatible with Python 3, fix it by yourself)
|
# link clang-format-diff (if not compatible with Python 3, fix it by yourself)
|
||||||
[ -f "/usr/local/bin/clang-format-diff" ] || \
|
[ -f "/usr/local/bin/clang-format-diff" ] || \
|
||||||
ln -s /usr/local/share/clang/clang-format-diff.py /usr/local/bin/clang-format-diff
|
ln -s /usr/local/share/clang/clang-format-diff.py /usr/local/bin/clang-format-diff
|
||||||
|
_install_deps "brew install" libuvc
|
||||||
elif [ "$HOST_OS" = "Win" ]; then
|
elif [ "$HOST_OS" = "Win" ]; then
|
||||||
# detect pacman on MSYS
|
# detect pacman on MSYS
|
||||||
_detect pacman
|
_detect pacman
|
||||||
|
|
102
src/uvc/uvc-libuvc.cc
Normal file
102
src/uvc/uvc-libuvc.cc
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
#include "uvc.h" // NOLINT
|
||||||
|
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include <libuvc/libuvc.h>
|
||||||
|
|
||||||
|
// #define ENABLE_DEBUG_SPAM
|
||||||
|
|
||||||
|
MYNTEYE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace uvc {
|
||||||
|
|
||||||
|
static void check(const char *call, uvc_error_t status) {
|
||||||
|
LOG_IF(FATAL, status < 0)
|
||||||
|
<< call << "(...) returned " << uvc_strerror(status);
|
||||||
|
}
|
||||||
|
#define CALL_UVC(name, ...) check(#name, name(__VA_ARGS__))
|
||||||
|
|
||||||
|
struct context {
|
||||||
|
uvc_context_t *ctx;
|
||||||
|
|
||||||
|
context() : ctx() {
|
||||||
|
CALL_UVC(uvc_init, &ctx, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
~context() {
|
||||||
|
if (ctx)
|
||||||
|
uvc_exit(ctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct device {
|
||||||
|
const std::shared_ptr<context> parent;
|
||||||
|
|
||||||
|
uvc_device_t *uvcdevice;
|
||||||
|
uvc_device_handle_t *handle = nullptr;
|
||||||
|
|
||||||
|
int vid, pid;
|
||||||
|
|
||||||
|
// uvc_stream_ctrl_t ctrl;
|
||||||
|
// uint8_t unit;
|
||||||
|
// video_channel_callback callback = nullptr;
|
||||||
|
|
||||||
|
device(std::shared_ptr<context> parent, uvc_device_t *uvcdevice)
|
||||||
|
: parent(parent), uvcdevice(uvcdevice) {
|
||||||
|
open();
|
||||||
|
|
||||||
|
uvc_device_descriptor_t *desc;
|
||||||
|
CALL_UVC(uvc_get_device_descriptor, uvcdevice, &desc);
|
||||||
|
vid = desc->idVendor;
|
||||||
|
pid = desc->idProduct;
|
||||||
|
uvc_free_device_descriptor(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
~device() {
|
||||||
|
if (handle)
|
||||||
|
uvc_close(handle);
|
||||||
|
if (uvcdevice)
|
||||||
|
uvc_unref_device(uvcdevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
void open() {
|
||||||
|
if (!handle)
|
||||||
|
CALL_UVC(uvc_open, uvcdevice, &handle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<context> create_context() {
|
||||||
|
return std::make_shared<context>();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<device>> query_devices(
|
||||||
|
std::shared_ptr<context> context) {
|
||||||
|
std::vector<std::shared_ptr<device>> devices;
|
||||||
|
|
||||||
|
uvc_device_t **list;
|
||||||
|
CALL_UVC(uvc_get_device_list, context->ctx, &list);
|
||||||
|
for (auto it = list; *it; ++it) {
|
||||||
|
try {
|
||||||
|
auto dev = std::make_shared<device>(context, *it);
|
||||||
|
devices.push_back(dev);
|
||||||
|
} catch (std::runtime_error &e) {
|
||||||
|
LOG(WARNING) << "usb:" << static_cast<int>(uvc_get_bus_number(*it)) << ':'
|
||||||
|
<< static_cast<int>(uvc_get_device_address(*it)) << ": "
|
||||||
|
<< e.what();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uvc_free_device_list(list, 1);
|
||||||
|
|
||||||
|
return devices;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_vendor_id(const device &device) {
|
||||||
|
return device.vid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_product_id(const device &device) {
|
||||||
|
return device.pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace uvc
|
||||||
|
|
||||||
|
MYNTEYE_END_NAMESPACE
|
34
src/uvc/uvc.h
Normal file
34
src/uvc/uvc.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef MYNTEYE_UVC_H_ // NOLINT
|
||||||
|
#define MYNTEYE_UVC_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "mynteye/mynteye.h"
|
||||||
|
|
||||||
|
#define MYNTEYE_VID 0x04B4
|
||||||
|
#define MYNTEYE_PID 0x00F9
|
||||||
|
|
||||||
|
MYNTEYE_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
namespace uvc {
|
||||||
|
|
||||||
|
struct context; // Opaque type representing access to the underlying UVC
|
||||||
|
// implementation
|
||||||
|
struct device; // Opaque type representing access to a specific UVC device
|
||||||
|
|
||||||
|
// Enumerate devices
|
||||||
|
std::shared_ptr<context> create_context();
|
||||||
|
std::vector<std::shared_ptr<device>> query_devices(
|
||||||
|
std::shared_ptr<context> context);
|
||||||
|
|
||||||
|
// Static device properties
|
||||||
|
int get_vendor_id(const device &device);
|
||||||
|
int get_product_id(const device &device);
|
||||||
|
|
||||||
|
} // namespace uvc
|
||||||
|
|
||||||
|
MYNTEYE_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // MYNTEYE_UVC_H_ NOLINT
|
Loading…
Reference in New Issue
Block a user