From 02819b5c047bb354b0ef2374e7c6a6ac4bbd5bba Mon Sep 17 00:00:00 2001
From: wangrong <wangrong@shsening.com>
Date: 星期四, 23 一月 2025 11:42:36 +0800
Subject: [PATCH] add sample

---
 samples/vehicle_property_and_similiarity_search/static/query_images/readme.txt         |    0 
 samples/similiarity_search/README.md                                                   |    0 
 samples/face_recognize/static/user_register_infos/0003-周智-男-34-武汉.png                  |    0 
 samples/vehicle_property_and_similiarity_search/clean.sh                               |    0 
 samples/face_recognize/clean.sh                                                        |    0 
 samples/lpr_camera/plate_recognize_server.py                                           |    0 
 samples/from_argv_rtsp_test.cpp                                                        |  145 ++++++
 samples/lpr_camera/docs/1.png                                                          |    0 
 samples/similiarity_search/docs/2.png                                                  |    0 
 samples/vehicle_property_and_similiarity_search/static/cropped_images/readme.txt       |    0 
 samples/from_argv_all_in_one_rtsp.cpp                                                  |   28 
 samples/vehicle_property_and_similiarity_search/README.md                              |    0 
 samples/math_review/vp_analysis_board.png                                              |    0 
 samples/vehicle_property_and_similiarity_search/templates/home.html                    |    0 
 samples/lpr_camera/static/dist/flv.min.js                                              |    0 
 samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline     |    0 
 samples/CMakeLists.txt                                                                 |   45 +
 samples/lpr_camera/plate_recognize_pipeline.cpp                                        |    0 
 samples/vehicle_property_and_similiarity_search/docs/1.png                             |    0 
 samples/lpr_camera/README.pdf                                                          |    0 
 samples/face_recognize/static/dist/DPlayer.min.js.map                                  |    0 
 samples/math_review/static/dist/flv.min.js                                             |    0 
 nodes/ba/vp_ba_jam_node.h                                                              |    6 
 samples/vehicle_behaviour_analysis/vp_analysis_board.png                               |    0 
 samples/similiarity_search/face_encoding_pipeline.cpp                                  |    0 
 samples/face_recognize/templates/home.html                                             |    0 
 samples/vehicle_property_and_similiarity_search/vehicle_search_server.py               |    0 
 samples/lpr_camera/static/dist/DPlayer.min.js.map                                      |    0 
 samples/vehicle_behaviour_analysis/vehicle_ba_pipeline.cpp                             |    0 
 samples/vehicle_behaviour_analysis/vehicle_ba_pipeline                                 |    0 
 samples/vehicle_property_and_similiarity_search/README.pdf                             |    0 
 nodes/vp_rtsp_ffmpeg_src_node.h                                                        |   36 
 samples/face_recognize/static/cropped_faces/readme.txt                                 |    0 
 samples/vehicle_behaviour_analysis/static/dist/DPlayer.min.js.map                      |    0 
 samples/face_recognize/static/user_register_infos/0002-杨澜-女-54-北京.png                  |    0 
 objects/vp_frame_target.h                                                              |    4 
 samples/similiarity_search/templates/search_result.html                                |    0 
 samples/vehicle_property_and_similiarity_search/templates/search_result.html           |    0 
 samples/math_review/static/dist/DPlayer.min.js                                         |    0 
 samples/lpr_camera/clean.sh                                                            |    0 
 samples/similiarity_search/search_server.py                                            |    0 
 samples/vehicle_behaviour_analysis/templates/home.html                                 |    0 
 samples/vehicle_behaviour_analysis/vehicle_ba_server.py                                |    0 
 samples/face_recognize/static/dist/DPlayer.min.js                                      |    0 
 samples/similiarity_search/templates/home.html                                         |    0 
 nodes/vp_infer_node.h                                                                  |    1 
 samples/vehicle_behaviour_analysis/README.md                                           |    0 
 samples/from_argv_all_in_one_sample.cpp                                                |    2 
 samples/vehicle_behaviour_analysis/README.pdf                                          |    0 
 samples/face_recognize/face_recognize_pipeline.cpp                                     |    0 
 samples/lpr_camera/static/plate_images/readme.txt                                      |    0 
 samples/similiarity_search/encoding_receiver.py                                        |    0 
 samples/math_review/math_expression_check_server.py                                    |    0 
 samples/from_argv_ba_jam_rtsp.cpp                                                      |  242 +++++-----
 samples/similiarity_search/docs/1.png                                                  |    0 
 samples/similiarity_search/clean.sh                                                    |    0 
 samples/face_recognize/face_recognize_server.py                                        |    0 
 samples/math_review/README.pdf                                                         |    0 
 samples/lpr_camera/templates/home.html                                                 |    0 
 nodes/ba/vp_ba_jam_node.cpp                                                            |   34 
 samples/similiarity_search/face_encoding_pipeline                                      |    0 
 samples/lpr_camera/plate_recognize_pipeline                                            |    0 
 samples/from_argv_all_in_one_rtsp_d.cpp                                                |  137 +++++
 samples/vehicle_behaviour_analysis/clean.sh                                            |    0 
 samples/vehicle_behaviour_analysis/static/record_images/readme.txt                     |    0 
 samples/math_review/static/dist/DPlayer.min.js.map                                     |    0 
 samples/math_review/math_expression_check_pipeline.cpp                                 |    0 
 samples/similiarity_search/README.pdf                                                  |    0 
 samples/face_recognize/face_recognize_pipeline                                         |    0 
 samples/math_review/docs/1.png                                                         |    0 
 samples/face_recognize/static/user_register_infos/0004-刘德华-男-64-香港.png                 |    0 
 samples/face_recognize/README.pdf                                                      |    0 
 samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline.cpp |    0 
 samples/vehicle_property_and_similiarity_search/property_encoding_receiver.py          |    0 
 samples/vehicle_behaviour_analysis/static/dist/DPlayer.min.js                          |    0 
 samples/vehicle_behaviour_analysis/docs/1.png                                          |    0 
 nodes/vp_rtsp_ffmpeg_src_node.cpp                                                      |  182 ++++++-
 samples/lpr_camera/README.md                                                           |    0 
 samples/similiarity_search/vehicle_encoding_pipeline                                   |    0 
 samples/similiarity_search/static/query_images/readme.txt                              |    0 
 samples/similiarity_search/vehicle_encoding_pipeline.cpp                               |    0 
 samples/from_argv_ba_jam_rtsp_m.cpp                                                    |  182 +++++++
 samples/similiarity_search/static/cropped_images/readme.txt                            |    0 
 samples/firesmoke_detect_sample.cpp                                                    |   55 ++
 nodes/vp_infer_node.cpp                                                                |   21 
 samples/vehicle_behaviour_analysis/static/record_videos/readme.txt                     |    0 
 samples/vehicle_property_and_similiarity_search/vp_analysis_board.png                  |    0 
 samples/face_recognize/vp_analysis_board.png                                           |    0 
 samples/math_review/templates/home.html                                                |    0 
 samples/similiarity_search/vp_analysis_board_face.png                                  |    0 
 samples/lpr_camera/static/dist/DPlayer.min.js                                          |    0 
 samples/math_review/clean.sh                                                           |    0 
 samples/face_recognize/docs/1.png                                                      |    0 
 nodes/vp_rtsp_src_node.h                                                               |    5 
 samples/face_recognize/README.md                                                       |    0 
 samples/from_argv_ba_crossline_rtsp.cpp                                                |    4 
 samples/face_recognize/static/user_register_infos/0001-赵本山-男-66-铁岭.png                 |    0 
 samples/from_argv_vehicle_tracking.cpp                                                 |    2 
 samples/vehicle_behaviour_analysis/static/dist/flv.min.js                              |    0 
 samples/similiarity_search/vp_analysis_board_vehicle.png                               |    0 
 /dev/null                                                                              |   82 ---
 samples/from_argv_ba_jam_rtsp_d.cpp                                                    |  162 +++---
 samples/math_review/static/screenshot_images/readme.txt                                |    0 
 samples/lpr_camera/vp_analysis_board.png                                               |    0 
 samples/face_recognize/static/dist/flv.min.js                                          |    0 
 samples/math_review/README.md                                                          |    0 
 106 files changed, 954 insertions(+), 421 deletions(-)

diff --git a/nodes/ba/vp_ba_jam_node.cpp b/nodes/ba/vp_ba_jam_node.cpp
index b4f2643..b34ca17 100644
--- a/nodes/ba/vp_ba_jam_node.cpp
+++ b/nodes/ba/vp_ba_jam_node.cpp
@@ -60,23 +60,23 @@
 
         // for vp_frame_target only
         std::vector<int> hit_traget_ids;
-        for (auto &target : meta->targets) {
-            if (target->primary_label != target->class_label_of_person) {
-                auto len = target->tracks.size();
-                auto loc = target->get_rect().track_point();
-                // target has been tracked AND tracked enough frames
-                if (len < check_interval_frames || target->track_id < 0) {
-                    continue;
-                }
-                // if target inside of stop region or not
-                if (!point_in_poly(loc, jam_region)) {
-                    continue;
-                }
-                auto pre_loc = target->tracks[len - check_interval_frames].track_point();
-                if (pre_loc.distance_with(loc) <= check_max_distance) {
-                    stop_checking_status[target->track_id]++;
-                    hit_traget_ids.push_back(target->track_id);
-                }
+        for (auto& target : meta->targets) {
+            auto len = target->tracks.size();
+            auto loc = target->get_rect().track_point();
+
+            // target has been tracked AND tracked enough frames
+            if (len < check_interval_frames || target->track_id < 0) {
+                continue;
+            }
+            // if target inside of stop region or not
+            if (!point_in_poly(loc, jam_region)) {
+                continue;
+            }
+
+            auto pre_loc = target->tracks[len - check_interval_frames].track_point();
+            if (pre_loc.distance_with(loc) <= check_max_distance) {
+                stop_checking_status[target->track_id]++;
+                hit_traget_ids.push_back(target->track_id);
             }
         }
 
diff --git a/nodes/ba/vp_ba_jam_node.h b/nodes/ba/vp_ba_jam_node.h
index aa52b25..7048c3b 100644
--- a/nodes/ba/vp_ba_jam_node.h
+++ b/nodes/ba/vp_ba_jam_node.h
@@ -34,9 +34,9 @@
         // jam checking logic parameters which may be configed by constructor passed in by user
         const int check_interval_frames = 20;
         const int check_min_hit_frames = 25 * 2;  // 25 fps * 2 seconds
-        const int check_max_distance = 3;
-        const int check_min_stops = 1;
-        const int check_notify_interval = 15;  // interval time (seconds) to notify (ensure not frequently)
+        const int check_max_distance = 8;
+        const int check_min_stops = 8;
+        const int check_notify_interval = 10;  // interval time (seconds) to notify (ensure not frequently)
     protected:
         virtual std::shared_ptr<vp_objects::vp_meta> handle_frame_meta(std::shared_ptr<vp_objects::vp_frame_meta> meta) override;
     public:
diff --git a/nodes/vp_infer_node.cpp b/nodes/vp_infer_node.cpp
index 099f392..cc86d8e 100644
--- a/nodes/vp_infer_node.cpp
+++ b/nodes/vp_infer_node.cpp
@@ -1,6 +1,6 @@
 
 #include <fstream>
-#include <opencv2/core/cuda.hpp>
+
 #include "vp_infer_node.h"
 
 namespace vp_nodes {
@@ -35,23 +35,8 @@
         try {
             net = cv::dnn::readNet(model_path, model_config_path);
             #ifdef VP_WITH_CUDA
-            // net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
-            // net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
-            // 妫�鏌ュ彲鐢ㄧ殑 GPU 鏁伴噺
-            int gpu_count = cv::cuda::getCudaEnabledDeviceCount();
-            if (gpu_count > 0) {
-                // 鍒濆鍖栭殢鏈烘暟绉嶅瓙骞堕殢鏈洪�夋嫨涓�涓� GPU
-                std::srand(static_cast<unsigned>(std::time(nullptr)));
-                int selected_gpu = std::rand() % gpu_count;
-                // 璁剧疆 CUDA 璁惧骞堕厤缃负浣跨敤鎸囧畾 GPU
-                cv::cuda::setDevice(selected_gpu);
-                net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
-                net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
-
-                VP_INFO(vp_utils::string_format("[%s] Using CUDA on GPU %d", node_name.c_str(), selected_gpu));
-            } else {
-                VP_WARN(vp_utils::string_format("[%s] No CUDA-enabled GPUs detected. Running on CPU.", node_name.c_str()));
-            }
+            net.setPreferableBackend(cv::dnn::DNN_BACKEND_CUDA);
+            net.setPreferableTarget(cv::dnn::DNN_TARGET_CUDA);
             #endif
         }
         catch(const std::exception& e) {
diff --git a/nodes/vp_infer_node.h b/nodes/vp_infer_node.h
index cc2bfb4..a05c21b 100644
--- a/nodes/vp_infer_node.h
+++ b/nodes/vp_infer_node.h
@@ -2,7 +2,6 @@
 
 #pragma once
 #include <sstream>
-#include <opencv2/core/cuda.hpp>
 #include <opencv2/dnn.hpp>
 #include "vp_node.h"
 
diff --git a/nodes/vp_rtsp_ffmpeg_src_node.cpp b/nodes/vp_rtsp_ffmpeg_src_node.cpp
index ce254df..10e5020 100644
--- a/nodes/vp_rtsp_ffmpeg_src_node.cpp
+++ b/nodes/vp_rtsp_ffmpeg_src_node.cpp
@@ -3,13 +3,19 @@
 #include <opencv2/core/core.hpp>
 #include <opencv2/imgproc.hpp>
 #include <opencv2/videoio.hpp>
-
+#include <opencv2/opencv.hpp>
 #include "vp_rtsp_ffmpeg_src_node.h"
 #include "../utils/vp_utils.h"
 #include <cstdio>
 #include <memory>
-#include <iostream>
 #include <stdexcept>
+#include <iostream>
+#include <vector>
+#include <thread>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <cstdlib> // for setting environment variable
 
 namespace vp_nodes
 {
@@ -28,11 +34,7 @@
                                                                                    ffmpeg_pix_fmt(ffmpeg_pix_fmt)
     {
         assert(skip_interval >= 0 && skip_interval <= 9);
-        if (use_gpu)
-        {
-            this->ffmpeg_template = vp_utils::string_format(this->ffmpeg_template, rtsp_url.c_str(), ffmpeg_format.c_str(), ffmpeg_pix_fmt.c_str(), std::to_string(100 + channel_index).c_str());
-        }
-        VP_INFO(vp_utils::string_format("[%s] [%s]", node_name.c_str(), ffmpeg_template.c_str()));
+        VP_INFO(vp_utils::string_format("[%s] [%s]", node_name.c_str(), ffmpeg_format.c_str()));
         this->initialized();
     }
 
@@ -41,9 +43,7 @@
         try
         {
             // FFmpeg command to probe stream metadata
-            std::string ffprobe_command = vp_utils::string_format(
-                "ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate -of csv=p=0 %s",
-                rtsp_url.c_str());
+            std::string ffprobe_command = vp_utils::string_format(ffprobe_template, rtsp_url.c_str());
 
             // Execute command and capture output
             FILE *pipe = popen(ffprobe_command.c_str(), "r");
@@ -59,6 +59,7 @@
                 result += buffer;
             }
             pclose(pipe);
+            VP_INFO(vp_utils::string_format("FFPROBE RESULT:%s ", result));
 
             // Parse the output (expected format: width,height,r_frame_rate)
             std::stringstream ss(result);
@@ -70,7 +71,7 @@
             // Parse width and height
             int video_width = std::stoi(width_str);
             int video_height = std::stoi(height_str);
-            int fps=25;
+            int fps = 25;
 
             // Parse r_frame_rate (e.g., "299/12" or "25")
             if (fps_str.find('/') != std::string::npos)
@@ -86,12 +87,12 @@
                 int denominator = std::stoi(denominator_str);
 
                 // Calculate and round to the nearest integer
-                int fps = static_cast<int>(std::round(static_cast<float>(numerator) / denominator));
+                fps = static_cast<int>(std::round(static_cast<float>(numerator) / denominator));
             }
             else
             {
                 // Handle integer frame rates
-                int fps = std::stoi(fps_str);
+                fps = std::stoi(fps_str);
             }
 
             // Optional: Correct minor deviations (e.g., if fps is close to 25)
@@ -102,10 +103,11 @@
 
             // Debug log for parsed properties
             VP_INFO(vp_utils::string_format("Stream URL:%s Stream properties - Width: %d, Height: %d, FPS: %d",
-                                            rtsp_url, video_width, video_height, fps));
+                                            rtsp_url.c_str(), video_width, video_height, fps));
 
             return std::vector<int>{video_width, video_height, fps};
-        }catch (...)
+        }
+        catch (...)
         {
             return std::vector<int>{0, 0, 0};
         }
