chenshijun
2019-04-22 291dbcd9331cd0df41addef74defa4654ee034fb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "RtspCaptureElement.h"
#include <basic/debug/Debug.h>
#include <opencv2/opencv.hpp>
#include <basic/timer_counter/Clocktimer.h>
#include <thread>
#include <basic/util/app/AppPreference.hpp>
#include <QString>
#include <QDateTime>
#include "RtspAnalysManager.h"
//#include <basic/pipe_element/ffmpeg/cap_ffmpeg_impl.hpp>
#include "../../../BasicPlatForm/basic/pipe_element/ffmpeg/FfmpegElement.cpp"
#include <basic/util/app/AppConfig.h>
 
RtspCaptureElement::RtspCaptureElement(const std::string &path, const std::string &camId, int fps, int reopenTime,
                                       int gpuIndex, RtspAnalysManager *manager) :
    TimerElement(10), m_path(path), m_gpuIndex(gpuIndex),
    m_reopenTime(reopenTime), m_camId(camId), m_pManager(manager) {
    m_cutPath = appPref.getStringData("user.loop.absolute.path");
 
    assert(!m_cutPath.empty());
    m_capture = new CvCapture_FFMPEG(m_camId);
}
 
//定时抓取图片,通过将图片放入RtspImageRedisElement的队列中,来减少视频的丢帧
void RtspCaptureElement::timerFunc() {
 
    bool ret = m_capture->grabFrame();
    if (!ret) {
        if (m_reopenTime < 0) {
            stop();
            INFO("grabFrame faild, element stopping");
            return;
        } else {
            usleep(m_reopenTime * 100);
            INFO("grabFrame faild, try reopen video: " << m_path);
            openVideo();
            ret = m_capture->grabFrame();
            if (!ret)return;
        }
    }
 
    u_char *data;
    int width = 0, height = 0, step = 0, cn = 0;
    cv::Mat copyMat;
 
    //#publish Video
    if (m_publishVideoRet) {
        if (videoPublishElement == nullptr) {
            string path = appConfig.getStringProperty("srsAddr") + "cam" + m_camId + ".flv";
            cv::Size size_(appConfig.getIntProperty("pulish.width"), appConfig.getIntProperty("pulish.height"));
            int gupIdx = appPref.getIntData("gpu.index");
            videoPublishElement = new ffmpeg::PipeVideoPublishElement(path, size_, "flv", 25, gupIdx);
            videoPublishElement->start();
        } else {
//            DBG("videoPublishElement->setImage()");
            m_capture->retrieveFrame(0, &data, &step, &width, &height, &cn);
            cv::Mat img(height, width, CV_8UC3, data, step);
            img.copyTo(copyMat);
 
            if (!copyMat.empty()) {
                videoPublishElement->setImage(copyMat);
                videoPublishElement->submit();
            } else {
                DBG("copyMat.empty()");
            }
        }
    } else {
        if (videoPublishElement != nullptr) {
            DBG("videoPublishElement->stop()");
            videoPublishElement->stop();
            videoPublishElement->wait();
            delete videoPublishElement;
            videoPublishElement = nullptr;
        }
    }
 
    //几张选一张放入Redis
    m_picCount++;
    if (m_picCount % m_nPicsPickOne != 0) {
        return;
    } else {
        m_picCount.store(0);
    }
 
    if (copyMat.empty()) {
//        ERR("copyMat.empty()");
        m_capture->retrieveFrame(0, &data, &step, &width, &height, &cn);
        cv::Mat img(height, width, CV_8UC3, data, step);
        img.copyTo(copyMat);
    }
    std::string imageName = m_capture->GetImageName();
    m_pManager->SaveImageToRedis(m_camId, imageName, copyMat);
 
    fireConnectors();
}
 
std::string RtspCaptureElement::MakeDir(const std::string &timeStamp) {
    std::string t_FilePath = m_cutPath;
 
    if (t_FilePath.back() != '/') {
        t_FilePath.push_back('/');
    }
    char buf[24];
    QDateTime dt = QDateTime::fromString(QString::fromStdString(timeStamp), "yyyy-MM-dd hh:mm:ss:zzz");
 
    std::string t_strTime = dt.toString("yyyyMMddhh").toStdString();
    // DBG("t_strTime="<<t_strTime);
    t_FilePath.append(m_camId + "/" + t_strTime.substr(0, 6) + "/" + t_strTime.substr(6, 2) + "/");
    //YYYYMMDDHH
    t_FilePath.append(t_strTime.substr(0, 10) + "/");
    std::string t_cmd = "mkdir -p '";
    t_cmd.append(t_FilePath + "'");
    //#get path mkdir path
    system(t_cmd.c_str());
 
    return t_FilePath;
}
 
void RtspCaptureElement::SaveVideo(const std::string &strImageName) {
    INFO("SaveVideo: " << strImageName);
    std::string strTimeStamp = AppUtil::getTimeUSecString();
    std::string strPath = MakeDir(strTimeStamp);
    m_capture->SaveVideoByImageName(strPath, strImageName);
}
 
 
void RtspCaptureElement::openVideo() {
    if (m_gpuIndex >= 0) {
        setenv("CUDA_VISIBLE_DEVICES", std::to_string(m_gpuIndex).c_str(), 0);
    }
    INFO("Open Video " << m_path << "  GPU_Index: " << m_gpuIndex);
    m_capture->open(m_path.c_str(), m_gpuIndex >= 0);
}
 
void RtspCaptureElement::threadInitial() {
    INFO("MYH DEBUG");
    openVideo();
}
 
void RtspCaptureElement::threadClosing() {
    INFO("MYH DEBUG");
    m_capture->close();
    delete m_capture;
    m_capture = nullptr;
}
 
void RtspCaptureElement::SetVideoMinMaxSeconds(const int minSeconds, const int maxSeconds) {
    m_capture->SetMinMaxVideoSeconds(minSeconds, maxSeconds);
}
 
void RtspCaptureElement::startPublishVideo() {
    m_publishVideoRet = true;
}
 
void RtspCaptureElement::stopPublishVideo() {
    m_publishVideoRet = false;
}