set(RK_PLUGIN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/plugins) option(RK3588_ENABLE_FFMPEG "Enable FFmpeg-based RTSP input" OFF) option(RK3588_ENABLE_MPP "Enable Rockchip MPP decode/encode" OFF) option(RK3588_ENABLE_ZLMEDIAKIT "Enable embedded ZLMediaKit RTSP server" OFF) option(RK3588_ENABLE_RGA "Enable Rockchip RGA hardware acceleration" OFF) option(RK3588_ENABLE_RKNN "Enable RKNN NPU inference" OFF) set(RK_RGA_ROOT "${RK_RKNN_ROOT}/examples/3rdparty/rga/RK3588" CACHE PATH "Path to RGA library") set(RK_RGA_INCLUDE_DIR "${RK_RGA_ROOT}/include" CACHE PATH "RGA include directory") set(RK_RGA_LIB_DIR "${RK_RGA_ROOT}/lib/Linux/aarch64" CACHE PATH "RGA library directory") set(RK_ZLMEDIAKIT_ROOT "${RK_RKNN_ROOT}/examples/3rdparty/zlmediakit" CACHE PATH "Path to ZLMediaKit mk_api bundle") set(RK_ZLMEDIAKIT_INCLUDE_DIR "${RK_ZLMEDIAKIT_ROOT}/include" CACHE PATH "ZLMediaKit mk_api include directory") set(RK_ZLMEDIAKIT_LIB_DIR "${RK_ZLMEDIAKIT_ROOT}/aarch64" CACHE PATH "ZLMediaKit mk_api library directory") set(RK_ZLMK_API_LIB_PATH "" CACHE FILEPATH "Absolute path to libmk_api.so") if(RK3588_ENABLE_FFMPEG) find_package(PkgConfig REQUIRED) pkg_check_modules(FFMPEG REQUIRED IMPORTED_TARGET libavformat libavcodec libavutil) endif() if(RK3588_ENABLE_MPP) # Prefer user-provided lib path; otherwise search common locations including rknpu2 prebuilts. find_library(RK_MPP_LIB rockchip_mpp HINTS ${RK_MPP_LIB_PATH} ${RK_MPP_ROOT}/build ${RK_MPP_ROOT}/lib ${RK_RKNN_ROOT}/examples/3rdparty/mpp/Linux/aarch64 ${RK_RKNN_ROOT}/examples/3rdparty/mpp/Linux/armhf NO_DEFAULT_PATH ) if(NOT RK_MPP_LIB) find_library(RK_MPP_LIB rockchip_mpp) endif() if(NOT RK_MPP_LIB) message(WARNING "MPP enabled but rockchip_mpp library not found; disable RK3588_ENABLE_MPP or set RK_MPP_LIB_PATH") endif() endif() if(RK3588_ENABLE_ZLMEDIAKIT) if(RK_ZLMK_API_LIB_PATH) set(RK_ZLMK_API_LIB "${RK_ZLMK_API_LIB_PATH}") else() find_library(RK_ZLMK_API_LIB mk_api HINTS ${RK_ZLMEDIAKIT_LIB_DIR} NO_DEFAULT_PATH ) if(NOT RK_ZLMK_API_LIB) find_library(RK_ZLMK_API_LIB mk_api) endif() endif() if(NOT RK_ZLMK_API_LIB) message(WARNING "ZLMediaKit enabled but mk_api library not found; set RK_ZLMK_API_LIB_PATH or RK_ZLMEDIAKIT_LIB_DIR") endif() endif() if(RK3588_ENABLE_RGA) find_library(RK_RGA_LIB rga HINTS ${RK_RGA_LIB_DIR} NO_DEFAULT_PATH ) if(NOT RK_RGA_LIB) find_library(RK_RGA_LIB rga) endif() if(NOT RK_RGA_LIB) message(WARNING "RGA enabled but librga not found; disable RK3588_ENABLE_RGA or set RK_RGA_LIB_DIR") endif() endif() if(RK3588_ENABLE_RKNN) find_library(RK_RKNN_LIB rknnrt HINTS ${RKNN_RUNTIME_LIB_DIR} ${RK_RKNN_ROOT}/runtime/RK3588/Linux/librknn_api/aarch64 NO_DEFAULT_PATH ) if(NOT RK_RKNN_LIB) find_library(RK_RKNN_LIB rknnrt) endif() if(NOT RK_RKNN_LIB) message(WARNING "RKNN enabled but librknnrt not found; disable RK3588_ENABLE_RKNN or set RKNN_RUNTIME_LIB_DIR") endif() endif() # AiScheduler shared library for NPU resource management add_library(ai_scheduler SHARED ${CMAKE_SOURCE_DIR}/src/ai_scheduler.cpp) target_include_directories(ai_scheduler PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(ai_scheduler PRIVATE project_options Threads::Threads) if(RK3588_ENABLE_RKNN AND RK_RKNN_LIB) target_compile_definitions(ai_scheduler PRIVATE RK3588_ENABLE_RKNN) target_include_directories(ai_scheduler PRIVATE ${RKNN_RUNTIME_INCLUDE_DIR}) target_link_libraries(ai_scheduler PRIVATE ${RK_RKNN_LIB}) endif() set_target_properties(ai_scheduler PROPERTIES OUTPUT_NAME "ai_scheduler" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) add_library(input_rtsp SHARED input_rtsp/input_rtsp_node.cpp) target_include_directories(input_rtsp PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(input_rtsp PRIVATE project_options Threads::Threads) if(RK3588_ENABLE_FFMPEG) target_compile_definitions(input_rtsp PRIVATE RK3588_ENABLE_FFMPEG) target_include_directories(input_rtsp PRIVATE ${FFMPEG_INCLUDE_DIRS}) target_link_libraries(input_rtsp PRIVATE PkgConfig::FFMPEG) endif() if(RK3588_ENABLE_MPP AND RK_MPP_LIB) target_compile_definitions(input_rtsp PRIVATE RK3588_ENABLE_MPP) target_include_directories(input_rtsp PRIVATE ${RK_MPP_ROOT}/inc ${RK_RKNN_ROOT}/examples/3rdparty/mpp/include ) target_link_libraries(input_rtsp PRIVATE ${RK_MPP_LIB}) endif() set_target_properties(input_rtsp PROPERTIES OUTPUT_NAME "input_rtsp" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) add_library(input_file SHARED input_file/input_file_node.cpp) target_include_directories(input_file PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(input_file PRIVATE project_options Threads::Threads) if(RK3588_ENABLE_FFMPEG) target_compile_definitions(input_file PRIVATE RK3588_ENABLE_FFMPEG) target_include_directories(input_file PRIVATE ${FFMPEG_INCLUDE_DIRS}) target_link_libraries(input_file PRIVATE PkgConfig::FFMPEG) endif() if(RK3588_ENABLE_MPP AND RK_MPP_LIB) target_compile_definitions(input_file PRIVATE RK3588_ENABLE_MPP) target_include_directories(input_file PRIVATE ${RK_MPP_ROOT}/inc ${RK_RKNN_ROOT}/examples/3rdparty/mpp/include ) target_link_libraries(input_file PRIVATE ${RK_MPP_LIB}) endif() set_target_properties(input_file PROPERTIES OUTPUT_NAME "input_file" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) add_library(publish SHARED publish/publish_node.cpp) target_include_directories(publish PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(publish PRIVATE project_options Threads::Threads) if(RK3588_ENABLE_FFMPEG) target_compile_definitions(publish PRIVATE RK3588_ENABLE_FFMPEG) target_include_directories(publish PRIVATE ${FFMPEG_INCLUDE_DIRS}) target_link_libraries(publish PRIVATE PkgConfig::FFMPEG) endif() if(RK3588_ENABLE_MPP AND RK_MPP_LIB) target_compile_definitions(publish PRIVATE RK3588_ENABLE_MPP) target_include_directories(publish PRIVATE ${RK_MPP_ROOT}/inc ${RK_RKNN_ROOT}/examples/3rdparty/mpp/include ) target_link_libraries(publish PRIVATE ${RK_MPP_LIB}) endif() if(RK3588_ENABLE_ZLMEDIAKIT AND RK_ZLMK_API_LIB) target_compile_definitions(publish PRIVATE RK3588_ENABLE_ZLMEDIAKIT) target_include_directories(publish PRIVATE ${RK_ZLMEDIAKIT_INCLUDE_DIR}) target_link_libraries(publish PRIVATE ${RK_ZLMK_API_LIB}) set_target_properties(publish PROPERTIES BUILD_RPATH "\$ORIGIN" INSTALL_RPATH "\$ORIGIN") add_custom_command(TARGET publish POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${RK_ZLMK_API_LIB}" $ ) install(FILES "${RK_ZLMK_API_LIB}" DESTINATION ${CMAKE_INSTALL_LIBDIR}/rk3588-media-server/plugins) endif() set_target_properties(publish PROPERTIES OUTPUT_NAME "publish" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) add_library(preprocess SHARED preprocess/preprocess_node.cpp ${CMAKE_SOURCE_DIR}/src/utils/dma_alloc.cpp ) target_include_directories(preprocess PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(preprocess PRIVATE project_options Threads::Threads) if(RK3588_ENABLE_FFMPEG) target_compile_definitions(preprocess PRIVATE RK3588_ENABLE_FFMPEG) target_include_directories(preprocess PRIVATE ${FFMPEG_INCLUDE_DIRS}) target_link_libraries(preprocess PRIVATE PkgConfig::FFMPEG) # swscale is required when preprocess runs in software mode (use_rga=false) pkg_check_modules(SWSCALE_PREPROCESS IMPORTED_TARGET libswscale) if(SWSCALE_PREPROCESS_FOUND) target_link_libraries(preprocess PRIVATE PkgConfig::SWSCALE_PREPROCESS) endif() endif() if(RK3588_ENABLE_RGA AND RK_RGA_LIB) target_compile_definitions(preprocess PRIVATE RK3588_ENABLE_RGA) target_include_directories(preprocess PRIVATE ${RK_RGA_INCLUDE_DIR}) target_link_libraries(preprocess PRIVATE ${RK_RGA_LIB}) endif() set_target_properties(preprocess PROPERTIES OUTPUT_NAME "preprocess" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) # ai_yolo plugin (RKNN-based YOLO inference) add_library(ai_yolo SHARED ai_yolo/ai_yolo_node.cpp) target_include_directories(ai_yolo PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(ai_yolo PRIVATE project_options Threads::Threads ai_scheduler) if(RK3588_ENABLE_RKNN AND RK_RKNN_LIB) target_compile_definitions(ai_yolo PRIVATE RK3588_ENABLE_RKNN) target_include_directories(ai_yolo PRIVATE ${RKNN_RUNTIME_INCLUDE_DIR}) target_link_libraries(ai_yolo PRIVATE ${RK_RKNN_LIB}) endif() set_target_properties(ai_yolo PROPERTIES OUTPUT_NAME "ai_yolo" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) # det_post plugin (post-processing pipeline for detection results) add_library(det_post SHARED det_post/det_post_node.cpp) target_include_directories(det_post PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(det_post PRIVATE project_options Threads::Threads) set_target_properties(det_post PROPERTIES OUTPUT_NAME "det_post" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) # osd plugin (on-screen display for detection results) add_library(osd SHARED osd/osd_node.cpp) target_include_directories(osd PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(osd PRIVATE project_options Threads::Threads) set_target_properties(osd PROPERTIES OUTPUT_NAME "osd" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) # alarm plugin (rule-based alarm with actions: log, http, snapshot, clip) add_library(alarm SHARED alarm/alarm_node.cpp alarm/rule_engine.cpp alarm/frame_ring_buffer.cpp alarm/packet_ring_buffer.cpp alarm/actions/log_action.cpp alarm/actions/http_action.cpp alarm/actions/external_api_action.cpp alarm/actions/snapshot_action.cpp alarm/actions/clip_action.cpp alarm/uploaders/local_uploader.cpp alarm/uploaders/minio_uploader.cpp alarm/uploaders/uploader_factory.cpp ${CMAKE_SOURCE_DIR}/src/utils/dma_alloc.cpp ) target_include_directories(alarm PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party ${CMAKE_CURRENT_SOURCE_DIR}/alarm ) target_link_libraries(alarm PRIVATE project_options Threads::Threads) if(RK3588_ENABLE_FFMPEG) target_compile_definitions(alarm PRIVATE RK3588_ENABLE_FFMPEG) target_include_directories(alarm PRIVATE ${FFMPEG_INCLUDE_DIRS}) target_link_libraries(alarm PRIVATE PkgConfig::FFMPEG) # Also need libswscale for image conversion pkg_check_modules(SWSCALE IMPORTED_TARGET libswscale) if(SWSCALE_FOUND) target_link_libraries(alarm PRIVATE PkgConfig::SWSCALE) endif() endif() # Optional: libcurl for HTTP action (on Linux) find_package(CURL QUIET) if(CURL_FOUND) target_link_libraries(alarm PRIVATE CURL::libcurl) endif() # Optional: OpenSSL for MinIO/S3 SigV4 signing (when presign_endpoint is not used) find_package(OpenSSL QUIET) if(OpenSSL_FOUND) target_compile_definitions(alarm PRIVATE RK3588_ENABLE_OPENSSL) target_link_libraries(alarm PRIVATE OpenSSL::Crypto) endif() set_target_properties(alarm PROPERTIES OUTPUT_NAME "alarm" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) # storage plugin (continuous recording with segment management) add_library(storage SHARED storage/storage_node.cpp) target_include_directories(storage PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_link_libraries(storage PRIVATE project_options Threads::Threads) if(RK3588_ENABLE_FFMPEG) target_compile_definitions(storage PRIVATE RK3588_ENABLE_FFMPEG) target_include_directories(storage PRIVATE ${FFMPEG_INCLUDE_DIRS}) target_link_libraries(storage PRIVATE PkgConfig::FFMPEG) if(SWSCALE_FOUND) target_link_libraries(storage PRIVATE PkgConfig::SWSCALE) endif() endif() if(RK3588_ENABLE_MPP AND RK_MPP_LIB) target_compile_definitions(storage PRIVATE RK3588_ENABLE_MPP) target_include_directories(storage PRIVATE ${RK_MPP_ROOT}/inc ${RK_RKNN_ROOT}/examples/3rdparty/mpp/include ) target_link_libraries(storage PRIVATE ${RK_MPP_LIB}) endif() set_target_properties(storage PROPERTIES OUTPUT_NAME "storage" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} ) # zlm_http plugin (embedded HTTP file server via ZLMediaKit) if(RK3588_ENABLE_ZLMEDIAKIT AND RK_ZLMK_API_LIB) add_library(zlm_http SHARED zlm_http/zlm_http_node.cpp) target_include_directories(zlm_http PRIVATE ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/third_party) target_compile_definitions(zlm_http PRIVATE RK3588_ENABLE_ZLMEDIAKIT) target_include_directories(zlm_http PRIVATE ${RK_ZLMEDIAKIT_INCLUDE_DIR}) target_link_libraries(zlm_http PRIVATE project_options Threads::Threads ${RK_ZLMK_API_LIB}) set_target_properties(zlm_http PROPERTIES OUTPUT_NAME "zlm_http" LIBRARY_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} RUNTIME_OUTPUT_DIRECTORY ${RK_PLUGIN_OUTPUT_DIR} BUILD_RPATH "\$ORIGIN" INSTALL_RPATH "\$ORIGIN" ) add_custom_command(TARGET zlm_http POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${RK_ZLMK_API_LIB}" $ ) install(TARGETS zlm_http LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/rk3588-media-server/plugins RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/rk3588-media-server/plugins ) endif() install(TARGETS input_rtsp input_file publish preprocess ai_yolo osd alarm storage ai_scheduler LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/rk3588-media-server/plugins RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}/rk3588-media-server/plugins )