@@ -116,38 +118,87 @@
         deinitialized();
     }
 
+    // 瀛愯繘绋嬪惎鍔� ffmpeg 骞惰繑鍥炵閬撴枃浠舵弿杩扮
+    int vp_rtsp_ffmpeg_src_node::start_ffmpeg_thread(const std::string &rtsp_url, int width, int height)
+    {
+
+        int pipe_fd[2];
+        if (pipe(pipe_fd) == -1)
+        {
+            perror("pipe");
+            return -1;
+        }
+
+        pid_t pid = fork();
+        if (pid == -1)
+        {
+            perror("fork");
+            return -1;
+        }
+
+        if (pid == 0) // 瀛愯繘绋�
+        {
+            close(pipe_fd[0]);               // 鍏抽棴璇荤
+            dup2(pipe_fd[1], STDOUT_FILENO); // 灏嗙閬撳啓绔粦瀹氬埌鏍囧噯杈撳嚭
+
+            // 鏍规嵁 channel_index 濂囧伓鏉ヨ缃� GPU
+            //int gpu_id = channel_index % total_gpus; // 鏍规嵁 channel_index 鍜� GPU 鏁伴噺杩涜鍒嗛厤
+            // 璁剧疆鐜鍙橀噺浠ラ�夋嫨 GPU
+            //setenv("CUDA_VISIBLE_DEVICES", std::to_string(gpu_id).c_str(), 1);
+
+            // 鏋勯�� ffmpeg 鍛戒护
+            execlp("ffmpeg", ("ffmpeg-" + std::to_string(channel_index)).c_str(),
+                   "-loglevel", "warning",
+                   "-hwaccel", "cuda",
+                   "-rtsp_transport", "tcp",
+                   "-i", rtsp_url.c_str(),
+                   "-f", ffmpeg_format.c_str(),
+                   "-pix_fmt", ffmpeg_pix_fmt.c_str(),
+                   "-s", (std::to_string(width) + "x" + std::to_string(height)).c_str(),
+                   "pipe:1",
+                   nullptr);
+            exit(EXIT_FAILURE); // 鑻� execlp 澶辫触
+        }
+        else
+        {                      // 鐖惰繘绋�
+            close(pipe_fd[1]); // 鍏抽棴鍐欑
+            return pipe_fd[0]; // 杩斿洖璇荤鏂囦欢鎻忚堪绗�
+        }
+    }
+
     // define how to read video from rtsp stream, create frame meta etc.
     // please refer to the implementation of vp_node::handle_run.
     void vp_rtsp_ffmpeg_src_node::handle_run()
     {
-
         std::vector<int> stream_infos = initialize_stream_properties();
 
-        int original_width = stream_infos[0];
-        int original_height = stream_infos[1];
-        int original_fps = stream_infos[2];
+        original_width = stream_infos[0];
+        original_height = stream_infos[1];
+        original_fps = stream_infos[2];
+
 
         int video_width = original_width;
         int video_height = original_height;
         // set true fps because skip some frames
         int fps = original_fps / (skip_interval + 1);
 
-        cv::Mat frame;
+        cv::Mat frame(original_height, original_width, CV_8UC3);
 
         int skip = 0;
-        FILE* ffmpeg_pipe ;
+        int pipe_fd = -1;
 
-        // Create a pipe buffer to read raw data from FFmpeg
-        size_t frame_size = original_height * original_width * 3; // Adjust this based on expected frame size (e.g., 1920x1080 with RGB)
-        unsigned char *frame_buffer = new unsigned char[frame_size];
+        int frame_size = original_width * original_height * 3; // 鍋囪 BGR24
+        std::vector<unsigned char> frame_buffer(frame_size);
+
+        bool pipe_ok = true;
 
         if (use_gpu)
         {
-            VP_INFO(this->ffmpeg_template);
-            ffmpeg_pipe = popen(this->ffmpeg_template.c_str(), "r");
-            if (!ffmpeg_pipe)
+            pipe_fd = start_ffmpeg_thread(rtsp_url, original_width, original_height);
+            VP_INFO(std::to_string(pipe_fd));
+            if (pipe_fd < 0)
             {
-                VP_WARN("Failed to start FFmpeg process, switching USING CPU.");
+                VP_ERROR(vp_utils::string_format("Failed to start cuda ffmpeg thread for  [%s]", rtsp_url.c_str()));
                 use_gpu = false;
             }
         }
@@ -159,7 +210,6 @@
 
             if (!use_gpu)
             {
-
                 // try to open capture
                 if (!rtsp_capture.isOpened())
                 {
@@ -190,18 +240,60 @@
             }
             else
             {
-                // Read the raw video data from the pipe into a frame
-                if (fread(frame_buffer, sizeof(unsigned char), frame_size, ffmpeg_pipe) <= 0)
-                {
-                    VP_WARN("Failed to read frame from FFmpeg pipe, retrying...");
-                    continue;
-                }
-                // stream_info_hooker activated if need
-                vp_stream_info stream_info{channel_index, original_fps, original_width, original_height, to_string()};
-                invoke_stream_info_hooker(node_name, stream_info);
 
-                // Convert the raw video data into an OpenCV Mat object
-                frame = cv::Mat(original_height, original_width, CV_8UC3, frame_buffer);
+                if (!pipe_ok)  // restart pipe_fd
+                {
+                    pipe_fd = start_ffmpeg_thread(rtsp_url, original_width, original_height);
+
+                }
+
+                size_t total_read = 0;
+
+                // 寰幆璇诲彇锛岀‘淇濅竴甯у畬鏁存暟鎹�
+                while (total_read < frame_size)
+                {
+                    ssize_t bytes_read = read(pipe_fd, frame_buffer.data() + total_read, frame_size - total_read);
+                    if (bytes_read < 0)
+                    { // 璇诲彇閿欒
+                        if (errno == EINTR)
+                        {
+                            // 绯荤粺璋冪敤琚腑鏂紝閲嶈瘯璇诲彇
+                            VP_DEBUG(vp_utils::string_format("Interrupted read for  [%s],re etrying...", rtsp_url.c_str()));
+                            continue;
+                        }
+                        else if (errno == EAGAIN)
+                        {
+                            // 闈為樆濉炴ā寮忎笅鏃犳暟鎹彲璇�
+                            VP_DEBUG(vp_utils::string_format("Io data available yet for  [%s],re etrying...", rtsp_url.c_str()));
+                            std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 绛夊緟鐗囧埢鍐嶈瘯
+                            continue;
+                        }
+                        else
+                        {
+                            // 鍏朵粬涓嶅彲鎭㈠閿欒锛岃褰曟棩蹇楀苟璺宠繃甯�
+                            VP_DEBUG(vp_utils::string_format("Read error for [%s].skipping frame...", rtsp_url.c_str()));
+                            break;
+                        }
+                    }
+                    else if (bytes_read == 0)
+                    { // 娴佺粨鏉�
+                        VP_DEBUG(vp_utils::string_format("Stream ended for [%s].skipping frame...", rtsp_url.c_str()));
+                        pipe_ok = false;
+                        continue; // 缁撴潫璇诲彇
+                    }
+
+                    total_read += bytes_read;
+                }
+
+                // 濡傛灉鏈兘鎴愬姛璇诲彇瀹屾暣甯э紝璁板綍鏃ュ織骞惰烦杩�
+                if (total_read < frame_size)
+                {
+                    VP_DEBUG(vp_utils::string_format("Incomplete frame read for [%s].skipping frame...", rtsp_url.c_str()));
+
+                }
+
+                // 灏嗘暟鎹嫹璐濆埌 OpenCV Mat
+                memcpy(frame.data, frame_buffer.data(), frame_size);
             }
 
             if (frame.empty())
@@ -232,6 +324,12 @@
             video_height = resize_frame.rows;
 
             this->frame_index++;
+            // 鎻掑叆姝ゅ
+            if (frame_index % 1000 == 0) {
+                VP_INFO(vp_utils::string_format(
+                    "Periodic Log - Channel Index: %d, Frame Index: %d, RTSP URL: %s, Use GPU: %s",
+                    channel_index, frame_index, rtsp_url.c_str(), use_gpu ? "true" : "false"));
+            }
             // create frame meta
             auto out_meta =
                 std::make_shared<vp_objects::vp_frame_meta>(resize_frame, this->frame_index, this->channel_index, video_width, video_height, fps);
@@ -253,7 +351,7 @@
         }
         if (use_gpu)
         {
-            fclose(ffmpeg_pipe);
+            close(pipe_fd);
         }
 
         // send dead flag for dispatch_thread
@@ -266,4 +364,4 @@
     {
         return rtsp_url;
     }
-}
\ No newline at end of file
+}
diff --git a/nodes/vp_rtsp_ffmpeg_src_node.h b/nodes/vp_rtsp_ffmpeg_src_node.h
index 4331ff6..ea20c91 100644
--- a/nodes/vp_rtsp_ffmpeg_src_node.h
+++ b/nodes/vp_rtsp_ffmpeg_src_node.h
@@ -1,33 +1,41 @@
 #pragma once
 
 #include <string>
+#include <vector>
+#include <sstream>
+#include <iostream>
 
 #include "vp_src_node.h"
 
