Explorar el Código

修改: .vscode/settings.json
删除: docker/Dockerfile.DbBase
修改: docker/Dockerfile.infer
修改: lib/libmodules.so
修改: modules/CMakeLists.txt
修改: modules/Cleaner/src/Cleaner.cpp
修改: modules/Manager/include/Manager.h
修改: modules/Manager/src/Manager.cpp
修改: modules/dataType/include/CNStreamInferData.h
修改: modules/dataType/include/DataSource.h
修改: modules/dataType/include/Notices.h
删除: modules/dataType/include/PIDSClientResultMsg.h
删除: modules/dataType/include/PIDSDataDefine.h
删除: modules/dataType/include/PIDSServerResultMsg.h
删除: modules/decoder/include/FFMpegDecoder.h
删除: modules/decoder/src/FFMpegDecoder.cpp
修改: modules/deviceState/src/deviceState.cpp
修改: modules/inference/include/inference.h
新文件: modules/inference/include/osd.h
修改: modules/inference/src/inference.cpp
新文件: modules/inference/src/osd.cpp
修改: modules/monitor/src/monitor.cpp
修改: modules/recorder/include/recorder.h
修改: modules/recorder/src/InferVideo.cpp
修改: modules/userApp/include/user_app.h
修改: modules/userApp/src/user_app.cpp
修改: source/config/config.ini
修改: source/config/config_infer_primary_yoloV5.txt
修改: source/src/main.cpp

lishengyin hace 2 años
padre
commit
5a03203348

+ 4 - 1
.vscode/settings.json

@@ -70,6 +70,9 @@
         "__bit_reference": "cpp",
         "__hash_table": "cpp",
         "__split_buffer": "cpp",
-        "__tree": "cpp"
+        "__tree": "cpp",
+        "queue": "cpp",
+        "stack": "cpp",
+        "__config": "cpp"
     }
 }

+ 0 - 1
docker/Dockerfile.DbBase

@@ -1 +0,0 @@
-FROM 192.168.31.174:8080/miva/mivadb:base

+ 2 - 10
docker/Dockerfile.infer

@@ -1,7 +1,7 @@
-# 配置miva推理镜像
+# 配置gsd推理镜像
 
 # Use L4T base docker
-FROM nvcr.io/nvidia/deepstream-l4t:5.0.1-20.09-samples
+FROM nvcr.io/nvidia/deepstream-l4t:5.1-21.02-samples
 
 # install基础依赖
 RUN apt-get update && \
@@ -20,14 +20,6 @@ RUN cd /root/ && tar -zxvf ZLToolKit.tar.gz
 RUN cp -rf /root/ZLToolKit/lib/* /usr/local/lib/
 RUN cp -rf /root/ZLToolKit/include/* /usr/local/include/
 
-# install opencv
-RUN cd /root/ && tar -zxvf opencv.tar.gz
-RUN cp -rf /root/opencv/lib/* /usr/local/lib/
-RUN cp -rf /root/opencv/include/* /usr/local/include/
-
-# 清除缓冲
-# RUN rm ${HOME}/.cache/gstreamer-1.0/registry.*
-
 
 
 

BIN
lib/libmodules.so


+ 3 - 4
modules/CMakeLists.txt

@@ -1,16 +1,15 @@
 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib/)
 include_directories(${3RDPARTY_INCLUDE_DIRS})
 
+# 添加编译参数
+add_compile_options(-Wall -std=c++11 -O2 -g -DPLATFORM_TEGRA)
+
 set(module_list "")
 
 if(build_inference)
   list(APPEND module_list inference)
   install(DIRECTORY inference/include/ DESTINATION include)
 endif()
-# if(build_decoder)
-#   list(APPEND module_list decoder)
-#   install(DIRECTORY decoder/include/ DESTINATION include)
-# endif()
 if(build_inifile)
   list(APPEND module_list inifile)
   install(DIRECTORY inifile/include/ DESTINATION include)

+ 0 - 44
modules/Cleaner/src/Cleaner.cpp

@@ -31,50 +31,6 @@ namespace gsd_ds
      */    
     int32_t Cleaner::ClearHistory()
     {
-        vector<vector<string>> sqlRet;
-        if(!this->ClearType) return -1;
-
-        if(this->ClearType == 1){  // 超过设定阈值就删除第一个,保持不超过阈值
-            SqlWriter sqlSelect("SELECT Id,time,OutPath FROM MIVA_DB.`InferRecord` WHERE finish = 1 AND Del = 0 ORDER BY Id ASC");
-            sqlSelect << sqlRet;
-            if(sqlRet.empty()) return -1;
-            if(sqlRet.size() > this->recordMax){
-                int count = sqlRet.size() - this->recordMax;
-                auto iter = sqlRet.begin();
-                for(int i = 0; i < count; i++){
-                    vector<vector<string>> sqlRet1;
-                    std::string shell = "rm -rf " + (*iter)[2];
-                    system(shell.c_str());
-                    DebugL << shell << endl;
-                    SqlWriter Sqlupdata("UPDATE MIVA_DB.InferRecord SET Del = 1 where Id = '?'");
-                    Sqlupdata << std::atoi((*iter)[0].c_str()) << sqlRet1;
-                    iter++;
-                }
-            }
-        }else if(this->ClearType == 2){ // 超过设定阈值,直接删除全部记录
-            SqlWriter sqlSelect("SELECT Id,time,OutPath FROM MIVA_DB.`InferRecord` WHERE finish = 1 AND Del = 0 ORDER BY Id ASC");
-            sqlSelect << sqlRet;
-            if(sqlRet.size() > this->recordMax){
-                recorder::Ptr m_recorder = recorder::CreateNew();
-                std::string shell = "rm -rf " + m_recorder->Dir + "/*";
-                system(shell.c_str());
-                DebugL << shell << endl;
-                vector<vector<string>> sqlRet1;
-                SqlWriter Sqlupdata("UPDATE MIVA_DB.InferRecord SET Del = 1");
-                Sqlupdata << sqlRet1;
-            }
-        }else if(this->ClearType == 3){ // 设定时间,如只保留前多少小时的数据
-            SqlWriter sqlSelect("SELECT Id,time,OutPath FROM MIVA_DB.`InferRecord` WHERE DATE(time) <= DATE(DATE_SUB(NOW(),INTERVAL '?' day))");
-            sqlSelect << this-> validTime << sqlRet;
-            for (auto& line : sqlRet){
-                std::string shell = "rm -rf " + line[2];
-                system(shell.c_str());
-                DebugL << shell << endl;
-            }
-            vector<vector<string>> sqlRet1;
-            SqlWriter sqlUpdate("UPDATE MIVA_DB.InferRecord SET Del = 1 where DATE(time) <= DATE(DATE_SUB(NOW(),INTERVAL '?' day));");
-            sqlUpdate << this-> validTime << sqlRet1;
-        }
         return 0;
     }
 

+ 1 - 1
modules/Manager/include/Manager.h

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2022-01-11 11:47:37
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-07-08 09:17:57
+ * @LastEditTime: 2022-07-20 09:40:22
  */
 #pragma once
 

+ 1 - 6
modules/Manager/src/Manager.cpp

@@ -234,8 +234,7 @@ namespace gsd_ds{
      * @return {*}
      */    
     bool Manager::decidePlayResult(){
-        std::shared_ptr<Inference> Infer = Inference::CreateNew();
-        return !Infer->Play ? true : false;
+        return true;
     }
 
     /**
@@ -244,10 +243,6 @@ namespace gsd_ds{
      * @return {*}
      */    
     bool Manager::decideResetResult(){
-        if(!this->ResetSwitch) return false;
-        std::shared_ptr<Inference> Infer = Inference::CreateNew();
-        if(Infer == nullptr) return false;
-        if(Infer->InferNum <= ResetThreshold) return false;
         return true;
     }
 

+ 5 - 1
modules/dataType/include/CNStreamInferData.h

@@ -90,6 +90,7 @@ public:
     int FrameCount;
     int width;
     int height;
+    int dv_Id;
 
     vector<DsInferInfo> Objects;
     
@@ -155,7 +156,7 @@ public:
         if (end != doc.FindMember("videoPath") && doc["videoPath"].IsString()) {
             videoPath = doc["videoPath"].GetString();
         } 
-        
+
         return true;
     }
 
@@ -193,6 +194,9 @@ public:
 
         writer.Key("videoPath");
         writer.String(videoPath.c_str());
+
+        writer.Key("dv_Id");
+        writer.Int(dv_Id);
         
         writer.EndObject();
     }

+ 1 - 0
modules/dataType/include/DataSource.h

@@ -20,6 +20,7 @@ public:
     std::string Pid;
     bool Play = false;
     int AddrNum = 0;
