feat(encode): add Jetson Multimedia API encoder backend
Integrate a native Jetson Multimedia API encoder path and keep the existing encoded access-unit contract for RTMP, RTP, and recording consumers. This adds conditional Jetson MMAPI detection in CMake, builds the required NVIDIA sample common classes into a dedicated support library, and compiles the new backend only when the platform dependencies are present. The runtime selector now lets encoder.backend=auto prefer Jetson MM for NVIDIA hardware requests while keeping encoder.backend=ffmpeg as an explicit FFmpeg path. Device selection semantics are updated so nvidia requires the Jetson backend, auto can fall back to FFmpeg software, and software remains FFmpeg-only. The Jetson backend converts supported raw inputs through swscale, feeds NvVideoEncoder in YUV420M, emits Annex-B access units, and harvests decoder configuration from a warmup keyframe so downstream packetizers keep their existing contract. This also splits FFmpeg encoder option handling into a shared header, updates runtime config/help text and tester defaults, and refreshes compatibility/caveat documentation to reflect the new selection behavior. Build-tree runtime RPATH handling is tightened so GCC 15 builds keep the matching libstdc++ visible locally. Verification covered GCC 15 builds, RTP H.264/H.265 tester runs, RTMP H.264 stub publish, local live SRS smoke with cvmmap://zed1, and remote execution on 192.168.2.155 using the deployed bundle lib directory for the GCC 15 runtime.
This commit is contained in:
+101
-6
@@ -8,6 +8,9 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
set(CVMMAP_STREAMER_INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
|
||||
|
||||
|
||||
function(cvmmap_streamer_append_runtime_dir out_var runtime_library)
|
||||
execute_process(
|
||||
COMMAND "${CMAKE_CXX_COMPILER}" -print-file-name=${runtime_library}
|
||||
@@ -69,6 +72,17 @@ set(
|
||||
"${CMAKE_CURRENT_LIST_DIR}/third_party/mcap/include"
|
||||
CACHE PATH
|
||||
"Path to MCAP headers")
|
||||
set(
|
||||
CVMMAP_STREAMER_ENABLE_JETSON_MM
|
||||
"AUTO"
|
||||
CACHE STRING
|
||||
"Enable Jetson Multimedia API encoder backend: AUTO, ON, or OFF")
|
||||
set_property(CACHE CVMMAP_STREAMER_ENABLE_JETSON_MM PROPERTY STRINGS AUTO ON OFF)
|
||||
set(
|
||||
CVMMAP_STREAMER_JETSON_MMAPI_ROOT
|
||||
"/usr/src/jetson_multimedia_api"
|
||||
CACHE PATH
|
||||
"Path to the Jetson Multimedia API root")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
@@ -117,7 +131,7 @@ if (CVMMAP_CNATS_PROVIDER STREQUAL "system")
|
||||
find_package(cnats CONFIG REQUIRED)
|
||||
find_package(cvmmap-core CONFIG QUIET PATHS "${CVMMAP_LOCAL_CORE_DIR}" NO_DEFAULT_PATH)
|
||||
if (NOT TARGET cvmmap::client)
|
||||
find_package(cvmmap-core CONFIG QUIET)
|
||||
find_package(cvmmap-core CONFIG REQUIRED PATHS "${CVMMAP_LOCAL_CORE_DIR}" NO_DEFAULT_PATH)
|
||||
endif()
|
||||
else()
|
||||
if (NOT EXISTS "${CVMMAP_LOCAL_NATS_STATIC}")
|
||||
@@ -240,6 +254,78 @@ else()
|
||||
set(CVMMAP_STREAMER_HAS_MCAP_DEPTH 0)
|
||||
endif()
|
||||
|
||||
set(_CVMMAP_STREAMER_JETSON_MM_INCLUDE_DIR "${CVMMAP_STREAMER_JETSON_MMAPI_ROOT}/include")
|
||||
set(_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR "${CVMMAP_STREAMER_JETSON_MMAPI_ROOT}/samples/common/classes")
|
||||
set(_CVMMAP_STREAMER_JETSON_MM_COMMON_SOURCES
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR}/NvBuffer.cpp"
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR}/NvElement.cpp"
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR}/NvElementProfiler.cpp"
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR}/NvLogging.cpp"
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR}/NvV4l2Element.cpp"
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR}/NvV4l2ElementPlane.cpp"
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_COMMON_DIR}/NvVideoEncoder.cpp")
|
||||
|
||||
set(_CVMMAP_STREAMER_JETSON_MM_MISSING_DEPS)
|
||||
if (NOT EXISTS "${_CVMMAP_STREAMER_JETSON_MM_INCLUDE_DIR}/NvVideoEncoder.h")
|
||||
list(APPEND _CVMMAP_STREAMER_JETSON_MM_MISSING_DEPS
|
||||
"Jetson Multimedia API headers at ${_CVMMAP_STREAMER_JETSON_MM_INCLUDE_DIR}")
|
||||
endif()
|
||||
foreach(_cvmmap_streamer_jetson_mm_source IN LISTS _CVMMAP_STREAMER_JETSON_MM_COMMON_SOURCES)
|
||||
if (NOT EXISTS "${_cvmmap_streamer_jetson_mm_source}")
|
||||
list(APPEND _CVMMAP_STREAMER_JETSON_MM_MISSING_DEPS
|
||||
"Jetson Multimedia API common source ${_cvmmap_streamer_jetson_mm_source}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
find_library(
|
||||
CVMMAP_STREAMER_NVBUFSURFACE_LIBRARY
|
||||
NAMES nvbufsurface
|
||||
PATHS
|
||||
/usr/lib/aarch64-linux-gnu/nvidia
|
||||
/usr/lib/aarch64-linux-gnu/tegra
|
||||
/usr/lib/aarch64-linux-gnu
|
||||
PATH_SUFFIXES nvidia tegra)
|
||||
if (NOT CVMMAP_STREAMER_NVBUFSURFACE_LIBRARY)
|
||||
list(APPEND _CVMMAP_STREAMER_JETSON_MM_MISSING_DEPS "libnvbufsurface")
|
||||
endif()
|
||||
|
||||
find_library(CVMMAP_STREAMER_LIBV4L2_LIBRARY NAMES v4l2)
|
||||
if (NOT CVMMAP_STREAMER_LIBV4L2_LIBRARY)
|
||||
list(APPEND _CVMMAP_STREAMER_JETSON_MM_MISSING_DEPS "libv4l2")
|
||||
endif()
|
||||
|
||||
if (_CVMMAP_STREAMER_JETSON_MM_MISSING_DEPS)
|
||||
list(JOIN _CVMMAP_STREAMER_JETSON_MM_MISSING_DEPS ", " _CVMMAP_STREAMER_JETSON_MM_UNAVAILABLE_REASON)
|
||||
set(_CVMMAP_STREAMER_JETSON_MM_AVAILABLE FALSE)
|
||||
else()
|
||||
set(_CVMMAP_STREAMER_JETSON_MM_UNAVAILABLE_REASON "Jetson Multimedia API dependencies")
|
||||
set(_CVMMAP_STREAMER_JETSON_MM_AVAILABLE TRUE)
|
||||
endif()
|
||||
|
||||
cvmmap_streamer_resolve_feature_mode(
|
||||
CVMMAP_STREAMER_HAS_JETSON_MM_BOOL
|
||||
CVMMAP_STREAMER_ENABLE_JETSON_MM
|
||||
"${CVMMAP_STREAMER_ENABLE_JETSON_MM}"
|
||||
${_CVMMAP_STREAMER_JETSON_MM_AVAILABLE}
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_UNAVAILABLE_REASON}")
|
||||
|
||||
if (CVMMAP_STREAMER_HAS_JETSON_MM_BOOL)
|
||||
set(CVMMAP_STREAMER_HAS_JETSON_MM 1)
|
||||
|
||||
add_library(cvmmap_streamer_jetson_mmapi STATIC
|
||||
${_CVMMAP_STREAMER_JETSON_MM_COMMON_SOURCES})
|
||||
target_include_directories(cvmmap_streamer_jetson_mmapi
|
||||
PUBLIC
|
||||
"${_CVMMAP_STREAMER_JETSON_MM_INCLUDE_DIR}")
|
||||
target_link_libraries(cvmmap_streamer_jetson_mmapi
|
||||
PUBLIC
|
||||
Threads::Threads
|
||||
${CVMMAP_STREAMER_LIBV4L2_LIBRARY}
|
||||
${CVMMAP_STREAMER_NVBUFSURFACE_LIBRARY})
|
||||
else()
|
||||
set(CVMMAP_STREAMER_HAS_JETSON_MM 0)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET cvmmap::client)
|
||||
if (
|
||||
EXISTS "${CVMMAP_LOCAL_ROOT}/core/include/cvmmap/client.hpp"
|
||||
@@ -344,13 +430,17 @@ add_library(cvmmap_streamer_feature_flags INTERFACE)
|
||||
target_compile_definitions(cvmmap_streamer_feature_flags
|
||||
INTERFACE
|
||||
CVMMAP_STREAMER_HAS_MCAP=${CVMMAP_STREAMER_HAS_MCAP}
|
||||
CVMMAP_STREAMER_HAS_MCAP_DEPTH=${CVMMAP_STREAMER_HAS_MCAP_DEPTH})
|
||||
CVMMAP_STREAMER_HAS_MCAP_DEPTH=${CVMMAP_STREAMER_HAS_MCAP_DEPTH}
|
||||
CVMMAP_STREAMER_HAS_JETSON_MM=${CVMMAP_STREAMER_HAS_JETSON_MM})
|
||||
|
||||
add_library(cvmmap_streamer_record_support STATIC
|
||||
src/encode/encoder_backend.cpp
|
||||
src/encode/ffmpeg_encoder_backend.cpp
|
||||
src/record/protobuf_descriptor.cpp
|
||||
src/record/mp4_record_writer.cpp)
|
||||
if (CVMMAP_STREAMER_HAS_JETSON_MM_BOOL)
|
||||
target_sources(cvmmap_streamer_record_support PRIVATE src/encode/jetson_mm_encoder_backend.cpp)
|
||||
endif()
|
||||
target_include_directories(cvmmap_streamer_record_support
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include"
|
||||
@@ -369,6 +459,9 @@ endif()
|
||||
if (TARGET PkgConfig::PROTOBUF_PKG)
|
||||
target_link_libraries(cvmmap_streamer_record_support PUBLIC PkgConfig::PROTOBUF_PKG)
|
||||
endif()
|
||||
if (CVMMAP_STREAMER_HAS_JETSON_MM_BOOL)
|
||||
target_link_libraries(cvmmap_streamer_record_support PUBLIC cvmmap_streamer_jetson_mmapi)
|
||||
endif()
|
||||
|
||||
if (CVMMAP_STREAMER_HAS_MCAP)
|
||||
add_library(cvmmap_streamer_mcap_runtime STATIC
|
||||
@@ -465,7 +558,9 @@ endif()
|
||||
|
||||
target_link_libraries(cvmmap_streamer_common PUBLIC ${CVMMAP_STREAMER_LINK_DEPS})
|
||||
|
||||
function(cvmmap_streamer_apply_build_rpath target)
|
||||
function(cvmmap_streamer_apply_runtime_rpath target)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
INSTALL_RPATH "${CVMMAP_STREAMER_INSTALL_RPATH}")
|
||||
if (CVMMAP_STREAMER_BUILD_RPATH)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
BUILD_RPATH "${CVMMAP_STREAMER_BUILD_RPATH}")
|
||||
@@ -484,7 +579,7 @@ function(add_cvmmap_binary target source)
|
||||
set_target_properties(${target} PROPERTIES
|
||||
OUTPUT_NAME "${target}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
|
||||
cvmmap_streamer_apply_build_rpath(${target})
|
||||
cvmmap_streamer_apply_runtime_rpath(${target})
|
||||
endfunction()
|
||||
|
||||
add_cvmmap_binary(cvmmap_streamer src/main_streamer.cpp)
|
||||
@@ -522,7 +617,7 @@ if (CVMMAP_STREAMER_HAS_MCAP)
|
||||
set_target_properties(mcap_reader_tester PROPERTIES
|
||||
OUTPUT_NAME "mcap_reader_tester"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
|
||||
cvmmap_streamer_apply_build_rpath(mcap_reader_tester)
|
||||
cvmmap_streamer_apply_runtime_rpath(mcap_reader_tester)
|
||||
|
||||
add_executable(mcap_replay_tester src/testers/mcap_replay_tester.cpp)
|
||||
target_include_directories(mcap_replay_tester
|
||||
@@ -548,7 +643,7 @@ if (CVMMAP_STREAMER_HAS_MCAP)
|
||||
set_target_properties(mcap_replay_tester PROPERTIES
|
||||
OUTPUT_NAME "mcap_replay_tester"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
|
||||
cvmmap_streamer_apply_build_rpath(mcap_replay_tester)
|
||||
cvmmap_streamer_apply_runtime_rpath(mcap_replay_tester)
|
||||
endif()
|
||||
|
||||
if (CVMMAP_STREAMER_HAS_MCAP_DEPTH)
|
||||
|
||||
Reference in New Issue
Block a user