-namespace vp_nodes {
+namespace vp_nodes
+{
     // rtsp source node, receive video stream via rtsp protocal.
     // example:
     // rtsp://admin:admin12345@192.168.77.110:554/
-    class vp_rtsp_ffmpeg_src_node: public vp_src_node {
+    class vp_rtsp_ffmpeg_src_node : public vp_src_node
+    {
     private:
         /* data */
-        std::string ffmpeg_template = "ffmpeg -hwaccel cuda -i %s -f %s -pix_fmt %s pipe:%s" ;
+        std::string ffprobe_template = "ffprobe -v error -select_streams v:0 -show_entries stream=width,height,r_frame_rate -of csv=p=0 %s";
         cv::VideoCapture rtsp_capture;
 
-        std::vector<int> initialize_stream_properties() ;
+        std::vector<int> initialize_stream_properties();
+        int start_ffmpeg_thread(const std::string &rtsp_url, int width, int height);
+
 
     protected:
         // re-implemetation
         virtual void handle_run() override;
+
     public:
-        vp_rtsp_ffmpeg_src_node(std::string node_name, 
-                        int channel_index, 
-                        std::string rtsp_url, 
-                        float resize_ratio = 1.0,
-                        int skip_interval = 0,
-                        bool use_gpu = false,
-                        std::string ffmpeg_format = "rawvideo",  // other options: avi/mp4/mov/mkv/flv/gif/h264/hevc
-                        std::string ffmpeg_pix_fmt= "yuv420p");
+        vp_rtsp_ffmpeg_src_node(std::string node_name,
+                                int channel_index,
+                                std::string rtsp_url,
+                                float resize_ratio = 1.0,
+                                int skip_interval = 0,
+                                bool use_gpu = false,
+                                std::string ffmpeg_format = "rawvideo", // other options: avi/mp4/mov/mkv/flv/gif/h264/hevc
+                                std::string ffmpeg_pix_fmt = "bgr24");  // yuv420p 甯﹀灏忎竴鍗婏紝浣嗗仛detection 鏃惰繕闇�瑕佽浆鎹㈡垚bgr24
         ~vp_rtsp_ffmpeg_src_node();
 
         virtual std::string to_string() override;
@@ -37,8 +45,8 @@
         bool use_gpu = false;
 
         std::string ffmpeg_format = "rawvideo";
-        std::string ffmpeg_pix_fmt = "yuv420p";
+        std::string ffmpeg_pix_fmt = "bgr24";
         // 0 means no skip
         int skip_interval = 0;
     };
-}
\ No newline at end of file
+}
diff --git a/nodes/vp_rtsp_src_node.h b/nodes/vp_rtsp_src_node.h
index 89f0854..15f9e18 100644
--- a/nodes/vp_rtsp_src_node.h
+++ b/nodes/vp_rtsp_src_node.h
@@ -11,9 +11,8 @@
     class vp_rtsp_src_node: public vp_src_node {
     private:
         /* data */
-        //std::string gst_template = "rtspsrc location=%s ! application/x-rtp,media=video ! rtph264depay ! h264parse ! %s ! videoconvert ! appsink";
-        std::string gst_template = "rtspsrc location=%s ! rtph264depay ! h264parse ! %s ! videoconvert ! appsink";
-       cv::VideoCapture rtsp_capture;
+        std::string gst_template = "rtspsrc location=%s ! application/x-rtp,media=video ! rtph264depay ! h264parse ! %s ! videoconvert ! appsink";
+        cv::VideoCapture rtsp_capture;
     protected:
         // re-implemetation
         virtual void handle_run() override;
diff --git a/objects/vp_frame_target.h b/objects/vp_frame_target.h
index 5dd262b..ea15e50 100644
--- a/objects/vp_frame_target.h
+++ b/objects/vp_frame_target.h
@@ -28,6 +28,8 @@
     private:
         /* data */
     public:
+        // default person label
+        std::string class_label_of_person = "person";
         // x of top left
         int x;
         // y of top left
@@ -44,8 +46,6 @@
         float primary_score;
         // label created by primary infer nodes
         std::string primary_label;
-        // class id of person
-        std::string class_label_of_person = "person";
 
         // frame the target belongs to
         int frame_index;
diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt
index 312ee6b..39b7238 100644
--- a/samples/CMakeLists.txt
+++ b/samples/CMakeLists.txt
@@ -21,6 +21,21 @@
 add_executable(from_argv_ba_crossline "from_argv_ba_crossline.cpp")
 target_link_libraries(from_argv_ba_crossline ${PROJECT_NAME})
 
+add_executable(from_argv_ba_wrong_direction "from_argv_ba_wrong_direction.cpp")
+target_link_libraries(from_argv_ba_wrong_direction ${PROJECT_NAME})
+
+add_executable(from_argv_ba_person "from_argv_ba_person.cpp")
+target_link_libraries(from_argv_ba_person ${PROJECT_NAME})
+
+add_executable(from_argv_all_in_one_sample "from_argv_all_in_one_sample.cpp")
+target_link_libraries(from_argv_all_in_one_sample ${PROJECT_NAME})
+
+add_executable(from_argv_all_in_one_rtsp "from_argv_all_in_one_rtsp.cpp")
+target_link_libraries(from_argv_all_in_one_rtsp ${PROJECT_NAME})
+
+add_executable(from_argv_all_in_one_rtsp_d "from_argv_all_in_one_rtsp_d.cpp")
+target_link_libraries(from_argv_all_in_one_rtsp_d ${PROJECT_NAME})
+
 add_executable(from_argv_ba_crossline_rtsp "from_argv_ba_crossline_rtsp.cpp")
 target_link_libraries(from_argv_ba_crossline_rtsp ${PROJECT_NAME})
 
@@ -33,6 +48,8 @@
 add_executable(from_argv_face_tracking_rtsp "from_argv_face_tracking_rtsp.cpp")
 target_link_libraries(from_argv_face_tracking_rtsp ${PROJECT_NAME})
 
+add_executable(from_argv_rtsp_test "from_argv_rtsp_test.cpp")
+target_link_libraries(from_argv_rtsp_test ${PROJECT_NAME})
 
 add_executable(image_des_sample "image_des_sample.cpp")
 target_link_libraries(image_des_sample ${PROJECT_NAME})
@@ -109,24 +126,6 @@
 add_executable(vp_test "vp_test.cpp")
 target_link_libraries(vp_test ${PROJECT_NAME})
 
-add_executable(from_argv_ba_wrong_direction "from_argv_ba_wrong_direction.cpp")
-target_link_libraries(from_argv_ba_wrong_direction ${PROJECT_NAME})
-
-add_executable(from_argv_ba_person "from_argv_ba_person.cpp")
-target_link_libraries(from_argv_ba_person ${PROJECT_NAME})
-
-add_executable(from_argv_ba_jam_rtsp "from_argv_ba_jam_rtsp.cpp")
-target_link_libraries(from_argv_ba_jam_rtsp ${PROJECT_NAME})
-
-add_executable(from_argv_ba_stop_rtsp "from_argv_ba_stop_rtsp.cpp")
-target_link_libraries(from_argv_ba_stop_rtsp ${PROJECT_NAME})
-
-add_executable(from_argv_ba_jam_rtsp_d "from_argv_ba_jam_rtsp_d.cpp")
-target_link_libraries(from_argv_ba_jam_rtsp_d ${PROJECT_NAME})
-
-add_executable(from_argv_ba_stop_rtsp_d "from_argv_ba_stop_rtsp_d.cpp")
-target_link_libraries(from_argv_ba_stop_rtsp_d ${PROJECT_NAME})
-
 # samples depend on Kafka
 if(VP_WITH_KAFKA)
     add_executable(message_broker_kafka_sample "message_broker_kafka_sample.cpp")
@@ -160,6 +159,16 @@
     add_executable(from_argv_ba_jam "from_argv_ba_jam.cpp")
     target_link_libraries(from_argv_ba_jam ${PROJECT_NAME})
 
+    add_executable(from_argv_ba_jam_rtsp "from_argv_ba_jam_rtsp.cpp")
+    target_link_libraries(from_argv_ba_jam_rtsp ${PROJECT_NAME})
+
+    add_executable(from_argv_ba_jam_rtsp_d "from_argv_ba_jam_rtsp_d.cpp")
+    target_link_libraries(from_argv_ba_jam_rtsp_d ${PROJECT_NAME})
+
+    add_executable(from_argv_ba_jam_rtsp_m "from_argv_ba_jam_rtsp_m.cpp")
+    target_link_libraries(from_argv_ba_jam_rtsp_m ${PROJECT_NAME})
+
+
     add_executable(from_argv_ba_stop "from_argv_ba_stop.cpp")
     target_link_libraries(from_argv_ba_stop ${PROJECT_NAME})
 
diff --git a/samples/ba_stop_sample_rtsp.cpp b/samples/ba_stop_sample_rtsp.cpp
deleted file mode 100644
index 5df3d36..0000000
--- a/samples/ba_stop_sample_rtsp.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "../nodes/vp_file_src_node.h"
-#include "../nodes/infers/vp_trt_vehicle_detector.h"
-#include "../nodes/track/vp_sort_track_node.h"
-#include "../nodes/ba/vp_ba_stop_node.h"
-#include "../nodes/osd/vp_ba_stop_osd_node.h"
-#include "../nodes/vp_split_node.h"
-#include "../nodes/vp_screen_des_node.h"
-
-#include "../utils/analysis_board/vp_analysis_board.h"
-
-/*
-* ## ba stop sample ##
-* behaviour analysis for stop, single instance of ba node work on 2 channels.
-*/
-
-int main() {
-    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
-    VP_LOGGER_INIT();
-
-    // create nodes
-    auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, "./vp_data/test_video/vehicle_stop.mp4", 0.6);
-    auto file_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_1", 1, "./vp_data/test_video/vehicle_stop.mp4", 0.6);
-    auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", "./vp_data//models/trt/vehicle/vehicle_detection.trt");
-    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
-    
-    // define a region in frame for every channel (value MUST in the scope of frame'size)
-    std::map<int, std::vector<vp_objects::vp_point>> regions = {
-        {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(20, 30), vp_objects::vp_point(600, 40), vp_objects::vp_point(600, 300), vp_objects::vp_point(10, 300)}},  // channel0 -> region
-        {1, std::vector<vp_objects::vp_point>{vp_objects::vp_point(20, 30), vp_objects::vp_point(1000, 40), vp_objects::vp_point(1000, 600), vp_objects::vp_point(10, 600)}}   // channel1 -> region
-    };
-    auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
-    auto osd = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd");
-    auto split = std::make_shared<vp_nodes::vp_split_node>("split", true);
-    auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
-    auto screen_des_1 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_1", 1);
-    
-    // construct pipeline
-    trt_vehicle_detector->attach_to({file_src_0, file_src_1});
-    tracker->attach_to({trt_vehicle_detector});
-    ba_stop->attach_to({tracker});
-    osd->attach_to({ba_stop});
-    split->attach_to({osd});
-    screen_des_0->attach_to({split});
-    screen_des_1->attach_to({split});
-
-    file_src_0->start();
-    file_src_1->start();
-
-    // for debug purpose
-    vp_utils::vp_analysis_board board({file_src_0, file_src_1});
-    board.display();
-}
\ No newline at end of file
diff --git a/samples/config.json b/samples/config.json
deleted file mode 100644
index e1164ae..0000000
--- a/samples/config.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-    "rtsp_sources": {
-        "1": "rtsp://192.168.1.24:8554/demo",
-        "2": "rtsp://192.168.1.24:8554/demo",
-        "3": "rtsp://192.168.1.24:8554/demo",
-        "4": "rtsp://192.168.1.24:8554/demo",
-        "5": "rtsp://192.168.1.24:8554/demo",
-        "6": "rtsp://192.168.1.24:8554/demo",
-        "7": "rtsp://192.168.1.24:8554/demo",
-        "8": "rtsp://192.168.1.24:8554/demo",
-        "9": "rtsp://192.168.1.24:8554/demo",
-        "10": "rtsp://192.168.1.24:8554/demo"
-    },
-    "resize_ratio": 0.4,
-    "kafka_server": "192.168.0.85:9092",
-    "region_points": {
-        "1": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "2": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "3": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "4": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "5": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "6": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "7": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "8": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "9": [[0, 520], [450, 50], [650, 50], [1000, 520]],
-        "10": [[0, 520], [450, 50], [650, 50], [1000, 520]]
-    }
-}
\ No newline at end of file
diff --git a/samples/face_recognize/README.md b/samples/face_recognize/README.md
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/README.pdf b/samples/face_recognize/README.pdf
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/face_recognize/clean.sh b/samples/face_recognize/clean.sh
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/docs/1.png b/samples/face_recognize/docs/1.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/face_recognize/face_recognize_pipeline b/samples/face_recognize/face_recognize_pipeline
index 15f7969..45dca69 100755
--- a/samples/face_recognize/face_recognize_pipeline
+++ b/samples/face_recognize/face_recognize_pipeline
Binary files differ
diff --git a/samples/face_recognize/face_recognize_pipeline.cpp b/samples/face_recognize/face_recognize_pipeline.cpp
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/face_recognize_server.py b/samples/face_recognize/face_recognize_server.py
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/static/cropped_faces/readme.txt b/samples/face_recognize/static/cropped_faces/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/static/dist/DPlayer.min.js b/samples/face_recognize/static/dist/DPlayer.min.js
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/static/dist/DPlayer.min.js.map b/samples/face_recognize/static/dist/DPlayer.min.js.map
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/static/dist/flv.min.js b/samples/face_recognize/static/dist/flv.min.js
old mode 100755
new mode 100644
diff --git "a/samples/face_recognize/static/user_register_infos/0001-\350\265\265\346\234\254\345\261\261-\347\224\267-66-\351\223\201\345\262\255.png" "b/samples/face_recognize/static/user_register_infos/0001-\350\265\265\346\234\254\345\261\261-\347\224\267-66-\351\223\201\345\262\255.png"
old mode 100755
new mode 100644
Binary files differ
diff --git "a/samples/face_recognize/static/user_register_infos/0002-\346\235\250\346\276\234-\345\245\263-54-\345\214\227\344\272\254.png" "b/samples/face_recognize/static/user_register_infos/0002-\346\235\250\346\276\234-\345\245\263-54-\345\214\227\344\272\254.png"
old mode 100755
new mode 100644
Binary files differ
diff --git "a/samples/face_recognize/static/user_register_infos/0003-\345\221\250\346\231\272-\347\224\267-34-\346\255\246\346\261\211.png" "b/samples/face_recognize/static/user_register_infos/0003-\345\221\250\346\231\272-\347\224\267-34-\346\255\246\346\261\211.png"
old mode 100755
new mode 100644
Binary files differ
diff --git "a/samples/face_recognize/static/user_register_infos/0004-\345\210\230\345\276\267\345\215\216-\347\224\267-64-\351\246\231\346\270\257.png" "b/samples/face_recognize/static/user_register_infos/0004-\345\210\230\345\276\267\345\215\216-\347\224\267-64-\351\246\231\346\270\257.png"
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/face_recognize/templates/home.html b/samples/face_recognize/templates/home.html
old mode 100755
new mode 100644
diff --git a/samples/face_recognize/vp_analysis_board.png b/samples/face_recognize/vp_analysis_board.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/firesmoke_detect_sample.cpp b/samples/firesmoke_detect_sample.cpp
index f1b0978..4bf20c5 100644
--- a/samples/firesmoke_detect_sample.cpp
+++ b/samples/firesmoke_detect_sample.cpp
@@ -2,6 +2,8 @@
 #include "../nodes/infers/vp_yolo_detector_node.h"
 #include "../nodes/osd/vp_osd_node.h"
 #include "../nodes/vp_split_node.h"
+#include "../nodes/vp_sync_node.h"
+
 #include "../nodes/vp_screen_des_node.h"
 #include "../nodes/vp_rtsp_des_node.h"
 
@@ -19,28 +21,65 @@
     // create nodes
     auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, "./vp_data/test_video/smoke2.mp4", 0.5);
     auto file_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_1", 1, "./vp_data/test_video/fire.mp4", 0.5);
-    auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("firesmoke_detector", "./vp_data/models/det_cls/firesmoke_yolov5s.onnx", "", "./vp_data/models/det_cls/firesmoke_3classes.txt", 640, 384);
+    auto split0 = std::make_shared<vp_nodes::vp_split_node>("split0", false, true);  // split by deep-copy not by channel!
+   
+    auto yolo_detector0 = std::make_shared<vp_nodes::vp_yolo_detector_node>("firesmoke_detector", "./vp_data/models/det_cls/firesmoke_yolov5s.onnx", "", "./vp_data/models/det_cls/firesmoke_3classes.txt", 640, 384);
+    auto yolo_detector1 = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
+
     auto osd = std::make_shared<vp_nodes::vp_osd_node>("osd");
