// video_service_manager.cc #include "video_service_manager.h" #include "spdlog/spdlog.h" VideoServiceManager::~VideoServiceManager() { // 确保在析构时停止所有服务 stop_all(); } void VideoServiceManager::load_and_start(ConfigManager& config) { if (!config.getIsVideoServiceEnabled()) { spdlog::warn("VideoService is disabled in configuration. No streams will be started."); return; } model_path_ = config.getVideoModelPath(); if (model_path_.empty()) { spdlog::error("Video model path is not set in configuration. Cannot start video services."); return; } auto stream_configs = config.getVideoStreamConfigs(); spdlog::info("Found {} video stream configurations.", stream_configs.size()); for (const auto& sc : stream_configs) { if (!sc.enabled) { spdlog::info("Video stream '{}' (input: {}) is disabled in config, skipping.", sc.id, sc.input_url); continue; } if (sc.rknn_thread_num <= 0) { spdlog::warn("Video stream '{}' has invalid rknn_thread_num ({}). Defaulting to 1.", sc.id, sc.rknn_thread_num); } int threads_for_this_stream = (sc.rknn_thread_num > 0) ? sc.rknn_thread_num : 1; try { // 为每个流创建一个独立的 VideoService 实例 auto service = std::make_unique( model_path_, threads_for_this_stream, sc.input_url, sc.output_rtsp ); if (service->start()) { spdlog::info("Successfully started video service for stream '{}' [Input: {}]. Output is [{}].", sc.id, sc.input_url, sc.output_rtsp); services_.push_back(std::move(service)); } else { spdlog::error("Failed to start video service for stream '{}' [Input: {}].", sc.id, sc.input_url); } } catch (const std::exception& e) { spdlog::error("Exception while creating VideoService for stream '{}' [{}]: {}", sc.id, sc.input_url, e.what()); } } spdlog::info("VideoServiceManager finished setup. {} streams are now running.", services_.size()); } void VideoServiceManager::stop_all() { spdlog::info("Stopping all video services ({})...", services_.size()); // 按顺序停止所有服务 for (auto& service : services_) { if (service) { service->stop(); } } services_.clear(); spdlog::info("All video services stopped and cleared."); }