+    int dv_Id;
 };
 
 class InferInfo{

+ 3 - 2
modules/dataType/include/Notices.h

@@ -1,8 +1,8 @@
 /*
  * @Author: error: git config user.name && git config user.email & please set dead value or install git
  * @Date: 2022-07-10 18:03:59
- * @LastEditors: error: git config user.name && git config user.email & please set dead value or install git
- * @LastEditTime: 2022-07-10 18:03:59
+ * @LastEditors: lishengyin
+ * @LastEditTime: 2022-07-20 11:07:59
  * @FilePath: /gsd_ds/modules/dataType/include/Notices.h
  * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
  */
@@ -20,3 +20,4 @@
 #define NOTICE_INFEREPER  "NOTICE_INFEREPER"
 #define NOTICE_END        "NOTICE_END"
 #define NOTICE_DEV        "NOTICE_DEV" 
+#define NOTICE_QUITLOOP   "NOTICE_QUITLOOP"

+ 0 - 69
modules/dataType/include/PIDSClientResultMsg.h

@@ -1,69 +0,0 @@
-#pragma once
-
-#include <iostream>
-#include "PIDSDataDefine.h"
-#include <map>
-
-
-using namespace std;
-
-
-class PIDSClientResultMsg
-{
-public:
-    // 列车线路号
-    int TrainLine;
-    int Train;
-    std::map<int, ResultData> data;
-
-public:
-    PIDSClientResultMsg(){}
-    ~PIDSClientResultMsg(){}
-
-
-    void Serialization(uint8_t* data)
-    {
-        data[0] = PIDS_DATA_HEAD;
-        data[1] = PIDS_SRC_TC1;
-        data[2] = PIDS_SRC_TYPE_MIVA;
-        // IP
-        data[3] = 172;
-        data[4] = 0;
-        data[5] = 0;
-        data[6] = 1;
-
-        int16_t length = 36;
-        data[7] = (length & 0x00FF);
-        data[8] = (length & 0xFF00) >> 8;
-
-        // 填充数据
-        // Time
-        getBCDTime(data + 9); 
-
-        data[15] = this->TrainLine;
-        data[16] = this->Train;
-
-        int id = 0;
-        for(int i = 0; i < 18; i+=3)
-        {
-            data[17+i] = this->data[id].Grade;
-            data[18+i] = (this->data[id].Num & 0x00FF);
-            data[19+i] = (this->data[id].Num & 0xFF00) >> 8;
-            id++;
-        }
-
-        int16_t crc = Crc16::GetCRC16(data, 9, length);
-        data[45] = (crc & 0xFF00) >> 8;
-        data[46] = (crc & 0x00FF);
-         
-        // 数据尾
-        data[47] = PIDS_DATA_END;
-    }
-
-    void ObjectToJson(std::string& json)
-    {
-        
-
-        json+="\r\n";
-    }
-};

+ 0 - 82
modules/dataType/include/PIDSDataDefine.h

@@ -1,82 +0,0 @@
-#pragma once
-#include <iostream>
-#include "Crc16.h"
-#include "Util/logger.h"
-#include <time.h>
-#include <ctime>
-#include <list>
-
-using namespace std;
-
-#define PIDS_DATA_HEAD  (0xFD)  // 帧头
-#define PIDS_DATA_END   (0xFE)  // 帧尾
-
-#define PIDS_SRC_TC1    (0x01)  // 源设备车厢编号:TC1
-#define PIDS_SRC_TC2    (0x02)  // 源设备车厢编号:TC2
-
-#define PIDS_SRC_TYPE_PIDS   (0x03)  // PIDS设备
-#define PIDS_SRC_TYPE_MIVA   (0x28)  // 视频分析服务器设备
-
-#define HEX2BCD(x) (((x) % 10) + ((((x) / 10) % 10) << 4))  /*20 -> 20H*/
-
-
-struct CarLoadData{
-    int NoLoad;
-    int DynamicLoad;
-};
-
-struct CarInferData{
-    std::string uri;
-    int num;
-};
-
-struct CarData{
-    CarLoadData loadData;
-    std::list<CarInferData> inferData;
-};
-
-struct ResultData{
-    int Grade;
-    int Num;
-};
-
-
-void getBCDTime(uint8_t *out)
-{
-    time_t t;
-    int i = 0;
-    struct tm *tp = NULL;
-
-    t = time(NULL);
-    tp = localtime(&t);
-    out[i++] = HEX2BCD(tp->tm_year-100);
-    out[i++] = HEX2BCD(tp->tm_mon+1);
-    out[i++] = HEX2BCD(tp->tm_mday);
-    out[i++] = HEX2BCD(tp->tm_hour);
-    out[i++] = HEX2BCD(tp->tm_min);
-    out[i++] = HEX2BCD(tp->tm_sec);
-}
-
-void getDataTime(char *ctime)
-{
-    time_t rawtime;
-    struct tm *info;
-    time(&rawtime);
-    info = localtime(&rawtime);
-    strftime(ctime, 80, "%Y-%m-%d %H:%M:%S", info);
-}
-
-int compare(const char* time1,const char* time2)
-{
-    int year1,month1,day1,hour1,min1,sec1;
-    int year2,month2,day2,hour2,min2,sec2;
-    sscanf(time1,"%d-%d-%d %d:%d:%d",&year1,&month1,&day1,&hour1,&min1,&sec1);
-    sscanf(time2,"%d-%d-%d %d:%d:%d",&year2,&month2,&day2,&hour2,&min2,&sec2);
-    int tm1 = year1*10000+month1*100+day1;
-    int tm2 = year2*10000+month2*100+day2;
-    if(tm1!=tm2) return (tm1>tm2)?1:0;//如果相等,大返回1,小返回0
-    tm1 = hour1*3600+min1*60+sec1;
-    tm2 = hour2*3600+min2*60+sec2;//将时分秒转换为秒数
-    if(tm1!=tm2) return (tm1>tm2)?1:0;//如果相等,大返回1,小返回0
-    return 2;//到这里必然是相等了
-}

+ 0 - 75
modules/dataType/include/PIDSServerResultMsg.h

@@ -1,75 +0,0 @@
-#pragma once
-
-#include <iostream>
-#include "PIDSDataDefine.h"
-#include <map>
-
-
-using namespace std;
-
-
-class PIDSServerResultMsg
-{
-public:
-    // 当前站站号
-    int CurrentSite;
-    // 下一站站号
-    int NextSite;
-    // 起始站站号
-    int StartSite;
-    // 终点站站好
-    int EndSite;
-    // 时间是否有效
-    bool TimeFlag;
-
-
-    // 车门标志位
-    uint8_t DoorFlag;
-    // TC2、TC1激活情况
-    uint8_t PIDSFlag;
-
-    std::map<int,int> DynamicLoad;
-
-public:
-    PIDSServerResultMsg(){};
-    ~PIDSServerResultMsg(){};
-    
-    // 反序列化
-    int32_t Deserialization(uint8_t *data, int length)
-    {
-        // 检查数据头尾
-        if(data[0] != PIDS_DATA_HEAD || data[length-1] != PIDS_DATA_END) {
-            ErrorL << "Incorrect data head and tail";
-            return ERR;
-        }
-        // 获取数据长度
-        uint16_t DataLength = ((uint16_t)data[8] << 8 | data[7]);
-
-        // 检查数据校验位
-        int16_t crc = Crc16::GetCRC16(data, 9, DataLength);
-
-        // if(data[length-3] != ((crc & 0xFF00) >> 8) || data[length-2] != (crc & 0x00FF)){
-        //     ErrorL << "Incorrect data check digit";
-        // }
-
-        // 数据校验通过提取数据
-        this->CurrentSite = data[9];
-        this->NextSite = data[10];
-        this->StartSite = data[11];
-        this->EndSite = data[12];
-        this->TimeFlag = data[13] ? true:false;
-
-        // 时间
-        // 标志
-        this->DoorFlag = data[21];
-        this->PIDSFlag = data[22];
-        // 提取动态负载
-        int id = 1;
-        for(int i = 0; i < 12; i+=2){
-            this->DynamicLoad[id] = (uint16_t)data[24 + i] << 8 | data[23 + i];
-            id++;
-        }
-        return OK;
-    }
-};
-

+ 0 - 100
modules/decoder/include/FFMpegDecoder.h

@@ -1,100 +0,0 @@
-/*
- * @Description: 
- * @Version: 1.0
- * @Autor: lishengyin
- * @Date: 2021-10-13 09:40:05
- * @LastEditors: lishengyin
- * @LastEditTime: 2021-10-13 09:40:05
- */
-/*
- * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
- *
- * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
- *
- * Use of this source code is governed by MIT license that can be found in the
- * LICENSE file in the root of the source tree. All contributing project authors
- * may be found in the AUTHORS file in the root of the source tree.
- */
-#ifndef FFMpegDecoder_H_
-#define FFMpegDecoder_H_
-#include <string>
-#include <memory>
-#include <stdexcept>
-#include "Extension/Frame.h"
-#include "Extension/Track.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "libavcodec/avcodec.h"
-#include "libswresample/swresample.h"
-#include "libavformat/avformat.h"
-#ifdef __cplusplus
-}
-#endif
-
-using namespace std;
-using namespace mediakit;
-
-class FFmpegFrame {
-public:
-    using Ptr = std::shared_ptr<FFmpegFrame>;
-
-    FFmpegFrame(std::shared_ptr<AVFrame> frame = nullptr);
-    ~FFmpegFrame();
-
-    AVFrame *get() const;
-    void fillPicture(AVPixelFormat target_format, int target_width, int  target_height);
-
-private:
-    char *_data = nullptr;
-    std::shared_ptr<AVFrame> _frame;
-};
-
-class FFmpegSwr{
-public:
-    using Ptr = std::shared_ptr<FFmpegSwr>;
-
-    FFmpegSwr(AVSampleFormat output, int channel, int channel_layout, int samplerate);
-    ~FFmpegSwr();
-
-    FFmpegFrame::Ptr inputFrame(const FFmpegFrame::Ptr &frame);
-
-private:
-    int _target_channels;
-    int _target_channel_layout;
-    int _target_samplerate;
-    AVSampleFormat _target_format;
-    SwrContext *_ctx = nullptr;
-    ResourcePool<FFmpegFrame> _frame_pool;
-};
-
-class FFmpegDecoder : public FrameWriterInterface {
-public:
-    using Ptr = std::shared_ptr<FFmpegDecoder>;
-    using onDec = function<void(const FFmpegFrame::Ptr &)>;
-
-    FFmpegDecoder(const Track::Ptr &track);
-    ~FFmpegDecoder() {}
-
-    void inputFrame(const Frame::Ptr &frame) override;
-    void inputFrame(const char *data, size_t size, uint32_t dts, uint32_t pts);
-
-    void setOnDecode(onDec cb);
-    void flush();
-    const AVCodecContext *getContext() const;
-
-private:
-    void onDecode(const FFmpegFrame::Ptr &frame);
-
-private:
-    Ticker _ticker;
-    onDec _cb;
-    FFmpegSwr::Ptr _swr;
-    ResourcePool<FFmpegFrame> _frame_pool;
-    std::shared_ptr<AVCodecContext> _context;
-};
-
-#endif /* FFMpegDecoder_H_ */
-
-

+ 0 - 310
modules/decoder/src/FFMpegDecoder.cpp