-    auto split = std::make_shared<vp_nodes::vp_split_node>("split_by_channel", true);
+    auto sync = std::make_shared<vp_nodes::vp_sync_node>("sync");
     auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);    
-    auto srceen_des_1 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_1", 1);
+    auto screen_des_1 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_1", 1);
+    auto split = std::make_shared<vp_nodes::vp_split_node>("split", true);  // split by deep-copy not by channel!
 
     // construct pipeline
-    yolo_detector->attach_to({file_src_0, file_src_1});
-    osd->attach_to({yolo_detector});
+    split0->attach_to({file_src_0,file_src_1});
+    yolo_detector0->attach_to({split0});
+    yolo_detector1->attach_to({split0});
+    sync->attach_to({yolo_detector0, yolo_detector1});
+    osd->attach_to({sync});
     split->attach_to({osd});
     screen_des_0->attach_to({split});
-    srceen_des_1->attach_to({split});
+    screen_des_1->attach_to({split});
 
     file_src_0->start();
     file_src_1->start();
 
+    // create nodes
+    auto file_src_01 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_01", 2, "./vp_data/test_video/smoke2.mp4", 0.5);
+    auto file_src_11 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_11", 3, "./vp_data/test_video/fire.mp4", 0.5);
+    auto split01 = std::make_shared<vp_nodes::vp_split_node>("split01", false, true);  // split by deep-copy not by channel!
+   
+    auto yolo_detector01 = std::make_shared<vp_nodes::vp_yolo_detector_node>("firesmoke_detector1", "./vp_data/models/det_cls/firesmoke_yolov5s.onnx", "", "./vp_data/models/det_cls/firesmoke_3classes.txt", 640, 384);
+    auto yolo_detector11 = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_detector1", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
+
+    auto osd1 = std::make_shared<vp_nodes::vp_osd_node>("osd1");
+    auto sync1 = std::make_shared<vp_nodes::vp_sync_node>("sync1");
+    auto screen_des_01 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_01", 2);    
+    auto screen_des_11 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_11", 3);
+    auto split1 = std::make_shared<vp_nodes::vp_split_node>("split1", true);  // split by deep-copy not by channel!
+
+    // construct pipeline
+    split01->attach_to({file_src_01,file_src_11});
+    yolo_detector01->attach_to({split01});
+    yolo_detector11->attach_to({split01});
+    sync1->attach_to({yolo_detector01, yolo_detector11});
+    osd1->attach_to({sync1});
+    split1->attach_to({osd1});
+    screen_des_01->attach_to({split1});
+    screen_des_11->attach_to({split1});
+
+    file_src_01->start();
+    file_src_11->start();
+
     // for debug purpose
-    vp_utils::vp_analysis_board board({file_src_0, file_src_1});
-    board.display(1, false);
+    //vp_utils::vp_analysis_board board({file_src_0, file_src_1,file_src_01,file_src_11});
+    //board.display(1, false);
 
     std::string wait;
     std::getline(std::cin, wait);
     file_src_0->detach_recursively();
     file_src_1->detach_recursively();
+    file_src_01->detach_recursively();
+    file_src_11->detach_recursively();
 }
\ No newline at end of file
diff --git a/samples/from_argv_all_in_one_rtsp.cpp b/samples/from_argv_all_in_one_rtsp.cpp
index d943159..e08ed54 100644
--- a/samples/from_argv_all_in_one_rtsp.cpp
+++ b/samples/from_argv_all_in_one_rtsp.cpp
@@ -36,31 +36,43 @@
     VP_LOGGER_INIT();
 
     std::vector<std::string> args(argv + 1, argv + argc);
+
     // 榛樿鐨勫懡浠よ鍙傛暟
     std::string rtsp_path = "rtsp://127.0.0.1:8554/demo";
     std::string kafka_server_point = "127.0.0.1:9092";
-
     float resize_ratio = 0.4;
     int skip_interval = 3;
     int channel_index = 21;
+    bool usegpu = false; // 鏂板鍙傛暟锛岄粯璁ゅ�间负 false
 
-    // 濡傛灉鎻愪緵浜嗙涓�涓拰绗簩涓弬鏁帮紝鍒欒鐩栭粯璁ょ殑璺緞
-    if (args.size() >= 5) {
+    // 濡傛灉鎻愪緵浜嗚嚦灏� 6 涓弬鏁帮紝鍒欒鐩栭粯璁ゅ��
+    if (args.size() >= 6) {
         rtsp_path = args[0];
         resize_ratio = std::stof(args[1]);
         kafka_server_point = args[2];
         skip_interval = std::stoi(args[3]);
         channel_index = std::stoi(args[4]);
+        std::string usegpu_arg = args[5];
+        // 灏嗗瓧绗︿覆杞崲涓哄竷灏斿�硷紝鏀寔 true/false 鎴� 1/0
+        std::transform(usegpu_arg.begin(), usegpu_arg.end(), usegpu_arg.begin(), ::tolower);
+        if (usegpu_arg == "true" || usegpu_arg == "1") {
+            usegpu = true;
+        } else if (usegpu_arg == "false" || usegpu_arg == "0") {
+            usegpu = false;
+        } else {
+            std::cerr << "Invalid value for <usegpu>. Please use 'true', 'false', '1', or '0'.\n";
+            return -1;
+        }
     } else {
-        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point> <skip_interval>\n";
-        std::cout << "Example: " << argv[0] << " rtsp://admin:Shmixcqwe%21%40%23@172.18.10.113/Streaming/Channels/101 0.4 172.18.0.247:9092 5 21 \n";
+        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point> <skip_interval> <channel_index> <usegpu>\n";
+        std::cout << "Example: " << argv[0] << " rtsp://127.0.0.1:8554/demo 0.4 127.0.0.1:9092 5 21 true\n";
         return -1;
     }
 
     // create nodes
     //auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio);
     //auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264", skip_interval); 
-    auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>("rtsp_src_1", channel_index, rtsp_path, resize_ratio, skip_interval); 
+    auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>("rtsp_src_1", channel_index, rtsp_path, resize_ratio, skip_interval, usegpu); 
     //auto file_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_1", 1, "./vp_data/test_video/falldown.mp4", 0.5);
     //auto split = std::make_shared<vp_nodes::vp_split_node>("split", false, true);  // split by deep-copy not by channel!
     
@@ -74,8 +86,8 @@
     
     // define a region in frame for every channel (value MUST in the scope of frame'size)
     std::map<int, std::vector<vp_objects::vp_point>> regions = {
-        {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(20, 30), vp_objects::vp_point(600, 40), vp_objects::vp_point(600, 300), vp_objects::vp_point(10, 300)}},  // channel0 -> region
-        {1, std::vector<vp_objects::vp_point>{vp_objects::vp_point(20, 30), vp_objects::vp_point(1000, 40), vp_objects::vp_point(1000, 600), vp_objects::vp_point(10, 600)}}   // channel1 -> region
+        {channel_index, std::vector<vp_objects::vp_point>{vp_objects::vp_point(290, 10), vp_objects::vp_point(340, 10), vp_objects::vp_point(600, 330), vp_objects::vp_point(40, 350)}},  // channel0 -> region
+        {1, std::vector<vp_objects::vp_point>{vp_objects::vp_point(290, 10), vp_objects::vp_point(340, 10), vp_objects::vp_point(600, 330), vp_objects::vp_point(40, 350)}}   // channel1 -> region
     };
     auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
     auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
diff --git a/samples/from_argv_all_in_one_rtsp_d.cpp b/samples/from_argv_all_in_one_rtsp_d.cpp
new file mode 100644
index 0000000..9eac353
--- /dev/null
+++ b/samples/from_argv_all_in_one_rtsp_d.cpp
@@ -0,0 +1,137 @@
+#include "../nodes/vp_file_src_node.h"
+#include "../nodes/vp_rtsp_src_node.h"
+#include "../nodes/vp_rtsp_ffmpeg_src_node.h"
+#include "../nodes/vp_split_node.h"
+#include "../nodes/infers/vp_trt_vehicle_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_plate_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_color_classifier.h"
+#include "../nodes/infers/vp_yolo_detector_node.h"
+
+#include "../nodes/osd/vp_osd_node.h"
+#include "../nodes/vp_sync_node.h"
+#include "../nodes/track/vp_sort_track_node.h"
+#include "../nodes/ba/vp_ba_jam_node.h"
+#include "../nodes/ba/vp_ba_stop_node.h"
+#include "../nodes/ba/vp_ba_wrong_direction_node.h"
+#include "../nodes/ba/vp_ba_person_gathering_node.h"
+#include "../nodes/ba/vp_ba_person_falldown_node.h"
+#include "../nodes/ba/vp_ba_report_detect_node.h"
+
+#include "../nodes/osd/vp_ba_stop_osd_node.h"
+#include "../nodes/broker/vp_json_kafka_broker_node.h"
+#include "../nodes/record/vp_record_node.h"
+#include "../nodes/vp_screen_des_node.h"
+#include "../nodes/vp_fake_des_node.h"
+#include "../nodes/vp_placeholder_node.h"
+
+#include "../utils/analysis_board/vp_analysis_board.h"
+
+/*
+* ## firesmoke_detect_sample ##
+* detect firesmoke using yolo.
+*/
+
+int main(int argc, char* argv[]) {
+    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
+    VP_LOGGER_INIT();
+
+    std::vector<std::string> args(argv + 1, argv + argc);
+    // 榛樿鐨勫懡浠よ鍙傛暟
+    std::string rtsp_path = "rtsp://127.0.0.1:8554/demo";
+    std::string kafka_server_point = "127.0.0.1:9092";
+
+    float resize_ratio = 0.4;
+    int skip_interval = 3;
+    int channel_index = 21;
+
+    // 濡傛灉鎻愪緵浜嗙涓�涓拰绗簩涓弬鏁帮紝鍒欒鐩栭粯璁ょ殑璺緞
+    if (args.size() >= 5) {
+        rtsp_path = args[0];
+        resize_ratio = std::stof(args[1]);
+        kafka_server_point = args[2];
+        skip_interval = std::stoi(args[3]);
+        channel_index = std::stoi(args[4]);
+    } else {
+        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point> <skip_interval>\n";
+        std::cout << "Example: " << argv[0] << " rtsp://admin:Shmixcqwe%21%40%23@172.18.10.113/Streaming/Channels/101 0.4 172.18.0.247:9092 5 21 \n";
+        return -1;
+    }
+
+    // create nodes
+    //auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio);
+    //auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264", skip_interval); 
+    auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>("rtsp_src_1", channel_index, rtsp_path, resize_ratio, skip_interval, true); 
+    //auto file_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_1", 1, "./vp_data/test_video/falldown.mp4", 0.5);
+    //auto split = std::make_shared<vp_nodes::vp_split_node>("split", false, true);  // split by deep-copy not by channel!
+    
+    //branch 0
+    //auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", "./vp_data/models/trt/vehicle/vehicle_detection.trt");
+    auto vehicle_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("vehicle_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
+    auto trt_vehicle_plate_detector = std::make_shared<vp_nodes::vp_trt_vehicle_plate_detector>("vehicle_plate_detector", "./vp_data/models/trt/plate/vehicle_plate_box_detection.trt", "./vp_data/models/trt/plate/vehicle_plate_text_recognition.trt");
+    auto trt_vehicle_color_classifier = std::make_shared<vp_nodes::vp_trt_vehicle_color_classifier>("color_cls", "./vp_data/models/trt/vehicle/vehicle_color_detection.trt", std::vector<int>{0, 1, 2});
+    
+    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
+    
+    // define a region in frame for every channel (value MUST in the scope of frame'size)
+    std::map<int, std::vector<vp_objects::vp_point>> regions = {
+        {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(290, 10), vp_objects::vp_point(340, 10), vp_objects::vp_point(610, 330), vp_objects::vp_point(40, 350)}},  // channel0 -> region
+        {1, std::vector<vp_objects::vp_point>{vp_objects::vp_point(290, 10), vp_objects::vp_point(340, 10), vp_objects::vp_point(610, 330), vp_objects::vp_point(40, 350)}}   // channel1 -> region
+    };
+    auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
+    auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
+    
+    // define a line in frame for every channel (value MUST in the scope of frame'size)
+    vp_objects::vp_point left_start(10, 10);  // change to proper value
+    vp_objects::vp_point left_end(10, 20);  // change to proper value
+    vp_objects::vp_point right_start(10, 20);  // change to proper value
+    vp_objects::vp_point right_end(10, 10);  // change to proper value
+    std::map<int, std::vector<vp_objects::vp_point>> left_lines = {{0, {left_start, left_end}}};  // channel0 -> point vector
+    std::map<int, std::vector<vp_objects::vp_point>> right_lines = {{0, {right_start, right_end}}};  // channel0 -> point vector
+    int half_screen_width = 800;
+    auto ba_wrong_direction = std::make_shared<vp_nodes::vp_ba_wrong_direction_node>("vp_ba_wrong_direction_node", left_lines,right_lines,half_screen_width,true,true);
+       
+    int min_gathering_count = 2;
+    auto ba_person_gathering = std::make_shared<vp_nodes::vp_ba_person_gathering_node>("vp_ba_person_gathering_node", min_gathering_count,true,true);
+    auto ba_person_falldown = std::make_shared<vp_nodes::vp_ba_person_falldown_node>("vp_ba_person_falldown_node", true,true);
+  
+    auto firesmoke_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("firesmoke_detector", "./vp_data/models/det_cls/firesmoke_yolov5s.onnx", "", "./vp_data/models/det_cls/firesmoke_3classes.txt", 640, 384,1,1000,0.8,0.8);
+    auto ba_report_detect = std::make_shared<vp_nodes::vp_ba_report_detect_node>("ba_report_detect_node","fire_smoke",std::vector<int>{1000,1001,1002}, true,true);
+
+
+    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_result", vp_nodes::vp_broke_for::BARESULT);
+    auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
+    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
+    
+    // for testing. USING fake_des node in production 
+    auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);    
+    auto fake_des_0 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_0", 0);
+
+    // construct pipeline
+    vehicle_detector->attach_to({file_src_0});
+    trt_vehicle_plate_detector->attach_to({vehicle_detector});
+    trt_vehicle_color_classifier->attach_to({trt_vehicle_plate_detector});
+    tracker->attach_to({trt_vehicle_color_classifier});
+    ba_jam->attach_to({tracker});
+    ba_stop->attach_to({ba_jam});
+    ba_wrong_direction->attach_to({ba_stop});
+    ba_person_gathering->attach_to({ba_wrong_direction});
+    ba_person_falldown->attach_to({ba_person_gathering});
+    firesmoke_detector->attach_to({ba_person_falldown});
+    ba_report_detect->attach_to({firesmoke_detector});
+    json_kafka_broker_0->attach_to({ba_report_detect});
+    osd_0->attach_to({json_kafka_broker_0});
+
+    recorder->attach_to({osd_0});
+    screen_des_0->attach_to({recorder});
+
+    file_src_0->start();
+
+    // for debug purpose
+    vp_utils::vp_analysis_board board({file_src_0});
+    board.display(1, false);
+
+    std::string wait;
+    std::getline(std::cin, wait);
+    file_src_0->detach_recursively();
+   
+}
\ No newline at end of file
diff --git a/samples/from_argv_all_in_one_sample.cpp b/samples/from_argv_all_in_one_sample.cpp
index 7061e85..4a9a54a 100644
--- a/samples/from_argv_all_in_one_sample.cpp
+++ b/samples/from_argv_all_in_one_sample.cpp
@@ -91,7 +91,7 @@
 
 
     auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", "192.168.0.85:9092", "vp_ba_vehicle", vp_nodes::vp_broke_for::BARESULT);
