Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
7791521
add camera parsing from cli to library
zhexiushen Sep 12, 2025
cbd1bd1
fix: ownership of io context in websocket client
zhexiushen Oct 16, 2025
26e484a
loop record default to false
zhexiushen Oct 16, 2025
627fe85
Version 0.1.1
zhexiushen Oct 16, 2025
4e75d24
ci: use self-built gstreamer
zhexiushen Oct 28, 2025
bc13104
ci: install build tools first
zhexiushen Oct 28, 2025
069ff19
ci: split clone and install of xdaqmetadata
zhexiushen Oct 28, 2025
517c9bd
ci: add windows build
zhexiushen Nov 5, 2025
9181923
ci: clone xdaqmetadata with bash shell
zhexiushen Nov 5, 2025
e5a3f95
Configure known hosts for GitHub on Windows
zhexiushen Nov 5, 2025
c07cbc2
ci: use bash to ssh-keyscan and clone repo
zhexiushen Nov 5, 2025
f72ace9
ci: setup compiler
zhexiushen Nov 6, 2025
64f703b
ci: install pkg-config on Windows
zhexiushen Nov 6, 2025
6ca77b2
Upgrade dep xdaqmetadata to 0.1.1
zhexiushen Dec 3, 2025
ff5199e
ci: install xdaqmetadata via conan index
zhexiushen Dec 3, 2025
63ceed4
ci: fix install xdaqmetadata with no conan profile found
zhexiushen Dec 3, 2025
cf5daaf
ci: update install conan index
zhexiushen Dec 3, 2025
8f396bf
Update build.yml
zhexiushen Dec 9, 2025
e33e1a6
Remove video/x-raw parsing
zhexiushen Dec 10, 2025
f9a27e7
Bump version into 0.1.2
zhexiushen Dec 10, 2025
00b653d
add parsing device id of camera
zhexiushen Dec 30, 2025
ad6f3f9
Bump version into v0.2.0
zhexiushen Dec 30, 2025
e282b1d
fix: occasional crash when stopping recording
zhexiushen Jan 19, 2026
8dc01a8
Bump version to 0.2.1
zhexiushen Jan 19, 2026
4b96e17
Update start_jpeg_recording API
zhexiushen Feb 11, 2026
712349c
Bump version to 0.3.0
zhexiushen Feb 11, 2026
0c3d5ee
fix: upgrade xdaqmetadata version
zhexiushen Feb 11, 2026
d48671d
fix: not expose json schema validator library
zhexiushen Feb 11, 2026
38c4328
add: h265 media type is now available
Apr 21, 2026
259f84b
Update:
Mar 25, 2026
57ac39a
Add: export_release_debug.bat script
Mar 26, 2026
a2eab60
fix: typo on script name
Mar 31, 2026
c5db897
Update start_jpeg_recording API
zhexiushen Feb 11, 2026
67e51d8
fix: upgrade xdaqmetadata version
zhexiushen Feb 11, 2026
422f309
minor library change
zhexiushen Mar 12, 2026
72314ca
Add cmake options to use ASAN/UBSAN/TSAN
zhexiushen May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/conan_profiles/macos-15-armv8
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[settings]
arch=armv8
compiler=clang
compiler.cppstd=gnu20
compiler.libcxx=libc++
compiler.version=18
os=Macos
os.version=15.0
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
9 changes: 9 additions & 0 deletions .github/conan_profiles/windows-2022-x64
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[settings]
arch=x86_64
compiler=msvc
compiler.cppstd=20
compiler.runtime=dynamic
compiler.version=194
os=Windows
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
137 changes: 137 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: build

on:
workflow_dispatch:

jobs:
build:
strategy:
matrix:
include:
- os: windows-2022
arch: x64
base_name: windows-x86_64
- os: macos-15
arch: armv8
base_name: macos-armv8

runs-on: ${{ matrix.os }}

env:
gst_version: 1.26.8

steps:
- uses: actions/checkout@v5

- name: Setup Compiler (Windows)
if: matrix.os == 'windows-2022'
uses: ilammy/msvc-dev-cmd@v1

- name: Setup Compiler (macOS)
if: matrix.os == 'macos-15'
run: |
echo "CC=$(brew --prefix llvm@18)/bin/clang" >> $GITHUB_ENV
echo "CXX=$(brew --prefix llvm@18)/bin/clang++" >> $GITHUB_ENV

- name: Install build tools
run: pipx install cmake conan ninja

- name: Install pkg-config (Windows)
if: matrix.os == 'windows-2022'
run: choco install pkgconfiglite

- name: Install conan profile
run: conan config install .github/conan_profiles/${{ matrix.os }}-${{ matrix.arch }} -tf profiles

- name: Cache conan
uses: actions/cache@v4
with:
path: ~/.conan2
key: ${{ matrix.base_name }}-conan-${{ hashFiles('conanfile.py') }}
restore-keys: ${{ matrix.base_name }}-conan-

- name: Cache gstreamer
uses: actions/cache@v4
id: cache-gstreamer
with:
path: |
C:\Program Files\gstreamer
/Library/Frameworks/GStreamer.framework
key: ${{ matrix.base_name }}-gstreamer-${{ env.gst_version }}
restore-keys: ${{ matrix.base_name }}-gstreamer-