@@ -1,310 +0,0 @@
-/*
- * Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
- *
- * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
- *
- * Use of this source code is governed by MIT license that can be found in the
- * LICENSE file in the root of the source tree. All contributing project authors
- * may be found in the AUTHORS file in the root of the source tree.
- */
-#include "FFMpegDecoder.h"
-#define MAX_DELAY_SECOND 60
-
-using namespace std;
-using namespace mediakit;
-
-static string ffmpeg_err(int errnum){
-    char errbuf[AV_ERROR_MAX_STRING_SIZE];
-    av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
-    return errbuf;
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-template<bool decoder = true, typename ...ARGS>
-AVCodec *getCodecByName(ARGS ...names);
-
-template<bool decoder = true, typename ...ARGS>
-AVCodec *getCodecByName(const char *name) {
-    auto codec = decoder ? avcodec_find_decoder_by_name(name) : avcodec_find_encoder_by_name(name);
-    if (codec) {
-        InfoL << (decoder ? "got decoder:" : "got encoder:") << name;
-    }
-    return codec;
-}
-
-template<bool decoder = true, typename ...ARGS>
-AVCodec *getCodecByName(const char *name, ARGS ...names) {
-    auto codec = getCodecByName<decoder>(names...);
-    if (codec) {
-        return codec;
-    }
-    return getCodecByName<decoder>(name);
-}
-
-template<bool decoder = true>
-AVCodec *getCodec(enum AVCodecID id) {
-    auto codec = decoder ? avcodec_find_decoder(id) : avcodec_find_encoder(id);
-    if (codec) {
-        InfoL << (decoder ? "got decoder:" : "got encoder:") << avcodec_get_name(id);
-    }
-    return codec;
-}
-
-template<bool decoder = true, typename ...ARGS>
-AVCodec *getCodec(enum AVCodecID id, ARGS ...names) {
-    auto codec = getCodecByName<decoder>(names...);
-    if (codec) {
-        return codec;
-    }
-    return getCodec<decoder>(id);
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-FFmpegFrame::FFmpegFrame(std::shared_ptr<AVFrame> frame) {
-    if (frame) {
-        _frame = std::move(frame);
-    } else {
-        _frame.reset(av_frame_alloc(), [](AVFrame *ptr) {
-            av_frame_unref(ptr);
-            av_frame_free(&ptr);
-        });
-    }
-}
-
-FFmpegFrame::~FFmpegFrame(){
-    if (_data) {
-        delete[] _data;
-        _data = nullptr;
-    }
-}
-
-AVFrame *FFmpegFrame::get() const{
-    return _frame.get();
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-FFmpegSwr::FFmpegSwr(AVSampleFormat output, int channel, int channel_layout, int samplerate){
-    _target_format = output;
-    _target_channels = channel;
-    _target_channel_layout = channel_layout;
-    _target_samplerate = samplerate;
-    _frame_pool.setSize(8);
-}
-
-FFmpegSwr::~FFmpegSwr(){
-    if (_ctx) {
-        swr_free(&_ctx);
-    }
-}
-
-FFmpegFrame::Ptr FFmpegSwr::inputFrame(const FFmpegFrame::Ptr &frame){
-    if (frame->get()->format == _target_format &&
-        frame->get()->channels == _target_channels &&
-        frame->get()->channel_layout == _target_channel_layout &&
-        frame->get()->sample_rate == _target_samplerate) {
-        //不转格式
-        return frame;
-    }
-    if (!_ctx) {
-        _ctx = swr_alloc_set_opts(nullptr, _target_channel_layout, _target_format, _target_samplerate,
-                                  frame->get()->channel_layout, (AVSampleFormat) frame->get()->format,
-                                  frame->get()->sample_rate, 0, nullptr);
-        InfoL << "swr_alloc_set_opts:" << av_get_sample_fmt_name((enum AVSampleFormat) frame->get()->format) << " -> "
-              << av_get_sample_fmt_name(_target_format);
-    }
-    if (_ctx) {
-        FFmpegFrame::Ptr out = _frame_pool.obtain();
-        out->get()->format = _target_format;
-        out->get()->channel_layout = _target_channel_layout;
-        out->get()->channels = _target_channels;
-        out->get()->sample_rate = _target_samplerate;
-        out->get()->pkt_dts = frame->get()->pkt_dts;
-        out->get()->pkt_pts = frame->get()->pkt_pts;
-        out->get()->pts = frame->get()->pts;
-
-        int ret;
-        if(0 != (ret = swr_convert_frame(_ctx, out->get(), frame->get()))){
-            WarnL << "swr_convert_frame failed:" << ffmpeg_err(ret);
-            return nullptr;
-        }
-        //修正大小
-        out->get()->linesize[0] = out->get()->nb_samples * out->get()->channels * av_get_bytes_per_sample((enum AVSampleFormat)out->get()->format);
-        return out;
-    }
-
-    return nullptr;
-}
-void FFmpegFrame::fillPicture(AVPixelFormat target_format, int target_width, int  target_height){
-    assert(_data == nullptr);
-    _data = new char[avpicture_get_size(target_format, target_width, target_height)];
-    avpicture_fill((AVPicture *) _frame.get(), (uint8_t *) _data, target_format, target_width, target_height);
-}
-
-///////////////////////////////////////////////////////////////////////////
-
-FFmpegDecoder::FFmpegDecoder(const Track::Ptr &track) {
-    _frame_pool.setSize(8);
-    avcodec_register_all();
-    AVCodec *codec = nullptr;
-    AVCodec *codec_default = nullptr;
-    switch (track->getCodecId()) {
-        case CodecH264:
-            codec_default = getCodec(AV_CODEC_ID_H264);
-            codec = getCodec(AV_CODEC_ID_H264, "h264_cuvid","h264_videotoolbox");
-            break;
-        case CodecH265:
-            codec_default = getCodec(AV_CODEC_ID_HEVC);
-            codec = getCodec(AV_CODEC_ID_HEVC, "hevc_cuvid","hevc_videotoolbox");
-            break;
-        case CodecAAC:
-            codec = getCodec(AV_CODEC_ID_AAC);
-            break;
-        case CodecG711A:
-            codec = getCodec(AV_CODEC_ID_PCM_ALAW);
-            break;
-        case CodecG711U:
-            codec = getCodec(AV_CODEC_ID_PCM_MULAW);
-            break;
-        case CodecOpus:
-            codec = getCodec(AV_CODEC_ID_OPUS);
-            break;
-        default: break;
-    }
-
-    if (!codec) {
-        throw std::runtime_error("未找到解码器");
-    }
-
-    while (true) {
-        _context.reset(avcodec_alloc_context3(codec), [](AVCodecContext *ctx) {
-            avcodec_close(ctx);
-            avcodec_free_context(&ctx);
-        });
-
-        if (!_context) {
-            throw std::runtime_error("创建解码器失败");
-        }
-
-        //保存AVFrame的引用
-        _context->refcounted_frames = 1;
-        _context->flags |= AV_CODEC_FLAG_LOW_DELAY;
-        _context->flags2 |= AV_CODEC_FLAG2_FAST;
-
-        switch (track->getCodecId()) {
-            case CodecG711A:
-            case CodecG711U: {
-                AudioTrack::Ptr audio = static_pointer_cast<AudioTrack>(track);
-                _context->channels = audio->getAudioChannel();
-                _context->sample_rate = audio->getAudioSampleRate();
-                _context->channel_layout = _context->channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
-                break;
-            }
-            default:
-                break;
-        }
-        AVDictionary *dict = nullptr;
-        av_dict_set(&dict, "threads", to_string(thread::hardware_concurrency()).data(), 0);
-        av_dict_set(&dict, "zerolatency", "1", 0);
-        av_dict_set(&dict, "strict", "-2", 0);
-
-        if (codec->capabilities & AV_CODEC_CAP_TRUNCATED) {
-            /* we do not send complete frames */
-            _context->flags |= AV_CODEC_FLAG_TRUNCATED;
-        }
-
-        int ret = avcodec_open2(_context.get(), codec, &dict);
-        if (ret >= 0) {
-            //成功
-            InfoL << "打开解码器成功:" << codec->name;
-            break;
-        }
-
-        if (codec_default && codec_default != codec) {
-            //硬件编解码器打开失败,尝试软件的
-            WarnL << "打开解码器" << codec->name << "失败,原因是:" << ffmpeg_err(ret) << ", 再尝试打开解码器" << codec_default->name;
-            codec = codec_default;
-            continue;
-        }
-        throw std::runtime_error(StrPrinter << "打开解码器" << codec->name << "失败:" << ffmpeg_err(ret));
-    }
-}
-
-void FFmpegDecoder::flush(){
-    while (true) {
-        FFmpegFrame::Ptr out_frame = _frame_pool.obtain();
-        auto ret = avcodec_receive_frame(_context.get(), out_frame->get());
-        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
-            break;
-        }
-        if (ret < 0) {
-            WarnL << "avcodec_receive_frame failed:" << ffmpeg_err(ret);
-            break;
-        }
-        onDecode(out_frame);
-    }
-}
-
-const AVCodecContext *FFmpegDecoder::getContext() const{
-    return _context.get();
-}
-
-void FFmpegDecoder::inputFrame(const Frame::Ptr &frame) {
-    inputFrame(frame->data(), frame->size(), frame->dts(), frame->pts());
-}
-
-void FFmpegDecoder::inputFrame(const char *data, size_t size, uint32_t dts, uint32_t pts) {
-    AVPacket pkt;
-    av_init_packet(&pkt);
-
-    pkt.data = (uint8_t *) data;
-    pkt.size = size;
-    pkt.dts = dts;
-    pkt.pts = pts;
-    
-    auto ret = avcodec_send_packet(_context.get(), &pkt);
-    if (ret < 0) {
-        if (ret != AVERROR_INVALIDDATA) {
-            WarnL << "avcodec_send_packet failed:" << ffmpeg_err(ret);
-        }
-        return;
-    }
-    while (true) {
-        FFmpegFrame::Ptr out_frame = _frame_pool.obtain();
-        ret = avcodec_receive_frame(_context.get(), out_frame->get());
-        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
-            break;
-        }
-        if (ret < 0) {
-            WarnL << "avcodec_receive_frame failed:" << ffmpeg_err(ret);
-            break;
-        }
-        if (pts - out_frame->get()->pkt_pts > MAX_DELAY_SECOND * 1000 && _ticker.createdTime() > 10 * 1000) {
-            //后面的帧才忽略,防止Track无法ready
-            WarnL << "解码时,忽略" << MAX_DELAY_SECOND << "秒前的数据:" << pts << " " << out_frame->get()->pkt_pts;
-            continue;
-        }
-        onDecode(out_frame);
-    }
-}
-
-void FFmpegDecoder::setOnDecode(FFmpegDecoder::onDec cb) {
-    _cb = std::move(cb);
-}
-
-void FFmpegDecoder::onDecode(const FFmpegFrame::Ptr &frame){
-    if (_context->codec_type == AVMEDIA_TYPE_AUDIO) {
-        if (!_swr) {
-            //固定输出16位整型的pcm
-            _swr = std::make_shared<FFmpegSwr>(AV_SAMPLE_FMT_S16, frame->get()->channels, frame->get()->channel_layout, frame->get()->sample_rate);
-        }
-        //音频情况下,转换音频format类型,比如说浮点型转换为int型
-        const_cast<FFmpegFrame::Ptr &>(frame) = _swr->inputFrame(frame);
-    }
-    if (_cb && frame) {
-        _cb(frame);
-    }
-}
-

+ 3 - 19
modules/deviceState/src/deviceState.cpp

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2022-01-11 10:45:05
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-07-08 09:38:50
+ * @LastEditTime: 2022-07-18 10:47:29
  */
 #include "deviceState.h"
 
@@ -63,7 +63,7 @@ namespace gsd_ds
         std::lock_guard<mutex> gurad(m_mutex);
         vector<vector<string>> sqlRet;
 
-        SqlWriter sqlUpdate_DeviceState("UPDATE MIVA_DB.DeviceState SET CpuUsage='?',GpuUsage='?',MemoryUsage='?',CpuTemp='?',GpuTemp='?',FdUsage='?',AUXTemp='?',A0Temp='?',ThermalTemp='?',updateTime='?'");
+        SqlWriter sqlUpdate_DeviceState("UPDATE gsdDB.DeviceState SET CpuUsage='?',GpuUsage='?',MemoryUsage='?',CpuTemp='?',GpuTemp='?',FdUsage='?',AUXTemp='?',A0Temp='?',ThermalTemp='?',updateTime='?'");
         sqlUpdate_DeviceState << this->CpuUsage << this->GpuUsage  << this->MemoryUsage << this->CpuTemp << this->GpuTemp << this->FdUsage << this->AUXTemp << this->A0Temp << this->ThermalTemp << Ctime << sqlRet;
         
         return 0;
@@ -75,24 +75,8 @@ namespace gsd_ds
      * @return {*}
      */    
     int32_t deviceState::SyncFdThreshold(int sourceNum, bool outState){
-        std::lock_guard<mutex> gurad(m_mutex);
-        static int num = 0;
-        static int fdMin = 3000;
-        // if(num != sourceNum || outState){
-        //     num = sourceNum;
-        //     fdMin = 3000;
-        // }
-        if((this->FdUsage > fdMin && this->FdUsage - fdMin <= 20) || this->FdUsage < fdMin){
-            if(this->FdUsage > 0) {
-                fdMin = this->FdUsage;
-                vector<vector<string>> sqlRet;
-                SqlWriter sqlUpdate("UPDATE MIVA_DB.MivaConfig SET FdThreshold='?'");
-                sqlUpdate << this->FdUsage << sqlRet;
-                return 0;
-            }
-        }
         return -1;
     }
-} // namespace MIVA
+} // namespace gsd_ds
 
 

+ 48 - 140
modules/inference/include/inference.h

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:37:51
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-07-13 16:54:01
+ * @LastEditTime: 2022-07-20 11:06:09
  */
 #pragma once
 #include <iostream>
@@ -46,9 +46,8 @@
 #include <opencv2/imgproc/types_c.h>
 
 #include "CNStreamInferData.h"
-
 #include "Base64.h"
-
+#include "osd.h"
 #include <list>
 
 #define OK 0