-    auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
+    auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0");
     auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
     
     // for testing. USING fake_des node in production 
diff --git a/samples/from_argv_ba_crossline_rtsp.cpp b/samples/from_argv_ba_crossline_rtsp.cpp
index 0b483bb..2f529a1 100644
--- a/samples/from_argv_ba_crossline_rtsp.cpp
+++ b/samples/from_argv_ba_crossline_rtsp.cpp
@@ -1,6 +1,5 @@
 #include "../nodes/vp_file_src_node.h"
 #include "../nodes/vp_rtsp_src_node.h"
-#include "../nodes/vp_rtsp_ffmpeg_src_node.h"
 
 #include "../nodes/infers/vp_yolo_detector_node.h"
 #include "../nodes/track/vp_sort_track_node.h"
@@ -34,6 +33,7 @@
         rtsp_path = args[0];
         resize_ratio = std::stof(args[1]);
         kafka_server_point = args[2];
+        
     } else {
         std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point>\n";
         std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.130.228:9092\n";
@@ -43,7 +43,7 @@
 
     // create nodes
     //auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio);
-    auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio,0,true); 
+    auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264"); 
     auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
     auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
     
diff --git a/samples/from_argv_ba_jam_rtsp.cpp b/samples/from_argv_ba_jam_rtsp.cpp
index 7f4aa05..f8ae0db 100644
--- a/samples/from_argv_ba_jam_rtsp.cpp
+++ b/samples/from_argv_ba_jam_rtsp.cpp
@@ -1,120 +1,122 @@
-#include "../nodes/vp_file_src_node.h"
-#include "../nodes/vp_rtsp_src_node.h"
-#include "../nodes/infers/vp_yolo_detector_node.h"
-#include "../nodes/track/vp_sort_track_node.h"
-#include "../nodes/ba/vp_ba_jam_node.h"
-#include "../nodes/osd/vp_ba_jam_osd_node.h"
-#include "../nodes/vp_screen_des_node.h"
-#include "../nodes/vp_rtmp_des_node.h"
-#include "../nodes/broker/vp_json_kafka_broker_node.h"
-#include "../nodes/vp_file_des_node.h"
-#include "../nodes/vp_split_node.h"
-#include "../nodes/record/vp_record_node.h"
-#include "../nodes/vp_fake_des_node.h"
-#include "../utils/analysis_board/vp_analysis_board.h"
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <map>
-#include <memory>
-
-int main(int argc, char* argv[]) {
-    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::WARN);
-    VP_LOGGER_INIT();
-
-    std::vector<std::string> args(argv + 1, argv + argc);
-
-    // 榛樿鐨勫懡浠よ鍙傛暟
-    std::string rtsp_base_url = "rtsp://192.168.1.24:8554/demo";
-    std::string kafka_server_point = "192.168.0.85:9092";
-    float resize_ratio = 0.4;
-
-    std::vector<std::string> rtsp_urls; 
-
-
-    // 瑙f瀽鍛戒护琛屽弬鏁�
-    if (args.size() >= 22) {
-        for (int i = 0; i < 20; ++i) {
-            rtsp_urls.push_back(args[i]); 
-        }
-        resize_ratio = std::stof(args[20]);
-        kafka_server_point = args[21];
-    } else {
-        std::cout << "Usage: " << argv[0] << " <rtsp_path_1> ... <rtsp_path_20> <resize_ratio> <kafka_server_point>\n";
-        std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.0.85:9092\n";
-        return -1;
-    }
-
-    // Create RTSP source nodes
-    std::vector<std::shared_ptr<vp_nodes::vp_rtsp_src_node>> rtsp_sources;
-    for (int i = 0; i < 20; ++i) {
-        rtsp_sources.push_back(std::make_shared<vp_nodes::vp_rtsp_src_node>(
-            "rtsp_src_" + std::to_string(i + 1), i + 1, rtsp_urls[i], resize_ratio, "avdec_h264"));
-    }
-    
-    auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_detector",
-        "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights",
-        "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg",
-        "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
-
-    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
-
-    // Define regions for every channel
-    auto define_regions = [](int num_sources) {
-        std::map<int, std::vector<vp_objects::vp_point>> regions;
-        for (int i = 1; i <= num_sources; ++i) {
-            regions[i] = std::vector<vp_objects::vp_point>{
-                vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50),
-                vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)};
-        }
-        return regions;
-    };
-
-    auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", define_regions(20));
-
-    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>(
-        "json_kafka_broker_0", kafka_server_point, "vp_ba_jam", vp_nodes::vp_broke_for::BARESULT);
-
-    auto osd = std::make_shared<vp_nodes::vp_ba_jam_osd_node>("osd");
-    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
-    auto split = std::make_shared<vp_nodes::vp_split_node>("split", true);
-    // Create 20 fake destination nodes, one for each channel
-    std::vector<std::shared_ptr<vp_nodes::vp_fake_des_node>> fake_des_nodes;
-    for (int i = 1; i <= 20; ++i) {
-        fake_des_nodes.push_back(std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_" + std::to_string(i), i));
-    }
-
-    // Construct pipeline
-    for (auto& rtsp_source : rtsp_sources) {
-        yolo_detector->attach_to({rtsp_source});
-    }
-
-    tracker->attach_to({yolo_detector});
-    ba_jam->attach_to({tracker});
-
-    json_kafka_broker_0->attach_to({ba_jam});
-    osd->attach_to({json_kafka_broker_0});
-    recorder->attach_to({osd});
-    split->attach_to({recorder});
-
-    // Attach fake destination nodes (one for each channel)
-    for (auto& fake_des_node : fake_des_nodes) {
-        fake_des_node->attach_to({split});
-    }
-
-    // Start RTSP sources
-    for (auto& rtsp_source : rtsp_sources) {
-        rtsp_source->start();
-    }
-
-    std::string wait;
-    std::getline(std::cin, wait);
-
-    // Cleanup
-    for (auto& rtsp_source : rtsp_sources) {
-        rtsp_source->detach_recursively();
-    }
-
-    return 0;
-}
+#include "../nodes/vp_file_src_node.h"
+#include "../nodes/vp_rtsp_src_node.h"
+#include "../nodes/vp_rtsp_ffmpeg_src_node.h"
+#include "../nodes/vp_split_node.h"
+#include "../nodes/infers/vp_trt_vehicle_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_plate_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_color_classifier.h"
+#include "../nodes/infers/vp_yolo_detector_node.h"
+
+#include "../nodes/osd/vp_osd_node.h"
+#include "../nodes/vp_sync_node.h"
+#include "../nodes/track/vp_sort_track_node.h"
+#include "../nodes/ba/vp_ba_jam_node.h"
+#include "../nodes/ba/vp_ba_stop_node.h"
+
+#include "../nodes/osd/vp_ba_stop_osd_node.h"
+#include "../nodes/broker/vp_json_kafka_broker_node.h"
+#include "../nodes/record/vp_record_node.h"
+#include "../nodes/vp_screen_des_node.h"
+#include "../nodes/vp_fake_des_node.h"
+#include "../nodes/vp_placeholder_node.h"
+
+#include "../utils/analysis_board/vp_analysis_board.h"
+
+/*
+* ## firesmoke_detect_sample ##
+* detect firesmoke using yolo.
+*/
+
+int main(int argc, char* argv[]) {
+    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
+    VP_LOGGER_INIT();
+
+    std::vector<std::string> args(argv + 1, argv + argc);
+
+    // 榛樿鐨勫懡浠よ鍙傛暟
+    std::string rtsp_path = "rtsp://127.0.0.1:8554/demo";
+    std::string kafka_server_point = "127.0.0.1:9092";
+    float resize_ratio = 0.4;
+    int skip_interval = 3;
+    int channel_index = 21;
+    bool usegpu = false; // 鏂板鍙傛暟锛岄粯璁ゅ�间负 false
+
+    // 濡傛灉鎻愪緵浜嗚嚦灏� 6 涓弬鏁帮紝鍒欒鐩栭粯璁ゅ��
+    if (args.size() >= 6) {
+        rtsp_path = args[0];
+        resize_ratio = std::stof(args[1]);
+        kafka_server_point = args[2];
+        skip_interval = std::stoi(args[3]);
+        channel_index = std::stoi(args[4]);
+        std::string usegpu_arg = args[5];
+        // 灏嗗瓧绗︿覆杞崲涓哄竷灏斿�硷紝鏀寔 true/false 鎴� 1/0
+        std::transform(usegpu_arg.begin(), usegpu_arg.end(), usegpu_arg.begin(), ::tolower);
+        if (usegpu_arg == "true" || usegpu_arg == "1") {
+            usegpu = true;
+        } else if (usegpu_arg == "false" || usegpu_arg == "0") {
+            usegpu = false;
+        } else {
+            std::cerr << "Invalid value for <usegpu>. Please use 'true', 'false', '1', or '0'.\n";
+            return -1;
+        }
+    } else {
+        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point> <skip_interval> <channel_index> <usegpu>\n";
+        std::cout << "Example: " << argv[0] << " rtsp://127.0.0.1:8554/demo 0.4 127.0.0.1:9092 5 21 true\n";
+        return -1;
+    }
+
+    // create nodes
+    //auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio);
+    //auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264", skip_interval); 
+    auto file_src_0 = std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>("rtsp_src_1", channel_index, rtsp_path, resize_ratio, skip_interval, usegpu); 
+    //auto file_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_1", 1, "./vp_data/test_video/falldown.mp4", 0.5);
+    //auto split = std::make_shared<vp_nodes::vp_split_node>("split", false, true);  // split by deep-copy not by channel!
+    
+    //branch 0
+    //auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", "./vp_data/models/trt/vehicle/vehicle_detection.trt");
+    auto vehicle_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("vehicle_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
+    auto trt_vehicle_plate_detector = std::make_shared<vp_nodes::vp_trt_vehicle_plate_detector>("vehicle_plate_detector", "./vp_data/models/trt/plate/vehicle_plate_box_detection.trt", "./vp_data/models/trt/plate/vehicle_plate_text_recognition.trt");
+    auto trt_vehicle_color_classifier = std::make_shared<vp_nodes::vp_trt_vehicle_color_classifier>("color_cls", "./vp_data/models/trt/vehicle/vehicle_color_detection.trt", std::vector<int>{0, 1, 2});
+    
+    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
+    
+    // define a region in frame for every channel (value MUST in the scope of frame'size)
+    std::map<int, std::vector<vp_objects::vp_point>> regions = {
+        {channel_index, std::vector<vp_objects::vp_point>{vp_objects::vp_point(280, 30), vp_objects::vp_point(340, 30), vp_objects::vp_point(600, 330), vp_objects::vp_point(30, 350)}},  // channel0 -> region
+        {1, std::vector<vp_objects::vp_point>{vp_objects::vp_point(280, 30), vp_objects::vp_point(340, 30), vp_objects::vp_point(600, 330), vp_objects::vp_point(30, 350)}}   // channel1 -> region
+    };
+    auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
+    auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
+    
+    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_result", vp_nodes::vp_broke_for::BARESULT);
+    auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
+    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
+    
+    // for testing. USING fake_des node in production 
+    auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);    
+    auto fake_des_0 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_0", 0);
+
+    // construct pipeline
+    vehicle_detector->attach_to({file_src_0});
+    trt_vehicle_plate_detector->attach_to({vehicle_detector});
+    trt_vehicle_color_classifier->attach_to({trt_vehicle_plate_detector});
+    tracker->attach_to({trt_vehicle_color_classifier});
+    ba_jam->attach_to({tracker});
+    ba_stop->attach_to({ba_jam});
+    json_kafka_broker_0->attach_to({ba_stop});
+    osd_0->attach_to({json_kafka_broker_0});
+
+    recorder->attach_to({osd_0});
+    fake_des_0->attach_to({recorder});
+
+    file_src_0->start();
+
+    // for debug purpose
+    // vp_utils::vp_analysis_board board({file_src_0});
+    // board.display(1, false);
+
+    std::string wait;
+    std::getline(std::cin, wait);
+    file_src_0->detach_recursively();
+   
+}
\ No newline at end of file
diff --git a/samples/from_argv_ba_jam_rtsp_bak.cpp b/samples/from_argv_ba_jam_rtsp_bak.cpp
deleted file mode 100644
index 202329d..0000000
--- a/samples/from_argv_ba_jam_rtsp_bak.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-#include "../nodes/vp_file_src_node.h"
-#include "../nodes/vp_rtsp_src_node.h"
-
-#include "../nodes/infers/vp_yolo_detector_node.h"
-#include "../nodes/track/vp_sort_track_node.h"
-#include "../nodes/ba/vp_ba_jam_node.h"
-#include "../nodes/osd/vp_ba_jam_osd_node.h"
-#include "../nodes/vp_screen_des_node.h"
-#include "../nodes/vp_rtmp_des_node.h"
-#include "../nodes/broker/vp_json_kafka_broker_node.h"
-#include "../nodes/vp_file_des_node.h"
-#include "../nodes/record/vp_record_node.h"
-#include "../nodes/vp_fake_des_node.h"
-
-#include "../utils/analysis_board/vp_analysis_board.h"
-
-/*
-* ## ba crossline sample ##
-* behaviour analysis for crossline.
-*/
-
-int main(int argc, char* argv[]) {
-    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
-    VP_LOGGER_INIT();
-
-    std::vector<std::string> args(argv + 1, argv + argc);
-    // 榛樿鐨勫懡浠よ鍙傛暟
-    std::string rtsp_path_1 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_2 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_3 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_4 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_5 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_6 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_7 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_8 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_9 = "rtsp://192.168.1.24:8554/demo";
-    std::string rtsp_path_10 = "rtsp://192.168.1.24:8554/demo";
-
-    std::string kafka_server_point = "192.168.0.85:9092";
-
-    float resize_ratio = 0.4;
-
-    // 濡傛灉鎻愪緵浜嗙涓�涓拰绗簩涓弬鏁帮紝鍒欒鐩栭粯璁ょ殑璺緞
-    if (args.size() >= 3) {
-        rtsp_path_1 = args[0];
-        rtsp_path_2 = args[1];
-        rtsp_path_3 = args[2];
-        rtsp_path_4 = args[3];
-        rtsp_path_5 = args[4];
-        rtsp_path_6 = args[5];
-        rtsp_path_7 = args[6];
-        rtsp_path_8 = args[7];
-        rtsp_path_9 = args[8];
-        rtsp_path_10 = args[9];                                                                        
-        resize_ratio = std::stof(args[10]);
-        kafka_server_point = args[11];
-        
-    } else {
-        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point>\n";
-        std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.0.85:9092\n";
-        return -1;
-    }
-
-
-    // create nodes
-    //auto rtsp_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio);
-    auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 1, rtsp_path_1, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_2 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_2", 2, rtsp_path_2, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_3 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_3", 3, rtsp_path_3, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_4 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_4", 4, rtsp_path_4, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_5 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_5", 5, rtsp_path_5, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_6 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_6", 6, rtsp_path_6, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_7 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_7", 7, rtsp_path_7, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_8 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_8", 8, rtsp_path_8, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_9 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_9", 9, rtsp_path_9, resize_ratio, "avdec_h264"); 
-    auto rtsp_src_10 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_10", 10, rtsp_path_10, resize_ratio, "avdec_h264");                                         
-    auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
-    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
-    
-    // define a region in frame for every channel (value MUST in the scope of frame'size)
-    std::map<int, std::vector<vp_objects::vp_point>> regions = {
-        //{0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(641, 58), vp_objects::vp_point(747, 51), vp_objects::vp_point(1132, 267), vp_objects::vp_point(366, 678)}}
-        {1, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {2, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {3, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {4, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {5, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {6, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {7, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {8, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {9, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}},
-        {10, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}}
-
-    };
-    auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
-
-    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_jam", vp_nodes::vp_broke_for::BARESULT);
-    auto osd = std::make_shared<vp_nodes::vp_ba_jam_osd_node>("osd");
-    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
-    auto fake_des_0 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_0", 2);
-    
-    // construct pipeline
-    yolo_detector->attach_to({rtsp_src_1,rtsp_src_2,rtsp_src_3,rtsp_src_4,rtsp_src_5,rtsp_src_6,rtsp_src_7,rtsp_src_8,rtsp_src_9,rtsp_src_10});
-    tracker->attach_to({yolo_detector});
-    ba_jam->attach_to({tracker});
-
-    json_kafka_broker_0->attach_to({ba_jam});
-    osd->attach_to({json_kafka_broker_0});
-    recorder->attach_to({osd});
-
-    fake_des_0->attach_to({recorder});
-
-    rtsp_src_1->start();
-    rtsp_src_2->start();
-    rtsp_src_3->start();
-    rtsp_src_4->start();
-    rtsp_src_5->start();
-    rtsp_src_6->start();
-    rtsp_src_7->start();
-    rtsp_src_8->start();
-    rtsp_src_9->start();
-    rtsp_src_10->start();                     
-
-    std::string wait;
-    std::getline(std::cin, wait);
-    rtsp_src_1->detach_recursively();
-}
\ No newline at end of file
diff --git a/samples/from_argv_ba_jam_rtsp_d.cpp b/samples/from_argv_ba_jam_rtsp_d.cpp
index dcc9931..5bd2d1d 100644
--- a/samples/from_argv_ba_jam_rtsp_d.cpp
+++ b/samples/from_argv_ba_jam_rtsp_d.cpp
@@ -1,82 +1,82 @@
-#include "../nodes/vp_file_src_node.h"
-#include "../nodes/vp_rtsp_src_node.h"
-
-#include "../nodes/infers/vp_yolo_detector_node.h"
-#include "../nodes/track/vp_sort_track_node.h"
-#include "../nodes/ba/vp_ba_jam_node.h"
-#include "../nodes/osd/vp_ba_jam_osd_node.h"
-#include "../nodes/vp_screen_des_node.h"
-#include "../nodes/vp_rtmp_des_node.h"
-#include "../nodes/broker/vp_json_kafka_broker_node.h"
-#include "../nodes/vp_file_des_node.h"
-#include "../nodes/record/vp_record_node.h"
-#include "../nodes/vp_fake_des_node.h"
-#include "../utils/analysis_board/vp_analysis_board.h"
-
-/*
-* ## ba crossline sample ##
-* behaviour analysis for crossline.
-*/
-
-int main(int argc, char* argv[]) {
-    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
-    VP_LOGGER_INIT();
-
-    std::vector<std::string> args(argv + 1, argv + argc);
-    // 榛樿鐨勫懡浠よ鍙傛暟
-    std::string rtsp_path = "rtsp://192.168.1.24:8554/demo";
-    std::string kafka_server_point = "192.168.0.85:9092";
-
-    float resize_ratio = 0.4;
-    int skip_interval = 1;
-
-    // 濡傛灉鎻愪緵浜嗙涓�涓拰绗簩涓弬鏁帮紝鍒欒鐩栭粯璁ょ殑璺緞
-    if (args.size() >= 4) {
-        rtsp_path = args[0];
-        resize_ratio = std::stof(args[1]);
-        kafka_server_point = args[2];
-        skip_interval = std::stoi(args[3]);
-    } else {
-        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point> <skip_interval>\n";
-        std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.0.85:9092 5 \n";
-        return -1;
-    }
-
-
-    // create nodes
-    // auto rtsp_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio, skip_interval);
-    auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264", skip_interval); 
-    auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
-    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
-    
-    // define a region in frame for every channel (value MUST in the scope of frame'size)
-    std::map<int, std::vector<vp_objects::vp_point>> regions = {
-        //{0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(641, 58), vp_objects::vp_point(747, 51), vp_objects::vp_point(1132, 267), vp_objects::vp_point(366, 678)}}
-        {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}}
-    };
-    auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
-    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_jam", vp_nodes::vp_broke_for::BARESULT);
-    auto osd = std::make_shared<vp_nodes::vp_ba_jam_osd_node>("osd");
-    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
-    auto fake_des_2 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_2", 0);
-    
-    // construct pipeline
-    yolo_detector->attach_to({rtsp_src_1});
-    tracker->attach_to({yolo_detector});
-    ba_jam->attach_to({tracker});
-    json_kafka_broker_0->attach_to({ba_jam});
-    osd->attach_to({json_kafka_broker_0});
-    recorder->attach_to({osd});
-    fake_des_2->attach_to({recorder});
-
-
-    rtsp_src_1->start();
-
-    // for debug purpose
-    vp_utils::vp_analysis_board board({rtsp_src_1});
-    board.display(1, false);
-
-    std::string wait;
-    std::getline(std::cin, wait);
-    rtsp_src_1->detach_recursively();
+#include "../nodes/vp_file_src_node.h"
+#include "../nodes/vp_rtsp_src_node.h"
+
+#include "../nodes/infers/vp_yolo_detector_node.h"
+#include "../nodes/track/vp_sort_track_node.h"
+#include "../nodes/ba/vp_ba_jam_node.h"
+#include "../nodes/osd/vp_ba_jam_osd_node.h"
+#include "../nodes/vp_screen_des_node.h"
+#include "../nodes/vp_rtmp_des_node.h"
+#include "../nodes/broker/vp_json_kafka_broker_node.h"
+#include "../nodes/vp_file_des_node.h"
+#include "../nodes/record/vp_record_node.h"
+#include "../nodes/vp_fake_des_node.h"
+#include "../utils/analysis_board/vp_analysis_board.h"
+
+/*
+* ## ba crossline sample ##
+* behaviour analysis for crossline.
+*/
+
+int main(int argc, char* argv[]) {
+    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
+    VP_LOGGER_INIT();
+
+    std::vector<std::string> args(argv + 1, argv + argc);
+    // 榛樿鐨勫懡浠よ鍙傛暟
+    std::string rtsp_path = "rtsp://192.168.1.24:8554/demo";
+    std::string kafka_server_point = "192.168.0.85:9092";
+
+    float resize_ratio = 0.4;
+    int skip_interval = 1;
+
+    // 濡傛灉鎻愪緵浜嗙涓�涓拰绗簩涓弬鏁帮紝鍒欒鐩栭粯璁ょ殑璺緞
+    if (args.size() >= 4) {
+        rtsp_path = args[0];
+        resize_ratio = std::stof(args[1]);
+        kafka_server_point = args[2];
+        skip_interval = std::stoi(args[3]);
+    } else {
+        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point> <skip_interval>\n";
+        std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.0.85:9092 5 \n";
+        return -1;
+    }
+
+
+    // create nodes
+    // auto rtsp_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio, skip_interval);
+    auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 21, rtsp_path, resize_ratio, "avdec_h264", skip_interval); 
+    auto yolo_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("yolo_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
+    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
+    
+    // define a region in frame for every channel (value MUST in the scope of frame'size)
+    std::map<int, std::vector<vp_objects::vp_point>> regions = {
+        //{0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(641, 58), vp_objects::vp_point(747, 51), vp_objects::vp_point(1132, 267), vp_objects::vp_point(366, 678)}}
+        {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}}
+    };
+    auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
+    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_jam", vp_nodes::vp_broke_for::BARESULT);
+    auto osd = std::make_shared<vp_nodes::vp_ba_jam_osd_node>("osd");
+    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
+    auto fake_des_2 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_2", 0);
+    
+    // construct pipeline
+    yolo_detector->attach_to({rtsp_src_1});
+    tracker->attach_to({yolo_detector});
+    ba_jam->attach_to({tracker});
+    json_kafka_broker_0->attach_to({ba_jam});
+    osd->attach_to({json_kafka_broker_0});
+    recorder->attach_to({osd});
+    fake_des_2->attach_to({recorder});
+
+
+    rtsp_src_1->start();
+
+    // for debug purpose
+    vp_utils::vp_analysis_board board({rtsp_src_1});
+    board.display(1, false);
+
+    std::string wait;
+    std::getline(std::cin, wait);
+    rtsp_src_1->detach_recursively();
 }
\ No newline at end of file
diff --git a/samples/from_argv_ba_jam_rtsp_m.cpp b/samples/from_argv_ba_jam_rtsp_m.cpp
new file mode 100644
index 0000000..42941c0
--- /dev/null
+++ b/samples/from_argv_ba_jam_rtsp_m.cpp
@@ -0,0 +1,182 @@
+#include "../nodes/vp_file_src_node.h"
+#include "../nodes/vp_rtsp_src_node.h"
+#include "../nodes/vp_rtsp_ffmpeg_src_node.h"
+#include "../nodes/vp_split_node.h"
+#include "../nodes/infers/vp_trt_vehicle_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_plate_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_color_classifier.h"
+#include "../nodes/infers/vp_yolo_detector_node.h"
+
+#include "../nodes/osd/vp_osd_node.h"
+#include "../nodes/vp_sync_node.h"
+#include "../nodes/track/vp_sort_track_node.h"
+#include "../nodes/ba/vp_ba_jam_node.h"
+#include "../nodes/ba/vp_ba_stop_node.h"
+
+#include "../nodes/osd/vp_ba_stop_osd_node.h"
+#include "../nodes/broker/vp_json_kafka_broker_node.h"
+#include "../nodes/record/vp_record_node.h"
+#include "../nodes/vp_screen_des_node.h"
+#include "../nodes/vp_fake_des_node.h"
+#include "../nodes/vp_placeholder_node.h"
+
+#include "../utils/analysis_board/vp_analysis_board.h"
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+#include <map>
+
+// Function to read configuration from a file
+std::vector<std::vector<std::string>> read_config_file(const std::string& file_path) {
+    std::vector<std::vector<std::string>> config_lines;
+    std::string line;
+    try {
+        std::ifstream infile(file_path);
+        while (std::getline(infile, line)) {
+            std::vector<std::string> params;
+            size_t start = 0;
+            size_t end = line.find(" ");
+            while (end != std::string::npos) {
+                params.push_back(line.substr(start, end - start));
+                start = end + 1;
+                end = line.find(" ", start);
+            }
+            params.push_back(line.substr(start, end));  // add the last parameter
+            config_lines.push_back(params);
+        }
+    } catch (const std::exception& e) {
+        std::cerr << "read config file ex: " << std::string(e.what()) << " <config_file>\n";
+    } catch (...) {
+        std::cerr << "read config file ex end1111\n";
+    }
+    return config_lines;
+}
+
+int main(int argc, char* argv[]) {
+    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
+    VP_LOGGER_INIT();
+    // Read configuration file
+    if (argc < 2) {
+        std::cerr << "Usage: " << argv[0] << " <config_file>\n";
+        return -1;
+    }
+    
+ 
+    try {
+        std::string config_file = argv[1];
+        auto configs = read_config_file(config_file);
+        VP_INFO(vp_utils::string_format("Launch a thread for each configuration  [%s]", config_file));
+
+        // Correct type declarations
+        std::string kafka_server_point = "";
+        std::vector<std::string> rtsp_srcs;
+        std::vector<int> channel_indexs;
+        std::vector<int> skip_intervals;
+        std::vector<bool> use_gpus;
+        std::vector<float> resize_ratios;
+
+        // Use shared pointers for nodes
+        std::vector<std::shared_ptr<vp_nodes::vp_node>> rtsp_nodes;
+        // std::vector<std::shared_ptr<vp_nodes::vp_src_node>> rtsp_nodes;
+        // Des鑺傜偣
+        std::vector<std::shared_ptr<vp_nodes::vp_des_node>> des_nodes;
+        // std::vector<std::shared_ptr<vp_nodes::vp_fake_des_node>> des_nodes;
+
+        // define a region in frame for every channel (value MUST in the scope of frame'size)
+        std::map<int, std::vector<vp_objects::vp_point>> regions = {};
+
+        for (const auto& config : configs) {
+            if (config.size() >= 5) {
+                float resize_ratio = std::stof(config[1]);
+                int skip_interval = std::stoi(config[3]);
+                int channel_index = std::stoi(config[4]);
+                bool usegpu = config.size() >= 6 && config[5] == "1";
+
+                rtsp_srcs.push_back(config[0]);
+                resize_ratios.push_back(resize_ratio);
+                kafka_server_point = config[2];
+                skip_intervals.push_back(skip_interval);
+                channel_indexs.push_back(channel_index);
+                use_gpus.push_back(usegpu);
+
+                regions[channel_index] = std::vector<vp_objects::vp_point>{
+                    vp_objects::vp_point(280, 30),
+                    vp_objects::vp_point(340, 30),
+                    vp_objects::vp_point(600, 330),
+                    vp_objects::vp_point(30, 350)};
+
+                rtsp_nodes.push_back(std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>(
+                    "rtsp_src_" + config[4], channel_index, config[0], resize_ratio, skip_interval, usegpu));
+
+                des_nodes.push_back(std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_" + config[4], channel_index));
+
+            } else {
+                std::cerr << "Invalid config line: ";
+                for (const auto& param : config) {
+                    std::cerr << param << " ";
+                }
+                std::cerr << "\n";
+            }
+        }
+
+        //branch 0
+        //auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", "./vp_data/models/trt/vehicle/vehicle_detection.trt");
+        auto vehicle_detector = std::make_shared<vp_nodes::vp_yolo_detector_node>("vehicle_detector", "./vp_data/models/det_cls/yolov3-tiny-2022-0721_best.weights", "./vp_data/models/det_cls/yolov3-tiny-2022-0721.cfg", "./vp_data/models/det_cls/yolov3_tiny_5classes.txt");
+        auto trt_vehicle_plate_detector = std::make_shared<vp_nodes::vp_trt_vehicle_plate_detector>("vehicle_plate_detector", "./vp_data/models/trt/plate/vehicle_plate_box_detection.trt", "./vp_data/models/trt/plate/vehicle_plate_text_recognition.trt");
+        auto trt_vehicle_color_classifier = std::make_shared<vp_nodes::vp_trt_vehicle_color_classifier>("color_cls", "./vp_data/models/trt/vehicle/vehicle_color_detection.trt", std::vector<int>{0, 1, 2});
+        
+        auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
+        
+        auto ba_jam = std::make_shared<vp_nodes::vp_ba_jam_node>("ba_jam", regions);
+        auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
+        
+        auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_result", vp_nodes::vp_broke_for::BARESULT);
+        auto osd_0 = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
+        auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
+        auto split = std::make_shared<vp_nodes::vp_split_node>("split", true);
+
+        // for testing. USING fake_des node in production    
+        auto fake_des_0 = std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_0", 0);
+
+        // construct pipeline
+        vehicle_detector->attach_to(rtsp_nodes);
+        trt_vehicle_plate_detector->attach_to({vehicle_detector});
+        trt_vehicle_color_classifier->attach_to({trt_vehicle_plate_detector});
+        tracker->attach_to({trt_vehicle_color_classifier});
+        ba_jam->attach_to({tracker});
+        ba_stop->attach_to({ba_jam});
+        json_kafka_broker_0->attach_to({ba_stop});
+        osd_0->attach_to({json_kafka_broker_0});
+
+        recorder->attach_to({osd_0});
+        split->attach_to({recorder});  
+
+        for (size_t i = 0; i < des_nodes.size(); ++i) {
+            des_nodes[i]->attach_to({split});
+        }
+
+        for (auto node : rtsp_nodes) {
+            ((vp_nodes::vp_src_node*)node.get())->start();
+        }
+
+        // for debug purpose
+        // vp_utils::vp_analysis_board board(rtsp_nodes);
+        // board.display(1, false);
+
+        std::string wait;
+        std::getline(std::cin, wait);
+
+        for (auto node : rtsp_nodes) {
+            ((vp_nodes::vp_src_node*)node.get())->detach_recursively();
+        }
+
+    } catch (const std::exception& e) {
+        std::cerr << "read config file ex: " << std::string(e.what()) << " <config_file>\n";
+    } catch (...) {
+        std::cerr << "read config file ex end\n";
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/samples/from_argv_ba_stop_rtsp.cpp b/samples/from_argv_ba_stop_rtsp.cpp
deleted file mode 100644
index e2a3ec3..0000000
--- a/samples/from_argv_ba_stop_rtsp.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "../nodes/vp_file_src_node.h"
-#include "../nodes/vp_rtsp_src_node.h"
-#include "../nodes/infers/vp_trt_vehicle_detector.h"
-#include "../nodes/track/vp_sort_track_node.h"
-#include "../nodes/ba/vp_ba_stop_node.h"
-#include "../nodes/osd/vp_ba_stop_osd_node.h"
-#include "../nodes/vp_screen_des_node.h"
-#include "../nodes/broker/vp_json_kafka_broker_node.h"
-#include "../nodes/vp_file_des_node.h"
-#include "../nodes/record/vp_record_node.h"
-
-#include "../utils/analysis_board/vp_analysis_board.h"
-
-/*
-* ## ba stop sample ##
-* behaviour analysis for stop, single instance of ba node work on 2 channels.
-*/
-
-int main(int argc, char* argv[]) {
-    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
-    VP_LOGGER_INIT();
-
-    std::vector<std::string> args(argv + 1, argv + argc);
-    // 榛樿鐨勫懡浠よ鍙傛暟
-    std::string rtsp_path = "rtsp://192.168.1.24:8554/demo";
-    std::string kafka_server_point = "192.168.0.85:9092";
-
-    float resize_ratio = 0.4;
-
-    // 濡傛灉鎻愪緵浜嗙涓�涓拰绗簩涓弬鏁帮紝鍒欒鐩栭粯璁ょ殑璺緞
-    if (args.size() >= 3) {
-        rtsp_path = args[0];
-        resize_ratio = std::stof(args[1]);
-        kafka_server_point = args[2];
-        
-    } else {
-        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point>\n";
-        std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.0.85:9092\n";
-        return -1;
-    }
-
-
-    // create nodes
-    //auto rtsp_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio);
-    auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264"); 
-    auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", "./vp_data//models/trt/vehicle/vehicle_detection.trt");
-    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
-    
-    // define a region in frame for every channel (value MUST in the scope of frame'size)
-    std::map<int, std::vector<vp_objects::vp_point>> regions = {
-        //{0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(641, 58), vp_objects::vp_point(747, 51), vp_objects::vp_point(1132, 267), vp_objects::vp_point(366, 678)}}
-        {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}}
-    };
-    auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
-    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_stop", vp_nodes::vp_broke_for::BARESULT);
-    auto osd = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd");
-    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
-    auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
-    auto file_des_node_0 = std::make_shared<vp_nodes::vp_file_des_node>("file_des_0", 0, "out-a-osd", "out-a-osd", 1);
-    
-    // construct pipeline
-    trt_vehicle_detector->attach_to({rtsp_src_1});
-    tracker->attach_to({trt_vehicle_detector});
-    ba_stop->attach_to({tracker});
-    json_kafka_broker_0->attach_to({ba_stop});
-    osd->attach_to({json_kafka_broker_0});
-    recorder->attach_to({osd});
-
-    screen_des_0->attach_to({recorder});
-    file_des_node_0->attach_to({recorder});
-
-    rtsp_src_1->start();
-
-    // for debug purpose
-    vp_utils::vp_analysis_board board({rtsp_src_1});
-    board.display();
-
-    std::string wait;
-    std::getline(std::cin, wait);
-    rtsp_src_1->detach_recursively();
-
-}
\ No newline at end of file
diff --git a/samples/from_argv_ba_stop_rtsp_d.cpp b/samples/from_argv_ba_stop_rtsp_d.cpp
deleted file mode 100644
index e2a3ec3..0000000
--- a/samples/from_argv_ba_stop_rtsp_d.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-#include "../nodes/vp_file_src_node.h"
-#include "../nodes/vp_rtsp_src_node.h"
-#include "../nodes/infers/vp_trt_vehicle_detector.h"
-#include "../nodes/track/vp_sort_track_node.h"
-#include "../nodes/ba/vp_ba_stop_node.h"
-#include "../nodes/osd/vp_ba_stop_osd_node.h"
-#include "../nodes/vp_screen_des_node.h"
-#include "../nodes/broker/vp_json_kafka_broker_node.h"
-#include "../nodes/vp_file_des_node.h"
-#include "../nodes/record/vp_record_node.h"
-
-#include "../utils/analysis_board/vp_analysis_board.h"
-
-/*
-* ## ba stop sample ##
-* behaviour analysis for stop, single instance of ba node work on 2 channels.
-*/
-
-int main(int argc, char* argv[]) {
-    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
-    VP_LOGGER_INIT();
-
-    std::vector<std::string> args(argv + 1, argv + argc);
-    // 榛樿鐨勫懡浠よ鍙傛暟
-    std::string rtsp_path = "rtsp://192.168.1.24:8554/demo";
-    std::string kafka_server_point = "192.168.0.85:9092";
-
-    float resize_ratio = 0.4;
-
-    // 濡傛灉鎻愪緵浜嗙涓�涓拰绗簩涓弬鏁帮紝鍒欒鐩栭粯璁ょ殑璺緞
-    if (args.size() >= 3) {
-        rtsp_path = args[0];
-        resize_ratio = std::stof(args[1]);
-        kafka_server_point = args[2];
-        
-    } else {
-        std::cout << "Usage: " << argv[0] << " <rtsp_path> <resize_ratio> <kafka_server_point>\n";
-        std::cout << "Example: " << argv[0] << " rtsp://192.168.1.24:8554/demo 0.4 192.168.0.85:9092\n";
-        return -1;
-    }
-
-
-    // create nodes
-    //auto rtsp_src_1 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, rtsp_path, resize_ratio);
-    auto rtsp_src_1 = std::make_shared<vp_nodes::vp_rtsp_src_node>("rtsp_src_1", 0, rtsp_path, resize_ratio, "avdec_h264"); 
-    auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", "./vp_data//models/trt/vehicle/vehicle_detection.trt");
-    auto tracker = std::make_shared<vp_nodes::vp_sort_track_node>("sort_tracker");
-    
-    // define a region in frame for every channel (value MUST in the scope of frame'size)
-    std::map<int, std::vector<vp_objects::vp_point>> regions = {
-        //{0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(641, 58), vp_objects::vp_point(747, 51), vp_objects::vp_point(1132, 267), vp_objects::vp_point(366, 678)}}
-        {0, std::vector<vp_objects::vp_point>{vp_objects::vp_point(0, 520), vp_objects::vp_point(450, 50), vp_objects::vp_point(650, 50), vp_objects::vp_point(1000, 520)}}
-    };
-    auto ba_stop = std::make_shared<vp_nodes::vp_ba_stop_node>("ba_stop", regions);
-    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", kafka_server_point, "vp_ba_stop", vp_nodes::vp_broke_for::BARESULT);
-    auto osd = std::make_shared<vp_nodes::vp_ba_stop_osd_node>("osd");
-    auto recorder = std::make_shared<vp_nodes::vp_record_node>("recorder", "./record", "./record");
-    auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
-    auto file_des_node_0 = std::make_shared<vp_nodes::vp_file_des_node>("file_des_0", 0, "out-a-osd", "out-a-osd", 1);
-    
-    // construct pipeline
-    trt_vehicle_detector->attach_to({rtsp_src_1});
-    tracker->attach_to({trt_vehicle_detector});
-    ba_stop->attach_to({tracker});
-    json_kafka_broker_0->attach_to({ba_stop});
-    osd->attach_to({json_kafka_broker_0});
-    recorder->attach_to({osd});
-
-    screen_des_0->attach_to({recorder});
-    file_des_node_0->attach_to({recorder});
-
-    rtsp_src_1->start();
-
-    // for debug purpose
-    vp_utils::vp_analysis_board board({rtsp_src_1});
-    board.display();
-
-    std::string wait;
-    std::getline(std::cin, wait);
-    rtsp_src_1->detach_recursively();
-
-}
\ No newline at end of file
diff --git a/samples/from_argv_rtsp_test.cpp b/samples/from_argv_rtsp_test.cpp
new file mode 100644
index 0000000..382d84b
--- /dev/null
+++ b/samples/from_argv_rtsp_test.cpp
@@ -0,0 +1,145 @@
+#include "../nodes/vp_file_src_node.h"
+#include "../nodes/vp_rtsp_src_node.h"
+#include "../nodes/vp_rtsp_ffmpeg_src_node.h"
+#include "../nodes/vp_split_node.h"
+#include "../nodes/infers/vp_trt_vehicle_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_plate_detector.h"
+#include "../nodes/infers/vp_trt_vehicle_color_classifier.h"
+#include "../nodes/infers/vp_yolo_detector_node.h"
+
+#include "../nodes/osd/vp_osd_node.h"
+#include "../nodes/vp_sync_node.h"
+#include "../nodes/track/vp_sort_track_node.h"
+#include "../nodes/ba/vp_ba_jam_node.h"
+#include "../nodes/ba/vp_ba_stop_node.h"
+
+#include "../nodes/osd/vp_ba_stop_osd_node.h"
+#include "../nodes/broker/vp_json_kafka_broker_node.h"
+#include "../nodes/record/vp_record_node.h"
+#include "../nodes/vp_screen_des_node.h"
+#include "../nodes/vp_fake_des_node.h"
+#include "../nodes/vp_placeholder_node.h"
+
+#include "../utils/analysis_board/vp_analysis_board.h"
+
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+#include <map>
+
+// Function to read configuration from a file
+std::vector<std::vector<std::string>> read_config_file(const std::string& file_path) {
+    std::vector<std::vector<std::string>> config_lines;
+    std::string line;
+    try {
+        std::ifstream infile(file_path);
+        while (std::getline(infile, line)) {
+            std::vector<std::string> params;
+            size_t start = 0;
+            size_t end = line.find(" ");
+            while (end != std::string::npos) {
+                params.push_back(line.substr(start, end - start));
+                start = end + 1;
+                end = line.find(" ", start);
+            }
+            params.push_back(line.substr(start, end));  // add the last parameter
+            config_lines.push_back(params);
+        }
+    } catch (const std::exception& e) {
+        std::cerr << "read config file ex: " << std::string(e.what()) << " <config_file>\n";
+    } catch (...) {
+        std::cerr << "read config file ex end1111\n";
+    }
+    return config_lines;
+}
+
+int main(int argc, char* argv[]) {
+    VP_SET_LOG_LEVEL(vp_utils::vp_log_level::INFO);
+    VP_LOGGER_INIT();
+    // Read configuration file
+    if (argc < 2) {
+        std::cerr << "Usage: " << argv[0] << " <config_file>\n";
+        return -1;
+    }
+    
+ 
+    try {
+        std::string config_file = argv[1];
+        auto configs = read_config_file(config_file);
+        VP_INFO(vp_utils::string_format("Launch a thread for each configuration  [%s]", config_file));
+
+        // Correct type declarations
+        std::string kafka_server_point = "";
+        std::vector<std::string> rtsp_srcs;
+        std::vector<int> channel_indexs;
+        std::vector<int> skip_intervals;
+        std::vector<bool> use_gpus;
+        std::vector<float> resize_ratios;
+
+        // Use shared pointers for nodes
+        std::vector<std::shared_ptr<vp_nodes::vp_node>> rtsp_nodes;
+        // std::vector<std::shared_ptr<vp_nodes::vp_src_node>> rtsp_nodes;
+        // Des鑺傜偣
+        std::vector<std::shared_ptr<vp_nodes::vp_des_node>> des_nodes;
+        // std::vector<std::shared_ptr<vp_nodes::vp_fake_des_node>> des_nodes;
+
+        for (const auto& config : configs) {
+            if (config.size() >= 5) {
+                float resize_ratio = std::stof(config[1]);
+                int skip_interval = std::stoi(config[3]);
+                int channel_index = std::stoi(config[4]);
+                bool usegpu = config.size() >= 6 && config[5] == "1";
+
+                rtsp_srcs.push_back(config[0]);
+                resize_ratios.push_back(resize_ratio);
+                kafka_server_point = config[2];
+                skip_intervals.push_back(skip_interval);
+                channel_indexs.push_back(channel_index);
+                use_gpus.push_back(usegpu);
+
+                rtsp_nodes.push_back(std::make_shared<vp_nodes::vp_rtsp_ffmpeg_src_node>(
+                    "rtsp_src_" + config[4], channel_index, config[0], resize_ratio, skip_interval, usegpu));
+
+                des_nodes.push_back(std::make_shared<vp_nodes::vp_fake_des_node>("fake_des_" + config[4], channel_index));
+
+            } else {
+                std::cerr << "Invalid config line: ";
+                for (const auto& param : config) {
+                    std::cerr << param << " ";
+                }
+                std::cerr << "\n";
+            }
+        }
+
+        auto split = std::make_shared<vp_nodes::vp_split_node>("split", true);
+
+        split->attach_to(rtsp_nodes);  
+
+        for (size_t i = 0; i < des_nodes.size(); ++i) {
+            des_nodes[i]->attach_to({split});
+        }
+
+        for (auto node : rtsp_nodes) {
+            ((vp_nodes::vp_src_node*)node.get())->start();
+        }
+
+        // for debug purpose
+        // vp_utils::vp_analysis_board board(rtsp_nodes);
+        // board.display(1, false);
+
+        std::string wait;
+        std::getline(std::cin, wait);
+
+        for (auto node : rtsp_nodes) {
+            ((vp_nodes::vp_src_node*)node.get())->detach_recursively();
+        }
+
+    } catch (const std::exception& e) {
+        std::cerr << "read config file ex: " << std::string(e.what()) << " <config_file>\n";
+    } catch (...) {
+        std::cerr << "read config file ex end\n";
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/samples/from_argv_vehicle_tracking.cpp b/samples/from_argv_vehicle_tracking.cpp
index bc85141..e3e7f43 100644
--- a/samples/from_argv_vehicle_tracking.cpp
+++ b/samples/from_argv_vehicle_tracking.cpp
@@ -35,7 +35,7 @@
     auto file_src_0 = std::make_shared<vp_nodes::vp_file_src_node>("file_src_0", 0, video_path, resize_ratio);
     auto trt_vehicle_detector = std::make_shared<vp_nodes::vp_trt_vehicle_detector>("vehicle_detector", model_path);
     auto track_0 = std::make_shared<vp_nodes::vp_sort_track_node>("track_0");
-    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", "192.168.130.228:9092", "vp_tracking", vp_nodes::vp_broke_for::BARESULT);
+    auto json_kafka_broker_0 = std::make_shared<vp_nodes::vp_json_kafka_broker_node>("json_kafka_broker_0", "192.168.0.85:9092", "vp_tracking", vp_nodes::vp_broke_for::BARESULT);
     auto osd_0 = std::make_shared<vp_nodes::vp_osd_node>("osd_0", "./vp_data/font/NotoSansCJKsc-Medium.otf");
     auto screen_des_0 = std::make_shared<vp_nodes::vp_screen_des_node>("screen_des_0", 0);
 
diff --git a/samples/lpr_camera/README.md b/samples/lpr_camera/README.md
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/README.pdf b/samples/lpr_camera/README.pdf
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/lpr_camera/clean.sh b/samples/lpr_camera/clean.sh
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/docs/1.png b/samples/lpr_camera/docs/1.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/lpr_camera/plate_recognize_pipeline b/samples/lpr_camera/plate_recognize_pipeline
index 509ec72..284a458 100755
--- a/samples/lpr_camera/plate_recognize_pipeline
+++ b/samples/lpr_camera/plate_recognize_pipeline
Binary files differ
diff --git a/samples/lpr_camera/plate_recognize_pipeline.cpp b/samples/lpr_camera/plate_recognize_pipeline.cpp
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/plate_recognize_server.py b/samples/lpr_camera/plate_recognize_server.py
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/static/dist/DPlayer.min.js b/samples/lpr_camera/static/dist/DPlayer.min.js
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/static/dist/DPlayer.min.js.map b/samples/lpr_camera/static/dist/DPlayer.min.js.map
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/static/dist/flv.min.js b/samples/lpr_camera/static/dist/flv.min.js
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/static/plate_images/readme.txt b/samples/lpr_camera/static/plate_images/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/templates/home.html b/samples/lpr_camera/templates/home.html
old mode 100755
new mode 100644
diff --git a/samples/lpr_camera/vp_analysis_board.png b/samples/lpr_camera/vp_analysis_board.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/math_review/README.md b/samples/math_review/README.md
old mode 100755
new mode 100644
diff --git a/samples/math_review/README.pdf b/samples/math_review/README.pdf
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/math_review/clean.sh b/samples/math_review/clean.sh
old mode 100755
new mode 100644
diff --git a/samples/math_review/docs/1.png b/samples/math_review/docs/1.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/math_review/math_expression_check_pipeline.cpp b/samples/math_review/math_expression_check_pipeline.cpp
old mode 100755
new mode 100644
diff --git a/samples/math_review/math_expression_check_server.py b/samples/math_review/math_expression_check_server.py
old mode 100755
new mode 100644
diff --git a/samples/math_review/static/dist/DPlayer.min.js b/samples/math_review/static/dist/DPlayer.min.js
old mode 100755
new mode 100644
diff --git a/samples/math_review/static/dist/DPlayer.min.js.map b/samples/math_review/static/dist/DPlayer.min.js.map
old mode 100755
new mode 100644
diff --git a/samples/math_review/static/dist/flv.min.js b/samples/math_review/static/dist/flv.min.js
old mode 100755
new mode 100644
diff --git a/samples/math_review/static/screenshot_images/readme.txt b/samples/math_review/static/screenshot_images/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/math_review/templates/home.html b/samples/math_review/templates/home.html
old mode 100755
new mode 100644
diff --git a/samples/math_review/vp_analysis_board.png b/samples/math_review/vp_analysis_board.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/similiarity_search/README.md b/samples/similiarity_search/README.md
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/README.pdf b/samples/similiarity_search/README.pdf
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/similiarity_search/clean.sh b/samples/similiarity_search/clean.sh
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/docs/1.png b/samples/similiarity_search/docs/1.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/similiarity_search/docs/2.png b/samples/similiarity_search/docs/2.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/similiarity_search/encoding_receiver.py b/samples/similiarity_search/encoding_receiver.py
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/face_encoding_pipeline b/samples/similiarity_search/face_encoding_pipeline
index 88232bc..5338752 100755
--- a/samples/similiarity_search/face_encoding_pipeline
+++ b/samples/similiarity_search/face_encoding_pipeline
Binary files differ
diff --git a/samples/similiarity_search/face_encoding_pipeline.cpp b/samples/similiarity_search/face_encoding_pipeline.cpp
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/search_server.py b/samples/similiarity_search/search_server.py
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/static/cropped_images/readme.txt b/samples/similiarity_search/static/cropped_images/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/static/query_images/readme.txt b/samples/similiarity_search/static/query_images/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/templates/home.html b/samples/similiarity_search/templates/home.html
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/templates/search_result.html b/samples/similiarity_search/templates/search_result.html
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/vehicle_encoding_pipeline b/samples/similiarity_search/vehicle_encoding_pipeline
index 59137cf..ecd62d4 100755
--- a/samples/similiarity_search/vehicle_encoding_pipeline
+++ b/samples/similiarity_search/vehicle_encoding_pipeline
Binary files differ
diff --git a/samples/similiarity_search/vehicle_encoding_pipeline.cpp b/samples/similiarity_search/vehicle_encoding_pipeline.cpp
old mode 100755
new mode 100644
diff --git a/samples/similiarity_search/vp_analysis_board_face.png b/samples/similiarity_search/vp_analysis_board_face.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/similiarity_search/vp_analysis_board_vehicle.png b/samples/similiarity_search/vp_analysis_board_vehicle.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/vehicle_behaviour_analysis/README.md b/samples/vehicle_behaviour_analysis/README.md
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/README.pdf b/samples/vehicle_behaviour_analysis/README.pdf
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/vehicle_behaviour_analysis/clean.sh b/samples/vehicle_behaviour_analysis/clean.sh
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/docs/1.png b/samples/vehicle_behaviour_analysis/docs/1.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/vehicle_behaviour_analysis/static/dist/DPlayer.min.js b/samples/vehicle_behaviour_analysis/static/dist/DPlayer.min.js
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/static/dist/DPlayer.min.js.map b/samples/vehicle_behaviour_analysis/static/dist/DPlayer.min.js.map
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/static/dist/flv.min.js b/samples/vehicle_behaviour_analysis/static/dist/flv.min.js
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/static/record_images/readme.txt b/samples/vehicle_behaviour_analysis/static/record_images/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/static/record_videos/readme.txt b/samples/vehicle_behaviour_analysis/static/record_videos/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/templates/home.html b/samples/vehicle_behaviour_analysis/templates/home.html
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/vehicle_ba_pipeline b/samples/vehicle_behaviour_analysis/vehicle_ba_pipeline
index 7a686bf..02e6f2d 100755
--- a/samples/vehicle_behaviour_analysis/vehicle_ba_pipeline
+++ b/samples/vehicle_behaviour_analysis/vehicle_ba_pipeline
Binary files differ
diff --git a/samples/vehicle_behaviour_analysis/vehicle_ba_pipeline.cpp b/samples/vehicle_behaviour_analysis/vehicle_ba_pipeline.cpp
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/vehicle_ba_server.py b/samples/vehicle_behaviour_analysis/vehicle_ba_server.py
old mode 100755
new mode 100644
diff --git a/samples/vehicle_behaviour_analysis/vp_analysis_board.png b/samples/vehicle_behaviour_analysis/vp_analysis_board.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/vehicle_property_and_similiarity_search/README.md b/samples/vehicle_property_and_similiarity_search/README.md
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/README.pdf b/samples/vehicle_property_and_similiarity_search/README.pdf
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/vehicle_property_and_similiarity_search/clean.sh b/samples/vehicle_property_and_similiarity_search/clean.sh
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/docs/1.png b/samples/vehicle_property_and_similiarity_search/docs/1.png
old mode 100755
new mode 100644
Binary files differ
diff --git a/samples/vehicle_property_and_similiarity_search/property_encoding_receiver.py b/samples/vehicle_property_and_similiarity_search/property_encoding_receiver.py
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/static/cropped_images/readme.txt b/samples/vehicle_property_and_similiarity_search/static/cropped_images/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/static/query_images/readme.txt b/samples/vehicle_property_and_similiarity_search/static/query_images/readme.txt
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/templates/home.html b/samples/vehicle_property_and_similiarity_search/templates/home.html
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/templates/search_result.html b/samples/vehicle_property_and_similiarity_search/templates/search_result.html
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline b/samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline
index ea9454f..b9e8f64 100755
--- a/samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline
+++ b/samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline
Binary files differ
diff --git a/samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline.cpp b/samples/vehicle_property_and_similiarity_search/vehicle_encoding_classify_pipeline.cpp
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/vehicle_search_server.py b/samples/vehicle_property_and_similiarity_search/vehicle_search_server.py
old mode 100755
new mode 100644
diff --git a/samples/vehicle_property_and_similiarity_search/vp_analysis_board.png b/samples/vehicle_property_and_similiarity_search/vp_analysis_board.png
old mode 100755
new mode 100644
Binary files differ

--
Gitblit v1.9.1