- name: Install gstreamer (Windows)
if: matrix.os == 'windows-2022' && steps.cache-gstreamer.outputs.cache-hit != 'true'
env:
gst_archive: gstreamer-1.0-msvc-x86_64-${{ env.gst_version }}.msi
gst_devel_archive: gstreamer-1.0-devel-msvc-x86_64-${{ env.gst_version }}.msi
run: |
curl -o "${{ env.gst_archive }}" "https://gstreamer.freedesktop.org/data/pkg/windows/${{ env.gst_version }}/msvc/${{ env.gst_archive }}"
curl -o "${{ env.gst_devel_archive }}" "https://gstreamer.freedesktop.org/data/pkg/windows/${{ env.gst_version }}/msvc/${{ env.gst_devel_archive }}"

$log = "install.log"

$process = Start-Process "msiexec" "/i `"${{ env.gst_archive }}`" /qn /l*! `"$log`"" -NoNewWindow -PassThru
$process_log = Start-Process "powershell" "Get-Content -Path `"$log`" -Wait" -NoNewWindow -PassThru
$process.WaitForExit()
$process_log.Kill()

$process = Start-Process "msiexec" "/i `"${{ env.gst_devel_archive }}`" /qn /l*! `"$log`"" -NoNewWindow -PassThru
$process_log = Start-Process "powershell" "Get-Content -Path `"$log`" -Wait" -NoNewWindow -PassThru
$process.WaitForExit()
$process_log.Kill()

- name: Install gstreamer (macOS)
if: matrix.os == 'macos-15' && steps.cache-gstreamer.outputs.cache-hit != 'true'
shell: bash
run: |
gst_archive=gstreamer-1.0-${{ env.gst_version }}-universal.pkg
gst_devel_archive=gstreamer-1.0-devel-${{ env.gst_version }}-universal.pkg

curl -o "$gst_archive" "https://gstreamer.freedesktop.org/data/pkg/osx/${{ env.gst_version }}/$gst_archive"
curl -o "$gst_devel_archive" "https://gstreamer.freedesktop.org/data/pkg/osx/${{ env.gst_version }}/$gst_devel_archive"

sudo installer -pkg $gst_archive -target /
sudo installer -pkg $gst_devel_archive -target /

- name: Setup conan index
run: |
git clone --depth 1 --branch master https://github.com/kontex-neuro/kontex-conan.git kontex-conan
conan remote add --force kontex-neuro ./kontex-conan

- name: Build & Install (Windows)
if: matrix.os == 'windows-2022'
env:
PKG_CONFIG_PATH: "C:\\Program Files\\gstreamer\\1.0\\msvc_x86_64\\lib\\pkgconfig"
run: |
conan install . -b missing -pr:a ${{ matrix.os }}-${{ matrix.arch }} -s build_type=Release
cmake -S . -B build/Release --preset conan-release -G "Ninja" -DCMAKE_INSTALL_PREFIX=build/install -DCMAKE_BUILD_TYPE=Release
cmake --build build/Release --target install

- name: Build & Install (macOS)
if: matrix.os == 'macos-15'
env:
PKG_CONFIG_PATH: /Library/Frameworks/GStreamer.framework/Versions/1.0/lib/pkgconfig
run: |
conan install . -b missing -pr:a ${{ matrix.os }}-${{ matrix.arch }} -s build_type=Release
cmake -S . -B build/Release --preset conan-release -G "Ninja" -DCMAKE_INSTALL_PREFIX=build/install -DCMAKE_BUILD_TYPE=Release
cmake --build build/Release --target install

- name: Get & Set version
shell: bash
run: |
version=$(conan inspect -f json . | jq -r '.version')
echo $version
echo "version=$version" >> $GITHUB_ENV

- name: Zip
shell: bash
run: |
mv build/install ${{ matrix.base_name }}
7z a ${{ matrix.base_name }}-${{ env.version }}.zip ${{ matrix.base_name }}

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.base_name }}
path: ${{ matrix.base_name }}-${{ env.version }}.zip
14 changes: 9 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
# IDE, Editor
__pycache__/
*.py[cod]
/*.pro.user*
/.vscode

# OS
.DS_Store

# Build
/build*
/.venv
/.cache
/CMakeUserPresets.json
dist/
build/
.venv/
.cache/
CMakeUserPresets.json

# clang
.clangd

*.log
*.mkv
*.mkv
*.sh
138 changes: 117 additions & 21 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,50 +1,146 @@
cmake_minimum_required(VERSION 3.25)

set(libxvc_VERSION 0.1.0)
set(libxvc_VERSION 0.2.1)

project(libxvc
LANGUAGES CXX
VERSION "${libxvc_VERSION}"
DESCRIPTION "Thor Vision Video Capture Library"
HOMEPAGE_URL "https://www.kontex.io/"
)

if(APPLE)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fexperimental-library>)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(Boost_USE_STATIC_LIBS ON)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "default install path" FORCE)
endif()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(BUILD_SHARED_LIBS "Build as shared library" OFF)
option(BUILD_TESTS "Build tests" OFF)
option(BUILD_TOOLS "Build tools" OFF)
# option(BUILD_PYTHON_BINDINGS "Build python bindings" ON)
# option(BUILD_PYTHON_STUBS "Build python stubs" OFF)
option(USE_ASAN "Enable AddressSanitizer (ASan)" OFF)
option(USE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF)
option(USE_TSAN "Enable ThreadSanitizer (TSan)" OFF)

if(USE_ASAN AND USE_TSAN)
message(
FATAL_ERROR
"AddressSanitizer (ASan) and ThreadSanitizer (TSan) are mutually exclusive and cannot be enabled at the same time."
)
endif()

set(SANITIZER_COMPILE_FLAGS "")
set(SANITIZER_LINK_FLAGS "")

if(USE_ASAN)
if(WIN32 AND MSVC)
list(APPEND SANITIZER_COMPILE_FLAGS /fsanitize=address)
list(APPEND SANITIZER_LINK_FLAGS /fsanitize=address)
else()
list(APPEND SANITIZER_COMPILE_FLAGS -fsanitize=address)
list(APPEND SANITIZER_LINK_FLAGS -fsanitize=address)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND SANITIZER_LINK_FLAGS -lpthread)
endif()
endif()
endif()

if(USE_UBSAN)
if(WIN32 AND MSVC)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
list(APPEND SANITIZER_COMPILE_FLAGS -fsanitize=undefined)
list(APPEND SANITIZER_LINK_FLAGS -fsanitize=undefined)
else()
message(
WARNING
"UndefinedBehaviorSanitizer (UBSan) is not directly supported via a simple flag in MSVC."
)
endif()
else()
list(APPEND SANITIZER_COMPILE_FLAGS -fsanitize=undefined)
list(APPEND SANITIZER_LINK_FLAGS -fsanitize=undefined)
endif()
endif()

if(USE_TSAN)
if(WIN32 AND MSVC)
message(
FATAL_ERROR
"ThreadSanitizer (TSan) is not supported by the MSVC compiler. Please use Clang or GCC."
)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
message(FATAL_ERROR "ThreadSanitizer (TSan) is not supported on macOS.")
else()
list(APPEND SANITIZER_COMPILE_FLAGS -fsanitize=thread)
list(APPEND SANITIZER_LINK_FLAGS -fsanitize=thread)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
list(APPEND SANITIZER_LINK_FLAGS -lpthread)
endif()
endif()
endif()

add_library(xvc)

target_compile_options(xvc PUBLIC ${SANITIZER_COMPILE_FLAGS})
target_link_options(xvc PUBLIC ${SANITIZER_LINK_FLAGS})

set(Boost_USE_STATIC_LIBS ON)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(nlohmann_json_schema_validator REQUIRED)
find_package(cpr REQUIRED)
find_package(xdaqmetadata REQUIRED)
find_package(Boost 1.81.0 REQUIRED)
find_package(CLI11 REQUIRED)
find_package(OpenSSL REQUIRED)

find_package(PkgConfig REQUIRED)
pkg_search_module(gstreamer REQUIRED IMPORTED_TARGET gstreamer-1.0>=1.4)
pkg_search_module(gstreamer-app REQUIRED IMPORTED_TARGET gstreamer-app-1.0>=1.4)
pkg_search_module(gstreamer-video REQUIRED IMPORTED_TARGET gstreamer-video-1.0>=1.4)

add_subdirectory(xdaqvc)
add_subdirectory(tool)

if(BUILD_TESTING)
if(BUILD_TESTS)
enable_testing()
find_package(GTest REQUIRED)
find_package(Catch2 REQUIRED)
include(CTest)
add_subdirectory(test)
add_subdirectory(tests)
endif()

include(CMakePackageConfigHelpers)
if(BUILD_TOOLS)
find_package(xdaqmetadata REQUIRED)
find_package(CLI11 REQUIRED)
pkg_search_module(gstreamer-app REQUIRED IMPORTED_TARGET gstreamer-app-1.0>=1.4)
pkg_search_module(gstreamer-video REQUIRED IMPORTED_TARGET gstreamer-video-1.0>=1.4)
add_subdirectory(tools)
endif()

# if(BUILD_PYTHON_BINDINGS)
# find_package(Python 3.9
# REQUIRED COMPONENTS Interpreter Development.Module
# # OPTIONAL_COMPONENTS Development.SABIModule
# )
# find_package(nanobind CONFIG REQUIRED)
# add_subdirectory(python/src)
# endif()

include(GNUInstallDirs)

install(
TARGETS xvc
EXPORT libxvc-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FILE_SET "public_headers" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/xdaqvc
)
install(
EXPORT libxvc-targets
FILE libxvc-targets.cmake
NAMESPACE libxvc::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libxvc"
)
export(
EXPORT libxvc-targets
FILE libxvc-config.cmake
NAMESPACE libxvc::
)

include(CMakePackageConfigHelpers)

configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/libxvc-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/libxvc-config.cmake"
Expand Down
Loading