@@ -62,33 +61,33 @@ namespace gsd_ds{
     {
     private:
         // Deepstream
-        GMainLoop *loop = NULL;
-        GstElement *pipeline = NULL,*streammux =NULL, *sink = NULL, *pgie = NULL,
-        *queue1, *queue2, *queue3, *queue4, *queue5, *nvvidconv = NULL, *caps_filter = NULL, *nvvidconv_postosd = NULL,
-        *encoder = NULL, 
-        *codecparser = NULL, 
-        *rtppay = NULL, 
-        *nvosd = NULL,*tiler = NULL;
-
-        GstElement *transform = NULL;
-        GstBus *bus = NULL;
+        GMainLoop *loop = nullptr;
+        GstElement *pipeline = nullptr,*streammux =nullptr, *sink = nullptr, *pgie = nullptr,
+        *queue1, *queue2, *queue3, *queue4, *queue5, *nvvidconv = nullptr, *caps_filter = nullptr, *nvvidconv_postosd = nullptr,
+        *encoder = nullptr, 
+        *codecparser = nullptr, 
+        *rtppay = nullptr, *videorate  = nullptr,
+        *nvosd = nullptr,*tiler = nullptr;
+        
+        GstElement *transform = nullptr;
+        GstBus *bus = nullptr;
         guint bus_watch_id;
-        GstPad *pgie_src_pad = NULL;
-        GstPad *tiler_sink_pad = NULL;
+        GstPad *pgie_src_pad = nullptr;
+        GstPad *tiler_sink_pad = nullptr;
 
         guint tiler_rows, tiler_columns;
         guint pgie_batch_size;
 
         float box_thickness_ = 1;
 
+        bool Play = false;
+        bool enable = false;
+
     public:
-        std::shared_ptr<std::vector<DataSource>> m_DataList = NULL;
+        std::shared_ptr<std::vector<DataSource>> m_DataList = nullptr;
         std::shared_ptr<InferInfo> m_InferInfo = nullptr;
         std::shared_ptr<recorder> m_recorder = nullptr;
-        
-        bool Play = false;
-        bool enable = false;
-        int InferNum = 0;
+        std::shared_ptr<ThreadPool> m_pool = nullptr;
 
         Inference();
         ~Inference();
@@ -140,13 +139,6 @@ namespace gsd_ds{
         void PausedTask();
 
         /**
-         * @description: 检查任务
-         * @param {*}
-         * @return {*}
-         */        
-        void CheckTask();
-
-        /**
          * @description: 状态返回
          * @param {*}
          * @return {*}
@@ -165,6 +157,19 @@ namespace gsd_ds{
          */        
         void DynamicAdjust();
 
+        /**
+         * @description: Destory()
+         * @return {*}
+         */        
+        void Destory();
+
+        /**
+         * @description: Quit
+         * @return {*}
+         */        
+        void QuitLoop();
+        
+
     public:
 
         /**
@@ -224,6 +229,22 @@ namespace gsd_ds{
         static int PtInPolygon (Point p, vector<Point>& ptPolygon, int nCount);
 
         /**
+         * @description: 启动rtsp
+         * @param {guint} rtsp_port_num
+         * @param {guint} updsink_port_num
+         * @param {guint64} udp_buffer_size
+         * @return {*}
+         */        
+        static gboolean start_rtsp_streaming (guint rtsp_port_num, guint updsink_port_num, guint64 udp_buffer_size);
+
+        /**
+         * @description: FloatToString
+         * @param {float} number
+         * @return {*}
+         */        
+        static std::string FloatToString(float number);
+
+        /**
          * @description: 添加数据源
          * @param {int} source_Id 数据源ID
          * @param {string} uri 数据源Url
@@ -249,13 +270,6 @@ namespace gsd_ds{
         void ModifyUri(GstElement *source_bin, std::string uri);
         
         /**
-         * @description: 释放元素
-         * @param {GstElement} *source_bin
-         * @return {*}
-         */        
-        void FreeElement(int source_Id,GstElement *source_bin);
-
-        /**
          * @description: 添加数据源
          * @param {int} sourceId
          * @return {*}
@@ -268,112 +282,6 @@ namespace gsd_ds{
          * @return {*}
          */        
         void SetBatch(int num);
-
-        /**
-         * @description: HSV2RGB
-         * @param {float} h
-         * @param {float} s
-         * @param {float} v
-         * @return {*}
-         */        
-        static cv::Scalar HSV2RGB(const float h, const float s, const float v) 
-        {
-            const int h_i = static_cast<int>(h * 6);
-            const float f = h * 6 - h_i;
-            const float p = v * (1 - s);
-            const float q = v * (1 - f * s);
-            const float t = v * (1 - (1 - f) * s);
-            float r, g, b;
-            switch (h_i) {
-                case 0:
-                r = v;
-                g = t;
-                b = p;
-                break;
-                case 1:
-                r = q;
-                g = v;
-                b = p;
-                break;
-                case 2:
-                r = p;
-                g = v;
-                b = t;
-                break;
-                case 3:
-                r = p;
-                g = q;
-                b = v;
-                break;
-                case 4:
-                r = t;
-                g = p;
-                b = v;
-                break;
-                case 5:
-                r = v;
-                g = p;
-                b = q;
-                break;
-                default:
-                r = 1;
-                g = 1;
-                b = 1;
-                break;
-            }
-            return cv::Scalar(r * 255, g * 255, b * 255);
-        }
-
-        /**
-         * @description: GenerateColorsForCategories
-         * @param {int} n
-         * @return {*}
-         */        
-        static std::vector<cv::Scalar> GenerateColorsForCategories(const int n) {
-            std::vector<cv::Scalar> colors;
-            cv::RNG rng(12345);
-            const float golden_ratio_conjugate = 0.618033988749895f;
-            const float s = 0.3f;
-            const float v = 0.99f;
-            for (int i = 0; i < n; ++i) {
-                const float h = std::fmod(rng.uniform(0.0f, 1.0f) + golden_ratio_conjugate, 1.0f);
-                colors.push_back(HSV2RGB(h, s, v));
-            }
-             return colors;
-        }
-
-        /**
-         * @description: CalcThickness
-         * @param {int} image_width
-         * @param {float} thickness
-         * @return {*}
-         */        
-        static int CalcThickness(int image_width, float thickness);
-
-        /**
-         * @description: DrawBox
-         * @param {Mat} image
-         * @param {Point} &top_left
-         * @param {Point} &bottom_right
-         * @param {Scalar} &color
-         * @return {*}
-         */        
-        static void DrawBox(cv::Mat image, const cv::Point &top_left, const cv::Point &bottom_right, const cv::Scalar &color);
-
-        /**
-         * @description: DrawText
-         * @return {*}
-         */        
-        static void DrawText(cv::Mat image, const cv::Point &bottom_left, const std::string &text, const cv::Scalar &color,
-                float scale = 1, int *text_height = nullptr);
-
-        /**
-         * @description: CalcScale
-         * @param {int} image_width
-         * @param {float} scale
-         * @return {*}
-         */        
-        static double CalcScale(int image_width, float scale);
     };
 }
 

+ 74 - 0
modules/inference/include/osd.h

@@ -0,0 +1,74 @@
+#ifndef _OSD_H_
+#define _OSD_H_
+
+#include <opencv2/core.hpp>
+#include <opencv2/videoio.hpp>
+#include <opencv2/highgui.hpp>
+#include <opencv2/imgproc.hpp>
+#include <opencv2/imgproc/types_c.h>
+
+using namespace std;
+
+
+namespace gsd_ds
+{
+    class osd
+    {
+    public:
+        osd() {}
+        ~osd() {}
+
+        /**
+         * @description: 转换格式
+         * @param {float} h
+         * @param {float} s
+         * @param {float} v
+         * @return {*}
+         */        
+        static cv::Scalar HSV2RGB(const float h, const float s, const float v);
+
+        /**
+         * @description: GenerateColorsForCategories
+         * @param {int} n
+         * @return {*}
+         */        
+        static std::vector<cv::Scalar> GenerateColorsForCategories(const int n);
+
+
+        /**
+         * @description: CalcThickness
+         * @param {int} image_width
+         * @param {float} thickness
+         * @return {*}
+         */        
+        static int CalcThickness(int image_width, float thickness);
+
+        /**
+         * @description: DrawBox
+         * @param {Mat} image
+         * @param {Point} &top_left
+         * @param {Point} &bottom_right
+         * @param {Scalar} &color
+         * @return {*}
+         */        
+        static void DrawBox(cv::Mat image, const cv::Point &top_left, const cv::Point &bottom_right, const cv::Scalar &color);
+
+        /**
+         * @description: DrawText
+         * @return {*}
+         */        
+        static void DrawText(cv::Mat image, const cv::Point &bottom_left, const std::string &text, const cv::Scalar &color,
+                float scale = 1, int *text_height = nullptr);
+
+        /**
+         * @description: CalcScale
+         * @param {int} image_width
+         * @param {float} scale
+         * @return {*}
+         */        
+        static double CalcScale(int image_width, float scale);
+    };
+} // namespace gsd_ds
+
+
+#endif

+ 153 - 302
modules/inference/src/inference.cpp

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:35:37
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-07-14 09:59:36
+ * @LastEditTime: 2022-07-20 11:05:47
  */
 #include "inference.h"
 #include "Notices.h"
@@ -13,10 +13,6 @@
 #include <gst/rtsp/gstrtsptransport.h>
 #include <gst/rtp/gstrtcpbuffer.h>
 
-#define MAX_DISPLAY_LEN 64
-
-#define PGIE_CLASS_ID_VEHICLE 0
-#define PGIE_CLASS_ID_PERSON 2
 
 /* By default, OSD process-mode is set to CPU_MODE. To change mode, set as:
  * 1: GPU mode (for Tesla only)
@@ -30,12 +26,12 @@
 /* The muxer output resolution must be set if the input streams will be of
  * different resolution. The muxer will scale all the input frames to this
  * resolution. */
-#define MUXER_OUTPUT_WIDTH 1920
-#define MUXER_OUTPUT_HEIGHT 1080
+#define MUXER_OUTPUT_WIDTH 1280
+#define MUXER_OUTPUT_HEIGHT 720
 
 /* Muxer batch formation timeout, for e.g. 40 millisec. Should ideally be set
  * based on the fastest source's framerate. */
-#define MUXER_BATCH_TIMEOUT_USEC 5000
+#define MUXER_BATCH_TIMEOUT_USEC 1000000 / 60
 
 #define TILED_OUTPUT_WIDTH 1280
 #define TILED_OUTPUT_HEIGHT 720
@@ -46,107 +42,105 @@
 
 #define MAX_NUM_SOURCES 30
 
-gint frame_number = 0;
-
-gint g_num_sources = 0;
 gint g_source_id_list[MAX_NUM_SOURCES];
-gboolean g_eos_list[MAX_NUM_SOURCES];
 gboolean g_source_enabled[MAX_NUM_SOURCES];
 
 GMutex eos_lock;
-
 GstElement *g_streammux = NULL;
 std::shared_ptr<InferInfo> g_InferInfo = NULL;
-
-map<string, map<int, queue<std::shared_ptr<cv::Mat>>>> m_frames;
-
 std::vector<cv::Scalar> colors_;
-
 #define MAX_SINK_BINS (1024)
-
 static guint server_count = 0;
-
 static GstRTSPServer *server [MAX_SINK_BINS];
 static GMutex server_cnt_lock;
 
-static gboolean
-start_rtsp_streaming (guint rtsp_port_num, guint updsink_port_num, guint64 udp_buffer_size)
-{
-  GstRTSPMountPoints *mounts;
-  GstRTSPMediaFactory *factory;
-  char udpsrc_pipeline[512];
-  char port_num_Str[64] = { 0 };
-
-  if (udp_buffer_size == 0)
-    udp_buffer_size = 512 * 1024;
-
-  sprintf (udpsrc_pipeline,
-      "( udpsrc name=pay0 port=%d buffer-size=%lu caps=\"application/x-rtp, media=video, "
-      "clock-rate=90000, encoding-name=%s, payload=96 \" )",
-      updsink_port_num, udp_buffer_size, "H264");
-
-  sprintf (port_num_Str, "%d", rtsp_port_num);
-
-  g_mutex_lock (&server_cnt_lock);
-
-  server [server_count] = gst_rtsp_server_new ();
-  g_object_set (server [server_count], "service", port_num_Str, NULL);
-
-  mounts = gst_rtsp_server_get_mount_points (server [server_count]);
-
-  factory = gst_rtsp_media_factory_new ();
-  gst_rtsp_media_factory_set_launch (factory, udpsrc_pipeline);
-
-  gst_rtsp_mount_points_add_factory (mounts, "/ds-test", factory);
-
-  g_object_unref (mounts);
-
-  gst_rtsp_server_attach (server [server_count], NULL);
-
-  server_count++;
-
-  g_mutex_unlock (&server_cnt_lock);
-
-  g_print
-      ("\n *** DeepStream: Launched RTSP Streaming at rtsp://localhost:%d/ds-test ***\n\n",
-      rtsp_port_num);
+namespace gsd_ds{
 
-  return TRUE;
-}
+    // m_Inference
+    std::shared_ptr<Inference> m_Inference = nullptr;
 
-// Keep 2 digits after decimal
-static std::string FloatToString(float number) {
-  char buffer[10];
-  snprintf(buffer, sizeof(buffer), "%.2f", number);
-  return std::string(buffer);
-}
+    /**
+     * @description: 构造
+     * @return {*}
+     */
+    Inference::Inference(){}
 
-namespace gsd_ds{
-    ThreadPool pool(4,ThreadPool::PRIORITY_HIGHEST, false);
-    std::shared_ptr<Inference> m_Inference = nullptr;
-    Inference::Inference()
-    {
-        
-    }
+    /**
+     * @description: 析构
+     * @return {*}
+     */    
     Inference::~Inference()
     {
         DebugL << "Returned, stopping playback" << endl;
-        // GstState state;
-        GstStateChangeReturn state_return;
-        g_main_loop_quit (this->loop);
-        state_return = gst_element_set_state(this->pipeline, GST_STATE_NULL);
-
-        StateResulit(state_return);
-        DebugL << "Deleting pipeline";
-        
+        this->m_InferInfo = NULL;
+    } 
+    
+    /**
+     * @description: 释放
+     * @return {*}
+     */    
+    void Inference::Destory(){
+        gst_element_set_state(this->pipeline, GST_STATE_NULL);
         gst_object_unref(GST_OBJECT(this->pipeline));
         g_source_remove(this->bus_watch_id);
         g_main_loop_unref(this->loop);
         g_mutex_clear (&eos_lock);
+    }
+
+    /**
+     * @description: Quit
+     * @return {*}
+     */    
+    void Inference::QuitLoop(){
+        g_main_loop_quit (this->loop);
+    }
+
+    /**
+     * @description: 启动rtsp
+     * @param {guint} rtsp_port_num
+     * @param {guint} updsink_port_num
+     * @param {guint64} udp_buffer_size
+     * @return {*}
+     */
+    gboolean Inference::start_rtsp_streaming (guint rtsp_port_num, guint updsink_port_num, guint64 udp_buffer_size)
+    {
+        GstRTSPMountPoints *mounts;
+        GstRTSPMediaFactory *factory;
+        char udpsrc_pipeline[512];
+        char port_num_Str[64] = { 0 };
+        if (udp_buffer_size == 0)
+        udp_buffer_size = 512 * 1024;
+        sprintf (udpsrc_pipeline,
+            "( udpsrc name=pay0 port=%d buffer-size=%lu caps=\"application/x-rtp, media=video, "
+            "clock-rate=90000, encoding-name=%s, payload=96 \" )",
+            updsink_port_num, udp_buffer_size, "H264");
+        sprintf (port_num_Str, "%d", rtsp_port_num);
+        g_mutex_lock (&server_cnt_lock);
+        server [server_count] = gst_rtsp_server_new ();
+        g_object_set (server [server_count], "service", port_num_Str, NULL);
+        mounts = gst_rtsp_server_get_mount_points (server [server_count]);
+        factory = gst_rtsp_media_factory_new ();
+        gst_rtsp_media_factory_set_launch (factory, udpsrc_pipeline);
+        gst_rtsp_mount_points_add_factory (mounts, "/live", factory);
+        g_object_unref (mounts);
+        gst_rtsp_server_attach (server [server_count], NULL);
+        server_count++;
+        g_mutex_unlock (&server_cnt_lock);
+        InfoL << "Play: rtsp://localhost:" << rtsp_port_num << "/live" << endl;
+        return TRUE;
+    }
+
+    /**
+     * @description: FloatToString
+     * @param {float} number
+     * @return {*}
+     */
+    std::string Inference::FloatToString(float number) {
+        char buffer[10];
+        snprintf(buffer, sizeof(buffer), "%.2f", number);
+        return std::string(buffer);
+    }
 
-        this->m_InferInfo = NULL;
-    } 
-    
     /**
      * @description: 获取Enable
      * @return {*}
@@ -173,36 +167,33 @@ namespace gsd_ds{
      */   
     int32_t Inference::Init()
     {
-        m_recorder = recorder::CreateNew();
-        // init
+        this->m_recorder = recorder::CreateNew();
         this->loop = g_main_loop_new (NULL, FALSE);
-
-        colors_ = GenerateColorsForCategories(80);
-
-        // 创建管道
+        colors_ = osd::GenerateColorsForCategories(80);
+        // create pipeline
         this->pipeline = gst_pipeline_new("gsd-pipeline");
 
-        // 创建批处理器
+        // create streammux
         this->streammux = gst_element_factory_make ("nvstreammux", "stream-muxer");
 
         g_streammux = this->streammux;
 
-        if(this->pipeline == NULL || this->streammux == NULL){
+        if(this->pipeline == nullptr || this->streammux == nullptr){
             ErrorL << "One element could not be created. Exiting.";
             return ERR;
         }
-
-        GstCaps *caps = NULL;
-
+        
+        // gst_bin_add
         gst_bin_add (GST_BIN (this->pipeline), streammux);
+
         this->m_InferInfo = InferInfo::CreateNew();
         g_InferInfo = this->m_InferInfo;
 
         // 创建数据源
         std::vector<DataSource>::iterator iter;
-        g_num_sources = 0;
+        int num_sources = 0;
         for(iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
-            GstElement *source_bin = create_uridecode_bin (g_num_sources, (gchar*)((*iter).uri).c_str());
+            GstElement *source_bin = create_uridecode_bin (num_sources, (gchar*)((*iter).uri).c_str());
             if (!source_bin) {
                 ErrorL << "Failed to create source bin. Exiting."; 
                 return ERR;
@@ -210,7 +201,7 @@ namespace gsd_ds{
             gst_bin_add(GST_BIN (this->pipeline), source_bin);
             iter->source_bin = source_bin;
             iter->Play = true;
-            g_num_sources++;
+            num_sources++;
         }
         /* Use nvinfer to infer on batched frame. */
         this->pgie = gst_element_factory_make("nvinfer", "primary-nvinference-engine");
@@ -233,30 +224,27 @@ namespace gsd_ds{
         this->nvosd = gst_element_factory_make ("nvdsosd", "nv-onscreendisplay");
 
         g_object_set (G_OBJECT (nvosd), "display-text", 1, NULL);
-        g_object_set (G_OBJECT (nvosd), "display-clock", 1, NULL);
+        g_object_set (G_OBJECT (nvosd), "display-clock", 0, NULL);
         g_object_set (G_OBJECT (nvosd), "display-bbox", 1, NULL);
         g_object_set (G_OBJECT (nvosd), "display-mask", 1, NULL);
         g_object_set (G_OBJECT (nvosd), "process-mode", 2, NULL);
 
         this->caps_filter = gst_element_factory_make ("capsfilter", "capsfilter");
-        caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420");
+        GstCaps *caps = gst_caps_from_string ("video/x-raw(memory:NVMM), format=I420");
         this->encoder = gst_element_factory_make ("nvv4l2h264enc", "encoder");
-
-        guint profile = 0;
-        guint bitrate = 4000000;
-        guint iframeinterval = 40;
-
+    
         this->codecparser = gst_element_factory_make ("h264parse", "h264-parser2");
         this->rtppay = gst_element_factory_make ("rtph264pay", "rtppay");
         this->sink = gst_element_factory_make ("udpsink", "udpsink");
 
         g_object_set (G_OBJECT (caps_filter), "caps", caps, NULL);
-        g_object_set (G_OBJECT (encoder), "profile", profile, NULL);
-        g_object_set (G_OBJECT (encoder), "iframeinterval", iframeinterval, NULL);
-        g_object_set (G_OBJECT (encoder), "bitrate", bitrate, NULL);
+        g_object_set (G_OBJECT (encoder), "profile", 0, NULL);
+        g_object_set (G_OBJECT (encoder), "iframeinterval", 50, NULL);
+        g_object_set (G_OBJECT (encoder), "bitrate", 4000000, NULL);
         g_object_set (G_OBJECT (encoder), "preset-level", 1, NULL);
         g_object_set (G_OBJECT (encoder), "insert-sps-pps", 1, NULL);
         g_object_set (G_OBJECT (encoder), "bufapi-version", 1, NULL);
+
         g_object_set (G_OBJECT (sink), "host", "224.224.255.255", "port",
             5400, "async", FALSE, "sync", 0, NULL);
 
@@ -274,10 +262,8 @@ namespace gsd_ds{
             return -1;
         }
 
-        g_object_set(G_OBJECT(streammux), "batch-size", g_num_sources, NULL);
-
+        g_object_set(G_OBJECT(streammux), "batch-size", num_sources, NULL);
         g_object_set(G_OBJECT(streammux), "live-source", 1, NULL);
-
         g_object_set (G_OBJECT (streammux), "width", MUXER_OUTPUT_WIDTH, "height",MUXER_OUTPUT_HEIGHT,
             "batched-push-timeout", MUXER_BATCH_TIMEOUT_USEC, NULL);
 
@@ -288,9 +274,9 @@ namespace gsd_ds{
         /* Override the batch-size set in the config file with the number of sources. */
         g_object_get (G_OBJECT (this->pgie), "batch-size", &(this->pgie_batch_size), NULL);
 
-        if ((int)this->pgie_batch_size != g_num_sources) {
-            WarnL << "WARNING: Overriding infer-config batch-size:" << this->pgie_batch_size << "with number of sources ("<<  g_num_sources << ")";
-            g_object_set (G_OBJECT (this->pgie), "batch-size", g_num_sources, NULL);
+        if ((int)this->pgie_batch_size != num_sources) {
+            WarnL << "WARNING: Overriding infer-config batch-size:" << this->pgie_batch_size << "with number of sources ("<<  num_sources << ")";
+            g_object_set (G_OBJECT (this->pgie), "batch-size", num_sources, NULL);
         }
         
         g_object_set (G_OBJECT (this->sink), "qos", 0, NULL);
@@ -301,24 +287,24 @@ namespace gsd_ds{
         this->bus_watch_id = gst_bus_add_watch (this->bus, bus_call, this->loop);
         gst_object_unref (this->bus);
         
-        gst_bin_add_many (GST_BIN (this->pipeline), this->queue1, this->pgie, this->tiler, this->queue2, this->nvvidconv, this->nvosd, this->nvvidconv_postosd,this->queue3,this->caps_filter,this->queue4,this->encoder, this->rtppay, this->sink, NULL);
+        gst_bin_add_many (GST_BIN (this->pipeline),this->queue1, this->pgie,this->queue2, this->nvvidconv,this->tiler,this->nvosd,this->nvvidconv_postosd,this->caps_filter,this->queue4, this->encoder, this->queue3,this->rtppay, this->sink, NULL);
 
-        if (!gst_element_link_many (streammux, this->queue1, this->pgie, this->tiler, this->queue2,this->nvvidconv, this->nvosd, this->nvvidconv_postosd,this->queue3,this->caps_filter,this->queue4, this->encoder, this->rtppay, this->sink, NULL)) {
+        if (!gst_element_link_many (streammux, this->queue1, this->pgie,this->queue2,this->nvvidconv, this->tiler,this->nvosd, this->nvvidconv_postosd,this->caps_filter,this->queue4, this->encoder, queue3,this->rtppay, this->sink, NULL)) {
             ErrorL << "Elements could not be linked. Exiting.";
             return -1;
         }
 
-        gboolean ret = TRUE;
-        ret = start_rtsp_streaming (8554, 5400, 0);
-
+        start_rtsp_streaming (8554, 5400, 0);
+    
         this->DynamicAdjust();
         
         this->tiler_sink_pad = gst_element_get_static_pad (this->nvvidconv, "src");
         gst_pad_add_probe (this->tiler_sink_pad, GST_PAD_PROBE_TYPE_BUFFER,
                 tiler_sink_pad_buffer_probe, NULL, NULL);
         gst_object_unref (this->tiler_sink_pad);
-
+    
         this->enable = true;
+
         return OK;
     }
 
@@ -332,17 +318,22 @@ namespace gsd_ds{
     {
         static int num = 0;
         InfoL << "启动" << endl;
-        pool.async([&](){
-            if(num == 0){
-                num++;
-                this->RestartTask();
-                // 不能去掉, 去掉会触发Deepstream内部句柄无法释放的Bug
-                g_main_loop_run(this->loop);
-            }else{
-                this->RestartTask();
-            }
-        });
-        pool.start();
+        gst_element_set_state(this->pipeline, GST_STATE_PLAYING);
+        g_main_loop_run(this->loop);
+        // if(m_pool == nullptr) return -1;
+        // m_pool->async([&](){
+        //     if(num == 0){
+        //         num++;
+        //         this->RestartTask();
+        //         // 不能去掉, 去掉会触发Deepstream内部句柄无法释放的Bug
+        //         g_main_loop_run(this->loop);
+        //         WarnL;
+
+        //     }else{
+        //         this->RestartTask();
+        //     }
+        // });
+        // m_pool->start();
         return OK;
     }
     
@@ -351,7 +342,8 @@ namespace gsd_ds{
      * @param {int} num
      * @return {*}
      */    
-    void Inference::SetBatch(int num){
+    void Inference::SetBatch(int num)
+    {
         g_object_set(G_OBJECT(this->streammux), "batch-size", num, NULL);
         g_object_set (G_OBJECT (this->pgie), "batch-size", num, NULL);
     }
@@ -366,18 +358,13 @@ namespace gsd_ds{
     {
         GstStateChangeReturn state_return;
         std::vector<DataSource>::iterator iter;
-
         for (iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
             if(iter->source_bin != NULL){
                 state_return = gst_element_set_state(iter->source_bin, GST_STATE_NULL);
                 StateResulit(state_return);
             }
         }
-        state_return = gst_element_set_state(this->streammux, GST_STATE_NULL);
-        StateResulit(state_return);
-        
         this->Play = false;
-        NoticeCenter::Instance().emitEvent(NOTICE_RELEASE);
     }
 
     /**
@@ -388,33 +375,26 @@ namespace gsd_ds{
      */    
     int32_t Inference::RestartTask()
     {
+        this->StopTask();
+
+        g_object_set (G_OBJECT (encoder), "profile", 0, NULL);
+        g_object_set (G_OBJECT (encoder), "iframeinterval", 40, NULL);
+        g_object_set (G_OBJECT (encoder), "bitrate", 4000000, NULL);
+        this->DynamicAdjust();
         int num = 0;
-        GstStateChangeReturn state_return;
         std::vector<DataSource>::iterator iter;
         for(iter=this->m_InferInfo->DataSources.begin(); iter!=this->m_InferInfo->DataSources.end();iter++){
             if(iter->Play && iter->source_bin != NULL) num++;
         }
-        for (iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
-            if(iter->source_bin != NULL){
-                state_return = gst_element_set_state(iter->source_bin, GST_STATE_NULL);
-                StateResulit(state_return);
-            }
-        }
-        state_return = gst_element_set_state(this->streammux, GST_STATE_NULL);
-        StateResulit(state_return);
-
         if(num == 0){
             DebugL << "没有数据源需要播放" << endl;
             this->Play = false;
             return ERR;
         }
         DebugL << "StartTask" << endl;
-
         gst_element_set_state(this->pipeline, GST_STATE_PAUSED);
         gst_element_set_state(this->pipeline, GST_STATE_PLAYING);
-        m_frames.clear();
         this->Play = true;
-        InferNum++;
         return OK;
     }
 
@@ -496,12 +476,11 @@ namespace gsd_ds{
             for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;l_obj = l_obj->next) 
             {
                 obj_meta = (NvDsObjectMeta *) (l_obj->data);
-                if (obj_meta->class_id == 14) {
+                if (obj_meta->class_id == 67) {
                     num++;
                 }
             } 
             NoticeCenter::Instance().emitEvent(NOTICE_DEV, frame_meta->source_id, num);
-
             if(src_data == nullptr) {
                 src_data = (char*) malloc(surface->surfaceList[frame_meta->batch_id].dataSize);
             }
@@ -540,12 +519,12 @@ namespace gsd_ds{
             // 编码数据
             cv::resize(*frame, *frame, cv::Size(960, 540)); 
             if(num == 0) {
-                recorder::getPtr()->ConsumerData(g_InferInfo->DataSources[frame_meta->source_id].Pid, num, *frame);
+                recorder::getPtr()->ConsumerData(std::to_string(g_InferInfo->DataSources[frame_meta->source_id].dv_Id), num, *frame);
                 continue;
             }
             for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;l_obj = l_obj->next){
                 obj_meta = (NvDsObjectMeta *) (l_obj->data);
-                if (obj_meta->class_id == 14) {
+                if (obj_meta->class_id == 67) {
                     DsInferInfo data;
                     NvDsComp_BboxInfo boxInfo;
                     boxInfo = obj_meta->detector_bbox_info;
@@ -571,7 +550,7 @@ namespace gsd_ds{
             cnStreamInferData->height = frame->rows;
             for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;l_obj = l_obj->next){
                 obj_meta = (NvDsObjectMeta *) (l_obj->data);
-                if (obj_meta->class_id == 14) {
+                if (obj_meta->class_id == 67) {
                     NvDsComp_BboxInfo boxInfo;
                     boxInfo = obj_meta->detector_bbox_info;
                     NvBbox_Coords box_Coord;
@@ -588,15 +567,15 @@ namespace gsd_ds{
 
                     bottom_left.x = (box_Coord.left) / frame_width * frame->cols;
                     bottom_left.y = (box_Coord.top +  box_Coord.height) / frame_height * frame->rows;
-                    DrawBox(*frame, top_left, bottom_right, colors_[obj_meta->class_id]);
+                    osd::DrawBox(*frame, top_left, bottom_right, colors_[obj_meta->class_id]);
                     std::string text;
                     text = obj_meta->obj_label;
                     text = text + " " + FloatToString(obj_meta->confidence);
-                    if(num <= 5) DrawText(*frame, bottom_left, text, colors_[obj_meta->class_id]);
+                    if(num <= 5) osd::DrawText(*frame, bottom_left, text, colors_[obj_meta->class_id]);
                 }
             }
-            recorder::getPtr()->ConsumerData(g_InferInfo->DataSources[frame_meta->source_id].Pid, num, *frame);
-            cnStreamInferData->videoPath = recorder::getPtr()->GetFileName(g_InferInfo->DataSources[frame_meta->source_id].Pid);
+            recorder::getPtr()->ConsumerData(std::to_string(g_InferInfo->DataSources[frame_meta->source_id].dv_Id), num, *frame);
+            cnStreamInferData->videoPath = recorder::getPtr()->GetFileName(std::to_string(g_InferInfo->DataSources[frame_meta->source_id].dv_Id));
             NoticeCenter::Instance().emitEvent(NOTICE_INFER, frame_meta->source_id, cnStreamInferData);
         }
         if(src_data != NULL) {
@@ -651,105 +630,6 @@ namespace gsd_ds{
     }
 
     /**
-     * @description: 画框
-     * @return {*}
-     */    
-    void Inference::DrawBox(cv::Mat image, const cv::Point& top_left, const cv::Point& bottom_right,
-                    const cv::Scalar& color) {
-        float w =bottom_right.x - top_left.x;
-        float h =bottom_right.y - top_left.y;
-        int wscale = w * .25f;
-        int hscale = h * .25f;
-        cv::Point top_right(bottom_right.x,top_left.y);
-        cv::Point bottom_left(top_left.x,bottom_right.y);
-        // -- 
-        cv::line(image,top_left,cv::Point(top_left.x + wscale,top_left.y),color, CalcThickness(image.cols, 1));
-        // |
-        cv::line(image,top_left,cv::Point(top_left.x ,top_left.y + hscale),color, CalcThickness(image.cols, 1));
-        //      --
-        cv::line(image,cv::Point(top_right.x - wscale,top_right.y),top_right,color, CalcThickness(image.cols, 1));
-        //        |
-        cv::line(image,top_right,cv::Point(top_right.x,top_right.y + hscale),color, CalcThickness(image.cols, 1));
-        //
-        // __
-        cv::line(image,bottom_left,cv::Point(bottom_left.x+wscale,bottom_left.y),color, CalcThickness(image.cols, 1));
-        //
-        //|
-        cv::line(image,bottom_left,cv::Point(bottom_left.x,bottom_left.y - hscale),color, CalcThickness(image.cols, 1));
-        //
-        //        |
-        cv::line(image,bottom_right,cv::Point(bottom_right.x,bottom_right.y - hscale),color, CalcThickness(image.cols, 1));
-        
-        cv::line(image,bottom_right,cv::Point(bottom_right.x - wscale,bottom_right.y),color, CalcThickness(image.cols, 1));
-    }
-
-    /**
-     * @description: 
-     * @param {int} image_width
-     * @param {float} thickness
-     * @return {*}
-     */    
-    int Inference::CalcThickness(int image_width, float thickness) {
-        int result = thickness * image_width / 300;
-        if (result <= 0) result = 1;
-        return result;
-    }
-
-    /**
-     * @description: CalcScale
-     * @param {int} image_width
-     * @param {float} scale
-     * @return {*}
-     */    
-    double Inference::CalcScale(int image_width, float scale)  { 
-        return scale * image_width / 1000; 
-    }
-    
-    /**
-     * @description: DrawText
-     * @return {*}
-     */    
-    void Inference::DrawText(cv::Mat image, const cv::Point& bottom_left, const std::string& text, const cv::Scalar& color,
-                     float scale, int* text_height)  {
-        double txt_scale = CalcScale(image.cols, 1) * scale;
-        int txt_thickness = CalcThickness(image.cols, 1) * scale;
-        int box_thickness = CalcThickness(image.cols, 1) * scale;
-
-        int baseline = 0;
-        int space_before = 0;
-        cv::Size text_size;
-        int label_height;
-        
-        text_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, txt_scale, txt_thickness, &baseline);
-        space_before = 3 * txt_scale;
-        text_size.width += space_before * 2;
-  
-        label_height = baseline + txt_thickness + text_size.height;
-        int offset = (box_thickness == 1 ? 0 : - (box_thickness + 1) / 2);
-        cv::Point label_top_left = bottom_left + cv::Point(offset, offset);
-        cv::Point label_bottom_right = label_top_left + cv::Point(text_size.width + offset, label_height);
-        // move up if the label is beyond the bottom of the image
-        if (label_bottom_right.y > image.rows) {
-            label_bottom_right.y -= label_height;
-            label_top_left.y -= label_height;
-        }
-        // move left if the label is beyond the right side of the image
-        if (label_bottom_right.x > image.cols) {
-            label_bottom_right.x = image.cols;
-            label_top_left.x = image.cols - text_size.width;
-        }
-        // draw text background
-        cv::rectangle(image, label_top_left, label_bottom_right, color, -1);
-        // draw text
-        cv::Point text_left_bottom =
-            label_top_left + cv::Point(space_before, label_height - baseline / 2 - txt_thickness / 2);
-        cv::Scalar text_color = cv::Scalar(255, 255, 255) - color;
-        char* str = const_cast<char*>(text.data());
-        cv::putText(image, text, text_left_bottom, cv::FONT_HERSHEY_SIMPLEX, txt_scale, text_color, txt_thickness);
-        if (text_height) *text_height = text_size.height + baseline;
-    }
-
-    /**
      * @description: 监听bus
      * @param {GstBus *} bus Deepstream的bus
      * @param {GstMessage *} msg 传递到bus中的msg
@@ -768,9 +648,9 @@ namespace gsd_ds{
                 gchar *debug;
                 GError *error;
                 gst_message_parse_warning (msg, &error, &debug);
-                // WarnL << "WARNING from element " << GST_OBJECT_NAME (msg->src) << ": " << error->message;
+                WarnL << "WARNING from element " << GST_OBJECT_NAME (msg->src) << ": " << error->message;
                 g_free (debug);
-                // WarnL << "Warning: " << error->message;
+                WarnL << "Warning: " << error->message;
                 g_error_free (error);
                 break;
             }
@@ -815,16 +695,13 @@ namespace gsd_ds{
     {
         WarnL << "Decodebin child added: " << name;
         if (g_strrstr (name, "decodebin") == name) {
-            
             g_signal_connect (G_OBJECT (object), "child-added",
                 G_CALLBACK (decodebin_child_added), user_data);
         }
         if (g_strrstr (name, "nvv4l2decoder") == name) {
         #ifdef PLATFORM_TEGRA
             g_object_set (object, "enable-max-performance", TRUE, NULL);
-            //g_object_set (object, "bufapi-version", TRUE, NULL);
-            g_object_set (object, "drop-frame-interval", 0, NULL);
-            // g_object_set (object, "num-extra-surfaces", 2, NULL);
+            g_object_set (object, "drop-frame-interval", 2, NULL);
         #else
             g_object_set (object, "gpu-id", 0, NULL);
         #endif
@@ -844,7 +721,6 @@ namespace gsd_ds{
         GstPad *sinkpad = NULL;
         GstState state;
         gst_element_get_state(this->m_InferInfo->DataSources[source_id].source_bin,&state,NULL, GST_CLOCK_TIME_NONE);
-        // DebugL << "state:" << state << endl;
         WarnL << "stop_source ID:( " << source_id << " , " << this->m_InferInfo->DataSources[source_id].uri << ")" << endl;
         if(state == GST_STATE_NULL){
             gst_bin_remove (GST_BIN (this->pipeline), this->m_InferInfo->DataSources[source_id].source_bin);
@@ -854,10 +730,10 @@ namespace gsd_ds{
             switch (state_return) {
                 case GST_STATE_CHANGE_SUCCESS:
                     InfoL << "STATE CHANGE SUCCESS";
-                    // g_snprintf (pad_name, 15, "sink_%u", source_id);
-                    // sinkpad = gst_element_get_static_pad (this->streammux, pad_name);
-                    // gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE));
-                    // gst_element_release_request_pad (this0>streammux, sinkpad);
+                    g_snprintf (pad_name, 15, "sink_%u", source_id);
+                    sinkpad = gst_element_get_static_pad (this->streammux, pad_name);
+                    gst_pad_send_event (sinkpad, gst_event_new_flush_stop (FALSE));
+                    gst_element_release_request_pad (this->streammux, sinkpad);
                     gst_bin_remove (GST_BIN (this->pipeline), this->m_InferInfo->DataSources[source_id].source_bin);
                     DebugL << "该source_bin移除成功" << endl;
                     break;
@@ -873,7 +749,7 @@ namespace gsd_ds{
                 default:
                     break;
             }
-        }
+        }   
         g_mutex_unlock (&eos_lock);
     }
 
@@ -890,7 +766,6 @@ namespace gsd_ds{
         GstCaps *caps = gst_pad_query_caps (pad, NULL);
         const GstStructure *str = gst_caps_get_structure (caps, 0);
         const gchar *name = gst_structure_get_name (str);
-
         WarnL << "decodebin new pad " << name;
         if (!strncmp (name, "video", 5)) {
             gint source_id = (*(gint *) data);
@@ -947,7 +822,7 @@ namespace gsd_ds{
     {
         g_mutex_lock (&eos_lock);
         GstElement *source_bin;
-
+        
         source_bin = create_uridecode_bin (source_Id, (gchar *)uri.c_str());
         if (!source_bin) {
             ErrorL << "Failed to create source bin. Exiting.";
@@ -970,16 +845,6 @@ namespace gsd_ds{
     }
 
     /**
-     * @description: 释放资源
-     * @param {GstElement} *source_bin
-     * @return {*}
-     */    
-    void Inference::FreeElement(int source_Id,GstElement *source_bin)
-    {
-        // gst_object_unref(GST_OBJECT(source_bin));
-    }
-
-    /**
      * @description: 添加数据源
      * @param {*}
      * @return {*}
@@ -991,33 +856,19 @@ namespace gsd_ds{
     }
 
     /**
-     * @description: 检查任务 
-     * @return {*}
-     */    
-    void Inference::CheckTask()
-    {
-        GstState state;
-        GstStateChangeReturn state_return;
-        for (auto iter = this->m_InferInfo->DataSources.begin(); iter != this->m_InferInfo->DataSources.end(); iter++){
-            if(iter->source_bin != NULL){
-                state_return = gst_element_set_state(iter->source_bin, GST_STATE_NULL);
-                // StateResulit(state_return);
-            }
-        }
-    }
-    
-    /**
      * @description: 动态调节
      * @return {*}
      */    
     void Inference::DynamicAdjust(){
-        int num = 0;
+        // int num = 0;
         // std::vector<DataSource>::iterator iter;
         // for(iter=this->m_InferInfo->DataSources.begin(); iter!=this->m_InferInfo->DataSources.end();iter++){
         //     if(iter->Play && iter->source_bin != NULL) num++;
         // }
-        // if(num <= 2) g_object_set (G_OBJECT (this->pgie), "interval", 1, NULL);
+        // if(num == 1) g_object_set (G_OBJECT (this->pgie), "interval", 0, NULL);
+        // else if(num <= 2) g_object_set (G_OBJECT (this->pgie), "interval", 1, NULL);
         // else if(num > 2 && num <= 4) g_object_set (G_OBJECT (this->pgie), "interval", 2, NULL);
         // else if(num > 4 && num <= 6) g_object_set (G_OBJECT (this->pgie), "interval", 3, NULL);
     }
 }
+

+ 174 - 0
modules/inference/src/osd.cpp

@@ -0,0 +1,174 @@
+#include "osd.h"
+
+namespace gsd_ds
+{
+    /**
+     * @description: HSV2RGB
+     * @param {float} h
+     * @param {float} s
+     * @param {float} v
+     * @return {*}
+     */    
+    cv::Scalar osd::HSV2RGB(const float h, const float s, const float v){
+        const int h_i = static_cast<int>(h * 6);
+        const float f = h * 6 - h_i;
+        const float p = v * (1 - s);
+        const float q = v * (1 - f * s);
+        const float t = v * (1 - (1 - f) * s);
+        float r, g, b;
+        switch (h_i) {
+            case 0:
+            r = v;
+            g = t;
+            b = p;
+            break;
+            case 1:
+            r = q;
+            g = v;
+            b = p;
+            break;
+            case 2:
+            r = p;
+            g = v;
+            b = t;
+            break;
+            case 3:
+            r = p;
+            g = q;
+            b = v;
+            break;
+            case 4:
+            r = t;
+            g = p;
+            b = v;
+            break;
+            case 5:
+            r = v;
+            g = p;
+            b = q;
+            break;
+            default:
+            r = 1;
+            g = 1;
+            b = 1;
+            break;
+        }
+        return cv::Scalar(r * 255, g * 255, b * 255);
+    }   
+
+    /**
+     * @description: GenerateColorsForCategories
+     * @param {int} n
+     * @return {*}
+     */    
+    std::vector<cv::Scalar> osd::GenerateColorsForCategories(const int n){
+        std::vector<cv::Scalar> colors;
+        cv::RNG rng(12345);
+        const float golden_ratio_conjugate = 0.618033988749895f;
+        const float s = 0.3f;
+        const float v = 0.99f;
+        for (int i = 0; i < n; ++i) {
+            const float h = std::fmod(rng.uniform(0.0f, 1.0f) + golden_ratio_conjugate, 1.0f);
+            colors.push_back(HSV2RGB(h, s, v));
+        }
+            return colors;
+    }
+
+    /**
+     * @description: DrawBox
+     * @return {*}
+     */    
+    void osd::DrawBox(cv::Mat image, const cv::Point& top_left, const cv::Point& bottom_right,
+                    const cv::Scalar& color) {
+        float w =bottom_right.x - top_left.x;
+        float h =bottom_right.y - top_left.y;
+        int wscale = w * .25f;
+        int hscale = h * .25f;
+        cv::Point top_right(bottom_right.x,top_left.y);
+        cv::Point bottom_left(top_left.x,bottom_right.y);
+        // -- 
+        cv::line(image,top_left,cv::Point(top_left.x + wscale,top_left.y),color, CalcThickness(image.cols, 1));
+        // |
+        cv::line(image,top_left,cv::Point(top_left.x ,top_left.y + hscale),color, CalcThickness(image.cols, 1));
+        //      --
+        cv::line(image,cv::Point(top_right.x - wscale,top_right.y),top_right,color, CalcThickness(image.cols, 1));
+        //        |
+        cv::line(image,top_right,cv::Point(top_right.x,top_right.y + hscale),color, CalcThickness(image.cols, 1));
+        //
+        // __
+        cv::line(image,bottom_left,cv::Point(bottom_left.x+wscale,bottom_left.y),color, CalcThickness(image.cols, 1));
+        //
+        //|
+        cv::line(image,bottom_left,cv::Point(bottom_left.x,bottom_left.y - hscale),color, CalcThickness(image.cols, 1));
+        //
+        //        |
+        cv::line(image,bottom_right,cv::Point(bottom_right.x,bottom_right.y - hscale),color, CalcThickness(image.cols, 1));
+        
+        cv::line(image,bottom_right,cv::Point(bottom_right.x - wscale,bottom_right.y),color, CalcThickness(image.cols, 1));
+    }
+
+    /**
+     * @description: 
+     * @param {int} image_width
+     * @param {float} thickness
+     * @return {*}
+     */    
+    int osd::CalcThickness(int image_width, float thickness) {
+        int result = thickness * image_width / 300;
+        if (result <= 0) result = 1;
+        return result;
+    }
+
+    /**
+     * @description: CalcScale
+     * @param {int} image_width
+     * @param {float} scale
+     * @return {*}
+     */    
+    double osd::CalcScale(int image_width, float scale)  { 
+        return scale * image_width / 1000; 
+    }
+    
+    /**
+     * @description: DrawText
+     * @return {*}
+     */    
+    void osd::DrawText(cv::Mat image, const cv::Point& bottom_left, const std::string& text, const cv::Scalar& color,
+                     float scale, int* text_height)  {
+        double txt_scale = CalcScale(image.cols, 1) * scale;
+        int txt_thickness = CalcThickness(image.cols, 1) * scale;
+        int box_thickness = CalcThickness(image.cols, 1) * scale;
+
+        int baseline = 0;
+        int space_before = 0;
+        cv::Size text_size;
+        int label_height;
+        
+        text_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, txt_scale, txt_thickness, &baseline);
+        space_before = 3 * txt_scale;
+        text_size.width += space_before * 2;
+  
+        label_height = baseline + txt_thickness + text_size.height;
+        int offset = (box_thickness == 1 ? 0 : - (box_thickness + 1) / 2);
+        cv::Point label_top_left = bottom_left + cv::Point(offset, offset);
+        cv::Point label_bottom_right = label_top_left + cv::Point(text_size.width + offset, label_height);
+        // move up if the label is beyond the bottom of the image
+        if (label_bottom_right.y > image.rows) {
+            label_bottom_right.y -= label_height;
+            label_top_left.y -= label_height;
+        }
+        // move left if the label is beyond the right side of the image
+        if (label_bottom_right.x > image.cols) {
+            label_bottom_right.x = image.cols;
+            label_top_left.x = image.cols - text_size.width;
+        }
+        // draw text background
+        cv::rectangle(image, label_top_left, label_bottom_right, color, -1);
+        // draw text
+        cv::Point text_left_bottom =
+            label_top_left + cv::Point(space_before, label_height - baseline / 2 - txt_thickness / 2);
+        cv::Scalar text_color = cv::Scalar(255, 255, 255) - color;
+        cv::putText(image, text, text_left_bottom, cv::FONT_HERSHEY_SIMPLEX, txt_scale, text_color, txt_thickness);
+        if (text_height) *text_height = text_size.height + baseline;
+    }
+} // namespace gsd_ds

+ 0 - 2
modules/monitor/src/monitor.cpp

@@ -47,9 +47,7 @@ namespace gsd_ds
         this->file = fopen("/proc/meminfo","r");
         char keyword[20];
         char valuech[20];
-        long mem = 0;
         fscanf(file,"MemTotal: %s kB\n",keyword);
-        mem = atol(keyword)/1000;
         fscanf(file,"MemFree: %s kB\n",valuech);
         fscanf(file,"MemAvailable: %s kB\n",valuech);
         MemoryUsage=atol(valuech)/1000;

+ 0 - 1
modules/recorder/include/recorder.h

@@ -70,7 +70,6 @@ namespace gsd_ds
     public:
         bool enable = true;
         bool RecordEnable = true;
-        int outType = 0;  // 0  图片 1视频
         std::string outDir = "";
         std::string Dir = "./video/";
         using Ptr = std::shared_ptr<recorder>;

+ 4 - 4
modules/recorder/src/InferVideo.cpp

@@ -62,11 +62,11 @@ bool InferVideo::capture(int num, Mat& dst)
             strftime(ctime, 80, "%Y-%m-%d_%H:%M:%S", info);
             string fileName = ctime;
             this -> m_fileName =  fileName  + "_" + this->pid + this->m_enc_type;
-            this -> m_outputDir = this -> m_outputDir + fileName.substr(0,7) + "/";
-            if(opendir(this -> m_outputDir.c_str()) == NULL){
-                mkdir((this->m_outputDir).c_str(),S_IRWXU|S_IRWXG|S_IRWXO);
+            std::string outDir = this -> m_outputDir + fileName.substr(0,7) + "/";
+            if(opendir(outDir.c_str()) == NULL){
+                mkdir((outDir).c_str(),S_IRWXU|S_IRWXG|S_IRWXO);
             } 
-            this -> m_videoWriter = std::make_shared<cv::VideoWriter>("appsrc ! autovideoconvert ! omxh264enc  ! matroskamux ! filesink location=" +  this->m_outputDir + this -> m_fileName + " sync=false", 0, (double)this->m_fps, this -> m_frameSize, true);
+            this -> m_videoWriter = std::make_shared<cv::VideoWriter>("appsrc ! autovideoconvert ! omxh264enc  ! matroskamux ! filesink location=" +  outDir + this -> m_fileName + " sync=false", 0, (double)this->m_fps, this -> m_frameSize, true);
         }
         // 压入视频中
         if(!(this->m_frameBuffer.empty())){

+ 3 - 12
modules/userApp/include/user_app.h

@@ -3,8 +3,8 @@
  * @Version: 1.0
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:41:50
- * @LastEditors: error: git config user.name && git config user.email & please set dead value or install git
- * @LastEditTime: 2022-07-10 18:59:21
+ * @LastEditors: lishengyin
+ * @LastEditTime: 2022-07-20 09:47:08
  */
 #pragma once
 
@@ -35,8 +35,6 @@
 #include "SendLogin.h"
 #include "NettyClientCommandEnum.h"
 #include "InferData.h"
-#include "PIDSClientResultMsg.h"
-#include "PIDSServerResultMsg.h"
 #include "CrowdednessConfig.h"
 #include "CrowdednessTimeConfig.h"
 #include "SendPassengerFlow.h"
@@ -108,14 +106,6 @@ namespace gsd_ds
         static void makeAddr(struct sockaddr *out,const char *ip,uint16_t port);
 
         /**
-         * @description: 
-         * @param {string} Pid
-         * @return {*}
-         */  
-        int GetAddrNum(std::string Pid);
-
-
-        /**
          * @description: 监听推理模块广播
          * @param {int} Source_id 数据源ID
          * @param {CNStreamInferData} 推理指针
@@ -132,6 +122,7 @@ namespace gsd_ds
     private:
         std::string m_appName;
         IniFile m_ini;
+
         const std::string m_configSrc = "../source/config/config.ini";
 
         // Mysql

+ 68 - 44
modules/userApp/src/user_app.cpp

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:35:42
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-07-13 16:59:50
+ * @LastEditTime: 2022-07-20 11:06:20
  */
 #include "user_app.h"
 
@@ -25,12 +25,20 @@ namespace gsd_ds
         return std::make_shared<UserApp>();
     }
     
+    /**
+     * @description: UserApp()
+     * @return {*}
+     */    
     UserApp::UserApp(){
         
     }
     
+    /**
+     * @description: ~UserApp()
+     * @return {*}
+     */    
     UserApp::~UserApp(){
-        Destroy();
+        //Destroy();
     }
 
     /**
@@ -49,13 +57,14 @@ namespace gsd_ds
             return ERR;
         }
         int ret = 0;
-
+        
         this->sql_ip = m_ini.getStringValue("MySql", "sql_ip", ret);
         this->sql_port = m_ini.getIntValue("MySql", "sql_port", ret);
         this->user = m_ini.getStringValue("MySql", "user", ret);
         this->password = m_ini.getStringValue("MySql", "password", ret);
         this->character = m_ini.getStringValue("MySql", "character", ret);
         this->device_id = m_ini.getIntValue("USER", "device_id", ret);
+        recorder::getPtr()->outDir = m_ini.getStringValue("video", "dir", ret);
 
         // 链接Mysql
         #if defined(SUPPORT_DYNAMIC_TEMPLATE)
@@ -79,9 +88,8 @@ namespace gsd_ds
             ErrorL << "Inference module creation failed!" << endl;
             return ERR;
         }
-        SqlWriter sqlSelect("SELECT Id,Uri,RecognitionRange,PId FROM MIVA_DB.`DataSources` WHERE Play = 1 and Del = 0");
+        SqlWriter sqlSelect("SELECT Id,Uri,RecognitionRange,dv_Id FROM gsdDB.`DataSources` WHERE Play = 1 and Del = 0");
         vector<vector<string>> sqlRet;
-
         sqlSelect << sqlRet;
         if(!sqlRet.empty()){
             int sourceId = 0;
@@ -90,10 +98,9 @@ namespace gsd_ds
                 data.Id = std::atoi(line[0].c_str());
                 data.uri = line[1];
                 data.range = line[2];
-                data.Pid = line[3];
+                data.dv_Id = std::atoi(line[3].c_str());
                 data.Play = true;
                 data.sourceId = sourceId;
-                data.AddrNum = GetAddrNum(data.Pid);
                 this->m_InferInfo->DataSources.push_back(data);
                 sourceId++;
             }
@@ -104,7 +111,12 @@ namespace gsd_ds
         }else{
             InfoL << "The stream to be played is not found, please add it in the background.";
         }
-        
+
+        NoticeCenter::Instance().addListener(0,NOTICE_QUITLOOP,
+                [&](){
+                this->m_Infer->QuitLoop();
+        });
+
         // 监听推理广播
         NoticeCenter::Instance().addListener(0,NOTICE_INFER,
                 [&](int Source_id, CNStreamInferData::Ptr data){
@@ -115,10 +127,10 @@ namespace gsd_ds
                 [&](int Source_id, int num){
                 this->ExperControler(Source_id, num);
         });
-    
+
         this->m_httpClient = HttpClient::CreateNew();
         if(this->m_httpClient == nullptr) ErrorL << "无法创建HttpClinet对象" << endl;
-        if(this->m_httpClient->Init("admin2", "0.0.0.0", 9080) != OK){
+        if(this->m_httpClient->Init("admin", "0.0.0.0", 9080) != OK){
             ErrorL << "HttpClinet对象初始化失败" << endl;
         }
         return OK;
@@ -132,7 +144,7 @@ namespace gsd_ds
      */    
     void UserApp::Destroy()
     {
-        this->m_Infer->StopTask();
+        this->m_Infer->Destory();
         InfoL << "System exited successfully!" << endl;
     }
     
@@ -147,15 +159,13 @@ namespace gsd_ds
         // 定时监控数据变化
         this->m_timer1 = std::make_shared<Timer>(3.0f,[&](){
             // 监听数据
-            // if(this->m_manager->getSyncDataPower() == OK) this->MonitorData();
             this->MonitorData();
             return true;
         },nullptr);
-        
-        m_Infer->StartTask();
+        if(!m_InferInfo->DataSources.empty()) m_Infer->StartTask();
         InfoL << "Task started successfully!" << endl;
     }
-
+    
     /**
      * 监听数据
      * @param {*}
@@ -163,36 +173,65 @@ namespace gsd_ds
      */    
     void UserApp::MonitorData()
     {
+        static int flag = 0;
         vector<vector<string>> sqlRet;
         vector<DataSource>::iterator iter;
-        
-        if(this->m_InferInfo->DataSources.empty()) return;
         // 查询
-        std::string sql = "SELECT Id,Uri,RecognitionRange,Play,PId FROM MIVA_DB.`DataSources` WHERE Del = 0 and Play = 1";
+        std::string sql = "SELECT Id,Uri,RecognitionRange,dv_Id FROM gsdDB.`DataSources` WHERE Del = 0 and Play = 1";
         SqlWriter sqlSelect(sql.c_str());
         sqlSelect << sqlRet;
-        
         if(!sqlRet.empty()){
+            int sourceId = 0;
+            if(this->m_InferInfo->DataSources.empty()){
+                for(auto &line : sqlRet){
+                    DataSource data;
+                    data.Id = std::atoi(line[0].c_str());
+                    data.uri = line[1];
+                    data.range = line[2];
+                    data.dv_Id = std::atoi(line[3].c_str());
+                    data.Play = true;
+                    data.sourceId = sourceId;
+                    this->m_InferInfo->DataSources.push_back(data);
+                    sourceId++;
+                }
+                if(!this->m_Infer->getAlive()){
+                    // 初始化Deepstream
+                    if(this->m_Infer->Init() != OK){
+                        ErrorL << "Inference module initialization failed" << endl;
+                    }
+                    this->m_Infer->StartTask();
+                }else{
+                    // 添加数据源
+                    for(auto& data : this->m_InferInfo->DataSources){
+                        data.source_bin = this->m_Infer->add_sources(data.sourceId, data.uri);
+                    }
+                    this->m_Infer->RestartTask();
+                }
+                return;
+            }
             int size = this->m_InferInfo->DataSources.size();
             for(int i = 0; i < size; i++){
                 if(i >= (int)sqlRet.size()) continue;
                 this->m_InferInfo->DataSources[i].Id = atoi(sqlRet[i][0].c_str()); 
                 this->m_InferInfo->DataSources[i].range = sqlRet[i][2];
-                this->m_InferInfo->DataSources[i].Play = atoi(sqlRet[i][3].c_str()) ? true:false;
-                this->m_InferInfo->DataSources[i].Pid = sqlRet[i][4];
-                this->m_InferInfo->DataSources[i].AddrNum = GetAddrNum(sqlRet[i][4]);
+                this->m_InferInfo->DataSources[i].Play = true;
+                this->m_InferInfo->DataSources[i].dv_Id = atoi(sqlRet[i][3].c_str());
                 if(this->m_InferInfo->DataSources[i].uri != sqlRet[i][1]){
                     this->m_Infer->ModifyUri(this->m_InferInfo->DataSources[i].source_bin, sqlRet[i][1]);
+                    flag = 1;
                 }
                 this->m_InferInfo->DataSources[i].uri = sqlRet[i][1];
             }
-            if(size == (int)sqlRet.size()) return;
+            if(size == (int)sqlRet.size()) {
+                if(flag) this->m_Infer->RestartTask();
+                flag = 0;
+                return;
+            }
             if(size > (int)sqlRet.size()){
                 int num = 0;
                 // stop
                 for(int i = sqlRet.size(); i < size; i++){
                     this->m_Infer->stop_release_source(i);
-                    this->m_Infer->FreeElement(i,this->m_InferInfo->DataSources[i].source_bin);
                     this->m_InferInfo->DataSources[i].source_bin = NULL;
                     num++;
                 }
@@ -204,23 +243,19 @@ namespace gsd_ds
                     data.Id = std::atoi(sqlRet[i][0].c_str());
                     data.uri = sqlRet[i][1];
                     data.range = sqlRet[i][2];
-                    data.Pid = sqlRet[i][3];
-                    data.AddrNum = GetAddrNum(data.Pid);
+                    data.dv_Id = std::atoi(sqlRet[i][3].c_str());
                     data.Play = true;
                     data.sourceId = i;
                     data.source_bin = this->m_Infer->add_sources(data.sourceId, data.uri);
                     this->m_InferInfo->DataSources.push_back(data);
                 }
-                
-                this->m_Infer->RestartTask();
-
             }
-            this->m_Infer->DynamicAdjust();
+            this->m_Infer->RestartTask();
             this->m_Infer->SetBatch(this->m_InferInfo->DataSources.size());
         }else{
+            if(this->m_InferInfo->DataSources.empty() && !this->m_Infer->getAlive()) return;
             for(iter=this->m_InferInfo->DataSources.begin(); iter!=this->m_InferInfo->DataSources.end(); iter++){
                 this->m_Infer->stop_release_source(iter->sourceId);
-                this->m_Infer->FreeElement(iter->sourceId,iter->source_bin);
                 iter->source_bin = NULL;
             }
             // 清除数据
@@ -246,18 +281,6 @@ namespace gsd_ds
     }
     
     /**
-     * @description: 获取地址数据
-     * @param {string} Pid
-     * @return {*}
-     */    
-    int UserApp::GetAddrNum(std::string Pid){
-        vector<vector<string>> sqlRet;
-        SqlWriter sqlSelect("SELECT * FROM MIVA_DB.`DataSources` WHERE Play = 1 and Del=0 and Pid='?'");
-        sqlSelect << Pid << sqlRet;
-        return (int)sqlRet.size();
-    }
-    
-    /**
      * @description: 监听推理模块广播
      * @param {int} Source_id 数据源ID
      * @param {CNStreamInferData} 推理指针
@@ -267,6 +290,7 @@ namespace gsd_ds
     void UserApp::ListenInfer(int Source_id, CNStreamInferData::Ptr data){
         if(data == nullptr) return;
         std::string json;
+        data->dv_Id = this->m_InferInfo->DataSources[Source_id].dv_Id;
         data->objectToJson(json);
         if(this->m_httpClient->Post_Bird(json) != OK){
             ErrorL << "请求发送失败" << endl;
@@ -289,7 +313,7 @@ namespace gsd_ds
         }else{
             if(ticker == nullptr) ticker = std::make_shared<Ticker>();
             int time = 10000;
-            if(ticker->elapsedTime() > time && this->m_DevPowerState){
+            if((int)(ticker->elapsedTime()) > time && this->m_DevPowerState){
                 this->m_DevPowerState = false;
                 ticker = nullptr;
                 // CLOSE

+ 3 - 2
source/config/config.ini

@@ -2,11 +2,12 @@
 sql_ip = 127.0.0.1
 sql_port = 3306
 user = root
-password = 123456
+password = sunwin2022
 character = utf8mb4
 
 [USER]
 device_id = 1
 
-
+[video]
+dir = /opt/datas/video/
 

+ 1 - 1
source/config/config_infer_primary_yoloV5.txt

@@ -55,7 +55,7 @@ network-type=0
 output-blob-names=prob
 ## 0=Group Rectangles, 1=DBSCAN, 2=NMS, 3= DBSCAN+NMS Hybrid, 4 = None(No clustering)
 cluster-mode=2
-interval=1
+interval=0
 maintain-aspect-ratio=1
 parse-bbox-func-name=NvDsInferParseCustomYoloV5
 custom-lib-path=../../lib/libnvdsinfer_custom_impl_Yolo.so

+ 6 - 6
source/src/main.cpp

@@ -4,7 +4,7 @@
  * @Autor: lishengyin
  * @Date: 2021-10-13 09:35:48
  * @LastEditors: lishengyin
- * @LastEditTime: 2022-07-08 13:52:09
+ * @LastEditTime: 2022-07-20 11:06:44
  */
 #include <iostream>
 #include "user_app.h"
@@ -21,7 +21,11 @@ int main(int argc, char *argv[])
 {
   //设置退出信号处理函数
   static semaphore sem;
-  signal(SIGINT, [](int) { sem.post(); });// 设置退出信号
+
+  signal(SIGINT, [](int) { 
+    sem.post(); 
+    NoticeCenter::Instance().emitEvent(NOTICE_QUITLOOP);
+  });// 设置退出信号
 
    //设置日志
   Logger::Instance().add(std::make_shared<ConsoleChannel>());
@@ -38,12 +42,8 @@ int main(int argc, char *argv[])
     ErrorL << "System initialization failed";
     return ERR;
   }
-  
   // 挂起任务
   app->StartTask();
-
-  sem.wait();
   app->Destroy();
-
   return 0;
 }