Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
54225dc3e4 | |||
ff66a2e0d6 |
4163
.gitignore
vendored
4163
.gitignore
vendored
File diff suppressed because it is too large
Load Diff
36
ReadMe.md
36
ReadMe.md
|
@ -1,18 +1,50 @@
|
|||
## 版本说明
|
||||
|
||||
| 版本 | 说明 |
|
||||
| --- | --- |
|
||||
| 1.00 | 初始版本 |
|
||||
| 1.01 | 1. 通过RKMPP实现硬解码; <br> 2. 视频以图片的方式按帧存储到本地; |
|
||||
| 1.02 | 1. 删除图片存储到本地的方式; <br> 2. 取流方式由Opencv修改为FFmpeg方式; <br> 3. 解码后的数据直接转为RK_FORMAT_YCbCr_422_SP格式发送给算法; <br> 4. 视频裸流数据存储在内存中,保存30s; <br> 5. 报警图片从报警录像视频中获取; |
|
||||
|
||||
## 编译方法
|
||||
|
||||
#### 下载代码
|
||||
|
||||
```
|
||||
git clone http://teweishi.oicp.net:3001/hehaoyang/IVA.git
|
||||
```
|
||||
|
||||
### 创建软链接
|
||||
#### 修改配置
|
||||
|
||||
* 进入目录
|
||||
|
||||
```
|
||||
cd IVA/app/
|
||||
```
|
||||
|
||||
* 取消 app.pro 文件中以下注释
|
||||
|
||||
```
|
||||
#DEFINES += USE_RABBITMQ
|
||||
#DEFINES += USE_ALGORITHM
|
||||
```
|
||||
|
||||
* 生成 Makefile 文件
|
||||
|
||||
```
|
||||
qmake app.pro
|
||||
```
|
||||
|
||||
#### 创建软链接
|
||||
|
||||
```
|
||||
cd external/npu/
|
||||
ln -s /usr/lib/librknnrt.so librknn_api.so
|
||||
```
|
||||
|
||||
### 编译
|
||||
#### 编译
|
||||
|
||||
```
|
||||
cd ../../
|
||||
make debug -j4
|
||||
```
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "HxDataBase.h"
|
||||
|
||||
#include "HxUtils.h"
|
||||
|
||||
QMutex HxDataBase::mutex;
|
||||
QSqlDatabase HxDataBase::database;
|
||||
QString HxDataBase::device_id;
|
||||
int HxDataBase::recording_prepend_time;
|
||||
QString HxDataBase::ftp_address, HxDataBase::ftp_username, HxDataBase::ftp_password;
|
||||
QString HxDataBase::qamqp_address, HxDataBase::qamqp_username, HxDataBase::qamqp_password;
|
||||
int HxDataBase::algorithm_type;
|
||||
|
@ -14,6 +14,7 @@ QStringList HxDataBase::bsd_video_input_source;
|
|||
QStringList HxDataBase::bsd_warn_regions;
|
||||
EventWarnParamConfig HxDataBase::warm_param_config;
|
||||
CameraCalibration HxDataBase::adas_camera_calibration;
|
||||
QStringList HxDataBase::alarm_protect_timestamp;
|
||||
|
||||
QSqlDatabase HxDataBase::open(QString filepath, QString connectionName)
|
||||
{
|
||||
|
@ -257,6 +258,9 @@ void HxDataBase::initialization()
|
|||
/* 设备编号 */
|
||||
device_id = read_setting("device_id", QString("TVIS"));
|
||||
|
||||
/* 预录时长 Seconds */
|
||||
recording_prepend_time = read_setting("recording_prepend_time", 5);
|
||||
|
||||
/* FTP信息 */
|
||||
ftp_address = read_setting("ftp_address", QString("192.168.10.10:7616"));
|
||||
ftp_username = read_setting("ftp_username", QString("nvruser"));
|
||||
|
@ -295,6 +299,9 @@ void HxDataBase::initialization()
|
|||
|
||||
/* 读取 ADAS 相机内外参 */
|
||||
read_adas_camera_calibration();
|
||||
|
||||
/* 报警保护时长 */
|
||||
alarm_protect_timestamp = read_setting("alarm_protect_timestamp", QString("3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3;3")).split(";");
|
||||
}
|
||||
|
||||
bool HxDataBase::save_setting()
|
||||
|
@ -302,6 +309,7 @@ bool HxDataBase::save_setting()
|
|||
database.transaction();
|
||||
|
||||
write_setting("device_id", device_id);
|
||||
write_setting("recording_prepend_time", QString::number(recording_prepend_time));
|
||||
write_setting("ftp_address", ftp_address);
|
||||
write_setting("ftp_username", ftp_username);
|
||||
write_setting("ftp_password", ftp_password);
|
||||
|
@ -315,6 +323,7 @@ bool HxDataBase::save_setting()
|
|||
write_setting("bsd_warn_regions", bsd_warn_regions.join("*"));
|
||||
write_warm_param_config();
|
||||
write_adas_camera_calibration();
|
||||
write_setting("alarm_protect_timestamp", alarm_protect_timestamp.join(";"));
|
||||
|
||||
return database.commit();
|
||||
}
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
|
||||
#include "MvObjectEventDetect.h"
|
||||
|
||||
#define BSD_MAX_CHANNEL 6
|
||||
#define BSD_MAX_CHANNEL 6
|
||||
|
||||
#define TEMPORARY_LOG_DIRECTORY "log"
|
||||
#define TEMPORARY_VIDEO_DIRECTORY "temp/video"
|
||||
#define TEMPORARY_ALARM_DIRECTORY "temp/alarm"
|
||||
#define TEMPORARY_RECORD_DIRECTORY "record"
|
||||
|
||||
class HxDataBase
|
||||
{
|
||||
|
@ -107,6 +106,9 @@ public:
|
|||
/* 设备编号 */
|
||||
static QString device_id;
|
||||
|
||||
/* 预录时长 Seconds */
|
||||
static int recording_prepend_time;
|
||||
|
||||
/* FTP地址 */
|
||||
static QString ftp_address;
|
||||
|
||||
|
@ -138,6 +140,9 @@ public:
|
|||
|
||||
/* ADAS 相机内外参 */
|
||||
static CameraCalibration adas_camera_calibration;
|
||||
|
||||
/* 报警保护时长 */
|
||||
static QStringList alarm_protect_timestamp;
|
||||
};
|
||||
|
||||
#endif // HXDATABASE_H
|
||||
|
|
|
@ -10,13 +10,13 @@
|
|||
/* 视频设备 */
|
||||
HxVideoDevice adas_video_device, bsd_video_device[6], dsm_video_device;
|
||||
|
||||
HxTaskDispatch* dispatcher = new HxTaskDispatch();
|
||||
HxTaskDispatch *dispatcher = new HxTaskDispatch();
|
||||
|
||||
QMutex upload_file_mutex;
|
||||
QQueue<QString> upload_file_queue;
|
||||
|
||||
#ifdef USE_RABBITMQ
|
||||
HxRabbitMQUtils HxRabbitMQ;
|
||||
HxRabbitMQ rabbit;
|
||||
#endif
|
||||
|
||||
/* 倒车灯;1:亮;0:熄灭 */
|
||||
|
@ -36,25 +36,25 @@ void HxTaskDispatch::initialization(void)
|
|||
/* 算法模块初始化 */
|
||||
#if USE_ALGORITHM
|
||||
/* adas检测配置 */
|
||||
strcpy(dispatcher->event_detect_config.szAdasDetectConfigPathName, "./algmode/adas_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szAdasDetectConfigPathName, "./resources/algmode/adas_detect.bin");
|
||||
/* adas跟踪配置 */
|
||||
strcpy(dispatcher->event_detect_config.szAdasTrackConfigPathName, "./algmode/adas_track.bin");
|
||||
strcpy(dispatcher->event_detect_config.szAdasTrackConfigPathName, "./resources/algmode/adas_track.bin");
|
||||
/* bsd检测配置 */
|
||||
strcpy(dispatcher->event_detect_config.szBsdDetectConfigPathName, "./algmode/bsd_detect.bin");
|
||||
// strcpy(dispatcher->event_detect_config.szRightBsdFrontDetectConfigPathName, "./algmode/bsd_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szBsdDetectConfigPathName, "./resources/algmode/bsd_detect.bin");
|
||||
// strcpy(dispatcher->event_detect_config.szRightBsdFrontDetectConfigPathName, "./resources/algmode/bsd_detect.bin");
|
||||
/* dsm人脸检测配置 */
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceDetectConfigPathName, "./algmode/dsm_face_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceDetectConfigPathName, "./resources/algmode/dsm_face_detect.bin");
|
||||
/* dsm人脸特征点检测配置 */
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceLandMarksDetectConfigPathName, "./algmode/dsm_face_landmarks_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceLandMarksDetectConfigPathName, "./resources/algmode/dsm_face_landmarks_detect.bin");
|
||||
/* dsm人脸认证检测配置 */
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceVerificationDetectConfigPathName, "./algmode/dsm_face_verification_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceVerificationDetectConfigPathName, "./resources/algmode/dsm_face_verification_detect.bin");
|
||||
/* dsm人眼认证检测配置 */
|
||||
strcpy(dispatcher->event_detect_config.szDsmEyeLandMarksDetectConfigPathName, "./algmode/dsm_eye_landmarks_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmEyeLandMarksDetectConfigPathName, "./resources/algmode/dsm_eye_landmarks_detect.bin");
|
||||
/* dsm人脸认证检测配置 */
|
||||
strcpy(dispatcher->event_detect_config.szDsmSmokeConfPathName, "./algmode/dsm_smoke_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmCallConfPathName, "./algmode/dsm_call_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceFeaturePathName, "./algmode/dsm_face_feature.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmHeadPoseConfPathName, "./algmode/data_68kp");
|
||||
strcpy(dispatcher->event_detect_config.szDsmSmokeConfPathName, "./resources/algmode/dsm_smoke_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmCallConfPathName, "./resources/algmode/dsm_call_detect.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmFaceFeaturePathName, "./resources/algmode/dsm_face_feature.bin");
|
||||
strcpy(dispatcher->event_detect_config.szDsmHeadPoseConfPathName, "./resources/algmode/data_68kp");
|
||||
|
||||
/* 输出调试信息 */
|
||||
MvSetPrintf(false);
|
||||
|
@ -73,9 +73,8 @@ void HxTaskDispatch::initialization(void)
|
|||
if (result != 0)
|
||||
HxLog::append("initialization", "set event warn param config failed!!");
|
||||
|
||||
|
||||
/* 相机标定 */
|
||||
if(MvCameraCalibration(&HxDataBase::adas_camera_calibration) != 0)
|
||||
if (MvCameraCalibration(&HxDataBase::adas_camera_calibration) != 0)
|
||||
HxLog::append("initialization", "camera calibration failed!!");
|
||||
#endif
|
||||
|
||||
|
@ -112,121 +111,97 @@ void HxTaskDispatch::initialization(void)
|
|||
dispatcher->start();
|
||||
|
||||
#ifdef USE_RABBITMQ
|
||||
HxRabbitMQ.set(HxDataBase::qamqp_address, HxDataBase::qamqp_username, HxDataBase::qamqp_password);
|
||||
HxRabbitMQ.set_exchanger_name("vehicle.direct.exchange");
|
||||
HxRabbitMQ.set_queue_name("bsd_video_transcode_tag");
|
||||
HxRabbitMQ.set_routing_key("bsd_video_transcode_tag_1");
|
||||
rabbit.set(HxDataBase::qamqp_address, HxDataBase::qamqp_username, HxDataBase::qamqp_password);
|
||||
rabbit.set_exchanger_name("vehicle.direct.exchange");
|
||||
rabbit.set_queue_name("bsd_video_transcode_tag");
|
||||
rabbit.set_routing_key("bsd_video_transcode_tag_1");
|
||||
#endif
|
||||
}
|
||||
|
||||
void HxTaskDispatch::listern(uint16_t port)
|
||||
{
|
||||
dispatcher->debug_tool = new HxSocketUtils(port);
|
||||
dispatcher->debug_tool = new HxSocket(port);
|
||||
|
||||
connect(dispatcher->debug_tool, &HxSocketUtils::data_receive_event, dispatcher, &HxTaskDispatch::data_receive_event);
|
||||
connect(dispatcher, &HxTaskDispatch::data_write_event, dispatcher->debug_tool, &HxSocketUtils::write);
|
||||
connect(dispatcher->debug_tool, &HxSocket::data_receive_event, dispatcher, &HxTaskDispatch::data_receive_event);
|
||||
connect(dispatcher, &HxTaskDispatch::data_write_event, dispatcher->debug_tool, &HxSocket::write);
|
||||
}
|
||||
|
||||
void HxTaskDispatch::connect_to_host(QString address, int port)
|
||||
{
|
||||
dispatcher->platform = new HxSocketUtils(address, port);
|
||||
dispatcher->platform = new HxSocket(address, port);
|
||||
|
||||
connect(dispatcher->platform, &HxSocketUtils::data_receive_event, dispatcher, &HxTaskDispatch::data_receive_event);
|
||||
connect(dispatcher, &HxTaskDispatch::data_write_event, dispatcher->platform, &HxSocketUtils::write);
|
||||
connect(dispatcher->platform, &HxSocket::data_receive_event, dispatcher, &HxTaskDispatch::data_receive_event);
|
||||
connect(dispatcher, &HxTaskDispatch::data_write_event, dispatcher->platform, &HxSocket::write);
|
||||
}
|
||||
|
||||
void HxTaskDispatch::algorithm_alarm_event(QDateTime time, int channel, int level, int event_type, int detect_type, int left, int top, int right, int bottom, int distance, int speed, QString base64_string, QString filepath)
|
||||
void HxTaskDispatch::alarm_upload_event(int algorithm_type, QDateTime timestamp, int channel, int event_type, int danger_level, ObjectPara *object_info, int object_number, CalibrationPoint *face_land_marks, int face_land_marks_number, LaneType left_line_type, LaneType right_line_type)
|
||||
{
|
||||
Q_UNUSED(speed);
|
||||
HxVideoDevice *device = nullptr;
|
||||
switch (algorithm_type)
|
||||
{
|
||||
case ALGORITHM_TYPE_ADAS:
|
||||
device = &adas_video_device;
|
||||
break;
|
||||
case ALGORITHM_TYPE_BSD:
|
||||
device = &bsd_video_device[channel];
|
||||
break;
|
||||
case ALGORITHM_TYPE_DSM:
|
||||
device = &dsm_video_device;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject root({ {"type", 4} });
|
||||
/* 判断报警是否在保护时间内 */
|
||||
if (!device->determine_alarm_detection_timestamp(event_type))
|
||||
return;
|
||||
|
||||
QJsonObject msgInfo({ {"time", time.toString("yyyy-MM-dd HH:mm:ss")},
|
||||
{"channel", channel},
|
||||
{"level", level},
|
||||
{"event_type", event_type},
|
||||
{"detect_type", detect_type},
|
||||
{"left", left},
|
||||
{"top", top},
|
||||
{"right", right},
|
||||
{"bottom", bottom},
|
||||
{"distance", distance},
|
||||
{"speed", dispatcher->car_info.fVelocity},
|
||||
{"image", base64_string},
|
||||
{"filepath", filepath} });
|
||||
/* 生成报警图片+视频 */
|
||||
auto filename = QString("%1_%2_%3_%4_%5").arg(HxDataBase::device_id).arg(algorithm_type, 2, 10, QChar('0')).arg(channel, 2, 10, QChar('0')).arg(timestamp.toString("yyyyMMdd"), timestamp.toString("HHmmss"));
|
||||
|
||||
root.insert("msgInfo", msgInfo);
|
||||
device->create_alarm_data(event_type, filename);
|
||||
|
||||
QJsonObject root({{"type", 4}});
|
||||
|
||||
QJsonObject msg_info_json({{"time", timestamp.toString("yyyy-MM-dd HH:mm:ss")},
|
||||
{"channel", channel},
|
||||
{"level", danger_level},
|
||||
{"event_type", event_type},
|
||||
{"left_line_type", left_line_type},
|
||||
{"right_line_type", right_line_type},
|
||||
{"image_path", QString("/%1/%2/alarm/%3.jpg").arg(QDateTime::currentDateTime().toString("yyyyMMdd"), HxDataBase::device_id, filename)},
|
||||
{"record_path", QString("/%1/%2/alarm/%3.mp4").arg(QDateTime::currentDateTime().toString("yyyyMMdd"), HxDataBase::device_id, filename)}});
|
||||
|
||||
QJsonArray object_info_json;
|
||||
for (int i = 0; i < object_number; i++)
|
||||
{
|
||||
object_info_json.append(QJsonObject({{"detect_type", object_info[i].nDetectType},
|
||||
{"left", object_info[i].nLeft},
|
||||
{"top", object_info[i].nTop},
|
||||
{"right", object_info[i].nRight},
|
||||
{"bottom", object_info[i].nBottom},
|
||||
{"distance", object_info[i].fDist},
|
||||
{"speed", object_info[i].fVelo},
|
||||
{"ttc", object_info[i].fTTC},
|
||||
{"target_post_x", object_info[i].nTargetPosX},
|
||||
{"target_post_y", object_info[i].nTargetPosY}}));
|
||||
}
|
||||
|
||||
QJsonArray face_land_marks_json;
|
||||
for (int i = 0; i < face_land_marks_number; i++)
|
||||
face_land_marks_json.append(QJsonObject({{"x", face_land_marks[i].x}, {"y", face_land_marks[i].y}}));
|
||||
|
||||
msg_info_json.insert("object_info", object_info_json);
|
||||
msg_info_json.insert("face_land_marks", face_land_marks_json);
|
||||
|
||||
root.insert("msgInfo", msg_info_json);
|
||||
|
||||
emit dispatcher->data_write_event(QJsonDocument(root).toJson(QJsonDocument::Compact));
|
||||
|
||||
HxLog::append("algorithm", QString("alarm type=0x%1, filepath=%2").arg(QString::number(event_type, 16), filepath));
|
||||
|
||||
// dispatcher->send_can_data(channel, pObjectTrackEventResult->nDangerLevel, pObjectTrackEventResult->objInfo[i].nDetectType);
|
||||
HxLog::append("algorithm", QString("alarm type=0x%1, filepath=%2").arg(QString::number(event_type, 16), filename));
|
||||
}
|
||||
|
||||
CarInfoInput* HxTaskDispatch::get_car_info(void) { return &dispatcher->car_info; }
|
||||
|
||||
QString HxTaskDispatch::get_video_frame_data(int type, int channel, int frame_id)
|
||||
{
|
||||
Q_UNUSED(channel);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return adas_video_device.build_image(frame_id);
|
||||
case 1:
|
||||
return bsd_video_device[channel].build_image(frame_id);
|
||||
case 2:
|
||||
return dsm_video_device.build_image(frame_id);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool HxTaskDispatch::get_alarm_detection_timestamp(int type, int channel)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return adas_video_device.get_alarm_detection_timestamp();
|
||||
case 1:
|
||||
return bsd_video_device[channel].get_alarm_detection_timestamp();
|
||||
case 2:
|
||||
return dsm_video_device.get_alarm_detection_timestamp();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString HxTaskDispatch::build_alarm_image(int type, int channel, int frame_id)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return adas_video_device.build_image(frame_id);
|
||||
case 1:
|
||||
return bsd_video_device[channel].build_image(frame_id);
|
||||
case 2:
|
||||
return dsm_video_device.build_image(frame_id);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
QString HxTaskDispatch::build_alarm_video(int type, int channel, int frame_id)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return adas_video_device.build_video(frame_id);
|
||||
case 1:
|
||||
return bsd_video_device[channel].build_video(frame_id);
|
||||
case 2:
|
||||
return dsm_video_device.build_video(frame_id);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
CarInfoInput *HxTaskDispatch::get_car_info(void) { return &dispatcher->car_info; }
|
||||
|
||||
void HxTaskDispatch::enqueue_upload_file(QString filename)
|
||||
{
|
||||
|
@ -241,7 +216,7 @@ void HxTaskDispatch::update_heartbeat()
|
|||
{
|
||||
heartbeat_timestamp = QDateTime::currentDateTime();
|
||||
|
||||
emit data_write_event(QJsonDocument(QJsonObject({ {"type", 0} })).toJson(QJsonDocument::Compact));
|
||||
emit data_write_event(QJsonDocument(QJsonObject({{"type", 0}})).toJson(QJsonDocument::Compact));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,7 +347,7 @@ void HxTaskDispatch::parsing_vehiclue_status(void)
|
|||
|
||||
#if USE_ALGORITHM
|
||||
MvSetDetectChannel(detect_channel);
|
||||
#endif
|
||||
#endif
|
||||
HxLog::append("algorithm", QString("starting detect channel=0x%1").arg(QString::number(detect_channel, 16)));
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +355,7 @@ void HxTaskDispatch::parsing_vehiclue_status(void)
|
|||
|
||||
void HxTaskDispatch::recording_upload_task(void)
|
||||
{
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
msleep(1000);
|
||||
|
||||
|
@ -390,11 +365,11 @@ void HxTaskDispatch::recording_upload_task(void)
|
|||
auto filename = upload_file_queue.dequeue();
|
||||
upload_file_mutex.unlock();
|
||||
|
||||
QString fullpath = QString("%1/%2").arg(TEMPORARY_ALARM_DIRECTORY).arg(filename);
|
||||
QString fullpath = QString("%1/%2").arg(TEMPORARY_RECORD_DIRECTORY, filename);
|
||||
|
||||
if(!QFile::exists(fullpath))
|
||||
if (!QFile::exists(fullpath))
|
||||
{
|
||||
HxLog::append("recording upload task", QString("file=%1 not exists, upload failed").arg(filename));
|
||||
HxLog::append("recording upload task", QString("file=%1 not exists, upload failed").arg(fullpath));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -405,19 +380,18 @@ void HxTaskDispatch::recording_upload_task(void)
|
|||
{
|
||||
msleep(100);
|
||||
|
||||
/* FTP 上传 */
|
||||
HxProcess::execute(QString("curl -u %1:%2 ftp://%3/%4/ --ftp-create-dirs -T %5").arg(HxDataBase::ftp_username, HxDataBase::ftp_password, HxDataBase::ftp_address, path, fullpath));
|
||||
/* 上传 */
|
||||
HxProcess::start(QString("curl -u %1:%2 ftp://%3/%4/ --ftp-create-dirs -T %5").arg(HxDataBase::ftp_username, HxDataBase::ftp_password, HxDataBase::ftp_address, path, fullpath));
|
||||
|
||||
QString command = QString("curl -u %1:%2 --ftp-ssl --head ftp://%3/%4/%5").arg(HxDataBase::ftp_username, HxDataBase::ftp_password, HxDataBase::ftp_address, path, filename);
|
||||
|
||||
/* 判断FTP文件是否存在 */
|
||||
auto res = HxProcess::start(command);
|
||||
/* 判断文件是否存在 */
|
||||
auto res = HxProcess::start(QString("curl -u %1:%2 --ftp-ssl --head ftp://%3/%4/%5").arg(HxDataBase::ftp_username, HxDataBase::ftp_password, HxDataBase::ftp_address, path, filename));
|
||||
|
||||
QRegExp rx("Content-Length:\\s\\d{1,9}");
|
||||
|
||||
if (rx.indexIn(res, 0) == -1)
|
||||
continue;
|
||||
|
||||
/* 比较大小 */
|
||||
QFileInfo info(fullpath);
|
||||
|
||||
auto size1 = info.size();
|
||||
|
@ -427,10 +401,10 @@ void HxTaskDispatch::recording_upload_task(void)
|
|||
{
|
||||
HxLog::append("recording upload task", QString("%1 upload finish").arg(filename));
|
||||
|
||||
if(info.suffix() == "mp4")
|
||||
if (info.suffix() == "mp4")
|
||||
{
|
||||
#ifdef USE_RABBITMQ
|
||||
emit HxRabbitMQ.publish(QString("{\"ftproot\": \"%1\", \"complate\": true}").arg(("/"+path+"/"+filename)));
|
||||
emit rabbit.publish(QString("{\"ftproot\": \"%1\", \"complate\": true}").arg(("/" + path + "/" + filename)));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -452,6 +426,7 @@ void HxTaskDispatch::run()
|
|||
|
||||
while (true)
|
||||
{
|
||||
/* 事件循环用于响应信号 */
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
/* 发送心跳数据 */
|
||||
|
@ -460,6 +435,7 @@ void HxTaskDispatch::run()
|
|||
/* 分析车辆行驶状态 */
|
||||
parsing_vehiclue_status();
|
||||
|
||||
/* 延时1s */
|
||||
QThread::msleep(1000);
|
||||
}
|
||||
}
|
||||
|
@ -490,7 +466,8 @@ void HxTaskDispatch::get_warn_param_config(int type)
|
|||
start_event_warn_kind.append(HxDataBase::warm_param_config.bStartEventWarnKind[i]);
|
||||
abnormal_warn_frame_count.append(HxDataBase::warm_param_config.nAbnormalWarnFrameCount[i] / 25);
|
||||
normal_frame_count.append(HxDataBase::warm_param_config.nNormalFrameCount[i] / 25);
|
||||
abnormal_warn_interval_frame_count.append(HxDataBase::warm_param_config.nAbnormalWarnIntervalFrameCount[i] / 25);
|
||||
// abnormal_warn_interval_frame_count.append(HxDataBase::warm_param_config.nAbnormalWarnIntervalFrameCount[i] / 25);
|
||||
abnormal_warn_interval_frame_count.append(HxDataBase::alarm_protect_timestamp.at(i).toInt());
|
||||
abnormal_warn_score_threshold.append((int)(HxDataBase::warm_param_config.fAbnormalWarnScoreThreshold[i] * ((i >= 17 && i <= 20) ? 1 : 100)));
|
||||
normal_warn_score_threshold.append((int)(HxDataBase::warm_param_config.fNormalWarnScoreThreshold[i] * ((i >= 17 && i <= 20) ? 1 : 100)));
|
||||
|
||||
|
@ -502,7 +479,7 @@ void HxTaskDispatch::get_warn_param_config(int type)
|
|||
<< "fNormalWarnScoreThreshold=" << HxDataBase::warm_param_config.fNormalWarnScoreThreshold[i];
|
||||
}
|
||||
|
||||
debug_tool_response_event(type, { {"start_event_warn_kind", start_event_warn_kind},
|
||||
debug_tool_response_event(type, {{"start_event_warn_kind", start_event_warn_kind},
|
||||
{"abnormal_warn_frame_count", abnormal_warn_frame_count},
|
||||
{"normal_frame_count", normal_frame_count},
|
||||
{"abnormal_warn_interval_frame_count", abnormal_warn_interval_frame_count},
|
||||
|
@ -519,7 +496,7 @@ void HxTaskDispatch::get_warn_param_config(int type)
|
|||
{"bsd_second_vel", HxDataBase::warm_param_config.fBsdSecondVel},
|
||||
{"bsd_third_vel", HxDataBase::warm_param_config.fBsdThirdVel},
|
||||
{"ldw_distance", HxDataBase::warm_param_config.nLdwDistance},
|
||||
{"dsm_vel", HxDataBase::warm_param_config.fDsmVel} });
|
||||
{"dsm_vel", HxDataBase::warm_param_config.fDsmVel}});
|
||||
}
|
||||
|
||||
void HxTaskDispatch::set_warn_param_config(int type, QJsonObject object)
|
||||
|
@ -539,6 +516,9 @@ void HxTaskDispatch::set_warn_param_config(int type, QJsonObject object)
|
|||
HxDataBase::warm_param_config.nAbnormalWarnIntervalFrameCount[i] = abnormal_warn_interval_frame_count.at(i).toInt() * 25;
|
||||
HxDataBase::warm_param_config.fAbnormalWarnScoreThreshold[i] = abnormal_warn_score_threshold.at(i).toDouble() / ((i >= 17 && i <= 20) ? 1 : 100);
|
||||
HxDataBase::warm_param_config.fNormalWarnScoreThreshold[i] = normal_warn_score_threshold.at(i).toDouble() / ((i >= 17 && i <= 20) ? 1 : 100);
|
||||
|
||||
/* 设置报警保护时长 */
|
||||
HxDataBase::alarm_protect_timestamp[i] = QString::number(abnormal_warn_interval_frame_count.at(i).toInt());
|
||||
}
|
||||
|
||||
HxDataBase::warm_param_config.nHmwTime = object.value("hmw_time").toInt();
|
||||
|
@ -555,24 +535,24 @@ void HxTaskDispatch::set_warn_param_config(int type, QJsonObject object)
|
|||
HxDataBase::warm_param_config.fDsmVel = object.value("dsm_vel").toDouble();
|
||||
|
||||
#if USE_ALGORITHM
|
||||
if(MvSetEventWarnParamConfig(&HxDataBase::warm_param_config) != 0)
|
||||
if (MvSetEventWarnParamConfig(&HxDataBase::warm_param_config) != 0)
|
||||
{
|
||||
debug_tool_response_event(type, { {"status", false} });
|
||||
debug_tool_response_event(type, {{"status", false}});
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
}
|
||||
|
||||
void HxTaskDispatch::get_adas_camera_calibration(int type)
|
||||
{
|
||||
#if USE_ALGORITHM
|
||||
if(MvGetCameraCalibrationInfo(&HxDataBase::adas_camera_calibration) != 0)
|
||||
if (MvGetCameraCalibrationInfo(&HxDataBase::adas_camera_calibration) != 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
debug_tool_response_event(type, { {"car_len", HxDataBase::adas_camera_calibration.fCarLen},
|
||||
debug_tool_response_event(type, {{"car_len", HxDataBase::adas_camera_calibration.fCarLen},
|
||||
{"car_width", HxDataBase::adas_camera_calibration.fCarWidth},
|
||||
{"ref_center", HxDataBase::adas_camera_calibration.fRefCenter},
|
||||
{"ref_top", HxDataBase::adas_camera_calibration.fRefTop},
|
||||
|
@ -581,7 +561,7 @@ void HxTaskDispatch::get_adas_camera_calibration(int type)
|
|||
{"camera_focus", HxDataBase::adas_camera_calibration.fCameraFocus},
|
||||
{"camera_dx", HxDataBase::adas_camera_calibration.fCameraDx},
|
||||
{"pitch", HxDataBase::adas_camera_calibration.fPitch},
|
||||
{"yaw", HxDataBase::adas_camera_calibration.fYaw} });
|
||||
{"yaw", HxDataBase::adas_camera_calibration.fYaw}});
|
||||
}
|
||||
void HxTaskDispatch::set_adas_camera_calibration(int type, QJsonObject object)
|
||||
{
|
||||
|
@ -597,14 +577,14 @@ void HxTaskDispatch::set_adas_camera_calibration(int type, QJsonObject object)
|
|||
HxDataBase::adas_camera_calibration.fYaw = object.value("yaw").toDouble();
|
||||
|
||||
#if USE_ALGORITHM
|
||||
if(MvCameraCalibration(&HxDataBase::adas_camera_calibration) != 0)
|
||||
if (MvCameraCalibration(&HxDataBase::adas_camera_calibration) != 0)
|
||||
{
|
||||
debug_tool_response_event(type, { {"status", false} });
|
||||
debug_tool_response_event(type, {{"status", false}});
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
}
|
||||
|
||||
void HxTaskDispatch::data_receive_event(QByteArray data)
|
||||
|
@ -635,93 +615,80 @@ void HxTaskDispatch::data_receive_event(QByteArray data)
|
|||
case 5:
|
||||
HxProcess::start(QString("date -s %1").arg(msginfo.value("date").toString()));
|
||||
HxProcess::start(QString("date -s %1").arg(msginfo.value("time").toString()));
|
||||
debug_tool_response_event(type, { {"status", true} });
|
||||
debug_tool_response_event(type, {{"status", true}});
|
||||
|
||||
HxLog::append("timing", QString(QJsonDocument(msginfo).toJson(QJsonDocument::Compact)));
|
||||
break;
|
||||
|
||||
/* 重启 */
|
||||
case 200:
|
||||
debug_tool_response_event(type, { {"status", true} });
|
||||
debug_tool_response_event(type, {{"status", true}});
|
||||
HxProcess::start("systemctl restart app.service");
|
||||
break;
|
||||
|
||||
/* 获取算法类型 */
|
||||
case 240:
|
||||
debug_tool_response_event(type, { {"mode", HxDataBase::algorithm_type} });
|
||||
debug_tool_response_event(type, {{"mode", HxDataBase::algorithm_type}});
|
||||
break;
|
||||
|
||||
/* 设置算法类型 */
|
||||
case 241:
|
||||
HxDataBase::algorithm_type = msginfo.value("mode").toInt();
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
/* 获取ADAS视频输入源 */
|
||||
case 242:
|
||||
debug_tool_response_event(type, { {"source", HxDataBase::adas_video_input_source} });
|
||||
debug_tool_response_event(type, {{"source", HxDataBase::adas_video_input_source}});
|
||||
break;
|
||||
|
||||
/* 设置ADAS视频输入源 */
|
||||
case 243:
|
||||
HxDataBase::adas_video_input_source = msginfo.value("source").toString();
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
break;
|
||||
|
||||
/* 抓拍 */
|
||||
case 244:
|
||||
debug_tool_response_event(type, { {"data", adas_video_device.snap()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
/* 获取BSD视频输入源 */
|
||||
case 245:
|
||||
debug_tool_response_event(type, { {"source", HxDataBase::bsd_video_input_source[msginfo.value("channel").toInt()]} });
|
||||
debug_tool_response_event(type, {{"source", HxDataBase::bsd_video_input_source[msginfo.value("channel").toInt()]}});
|
||||
break;
|
||||
|
||||
/* 设置BSD视频输入源 */
|
||||
case 246:
|
||||
HxDataBase::bsd_video_input_source[msginfo.value("channel").toInt()] = msginfo.value("source").toString();
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
break;
|
||||
|
||||
/* 抓拍 */
|
||||
case 247:
|
||||
debug_tool_response_event(type, { {"data", bsd_video_device[msginfo.value("channel").toInt()].snap()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
/* 获取Dsm视频输入源 */
|
||||
case 248:
|
||||
debug_tool_response_event(type, { {"source", HxDataBase::dsm_video_input_source} });
|
||||
debug_tool_response_event(type, {{"source", HxDataBase::dsm_video_input_source}});
|
||||
break;
|
||||
|
||||
/* 设置Dsm视频输入源 */
|
||||
case 249:
|
||||
HxDataBase::dsm_video_input_source = msginfo.value("source").toString();
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
break;
|
||||
|
||||
/* 抓拍 */
|
||||
case 250:
|
||||
debug_tool_response_event(type, { {"data", dsm_video_device.snap()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
/* 获取BSD报警区域 */
|
||||
case 251:
|
||||
debug_tool_response_event(type, { {"data", HxDataBase::bsd_warn_regions[msginfo.value("channel").toInt()]} });
|
||||
debug_tool_response_event(type, {{"data", HxDataBase::bsd_warn_regions[msginfo.value("channel").toInt()]}});
|
||||
break;
|
||||
|
||||
/* 设置BSD报警区域 */
|
||||
case 252:
|
||||
HxDataBase::bsd_warn_regions[msginfo.value("channel").toInt()] = msginfo.value("data").toString();
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
/* 获取设备编号及FTP信息 */
|
||||
case 253:
|
||||
debug_tool_response_event(type, { {"device_id", HxDataBase::device_id},
|
||||
{"ftp_address", HxDataBase::ftp_address},
|
||||
{"ftp_username", HxDataBase::ftp_username},
|
||||
{"ftp_password", HxDataBase::ftp_password}, });
|
||||
debug_tool_response_event(type, {
|
||||
{"device_id", HxDataBase::device_id},
|
||||
{"ftp_address", HxDataBase::ftp_address},
|
||||
{"ftp_username", HxDataBase::ftp_username},
|
||||
{"ftp_password", HxDataBase::ftp_password},
|
||||
});
|
||||
break;
|
||||
|
||||
/* 设置设备编号及FTP信息 */
|
||||
|
@ -730,10 +697,9 @@ void HxTaskDispatch::data_receive_event(QByteArray data)
|
|||
HxDataBase::ftp_address = msginfo.value("ftp_address").toString();
|
||||
HxDataBase::ftp_username = msginfo.value("ftp_username").toString();
|
||||
HxDataBase::ftp_password = msginfo.value("ftp_password").toString();
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
|
||||
case 255:
|
||||
get_warn_param_config(type);
|
||||
break;
|
||||
|
@ -752,9 +718,9 @@ void HxTaskDispatch::data_receive_event(QByteArray data)
|
|||
|
||||
/* 获取 RabbitMQ 信息 */
|
||||
case 259:
|
||||
debug_tool_response_event(type, { {"qamqp_address", HxDataBase::qamqp_address},
|
||||
debug_tool_response_event(type, {{"qamqp_address", HxDataBase::qamqp_address},
|
||||
{"qamqp_username", HxDataBase::qamqp_username},
|
||||
{"qamqp_password", HxDataBase::qamqp_password} });
|
||||
{"qamqp_password", HxDataBase::qamqp_password}});
|
||||
break;
|
||||
|
||||
/* 设置 RabbitMQ 信息 */
|
||||
|
@ -762,11 +728,20 @@ void HxTaskDispatch::data_receive_event(QByteArray data)
|
|||
HxDataBase::qamqp_address = msginfo.value("qamqp_address").toString();
|
||||
HxDataBase::qamqp_username = msginfo.value("qamqp_username").toString();
|
||||
HxDataBase::qamqp_password = msginfo.value("qamqp_password").toString();
|
||||
debug_tool_response_event(type, { {"status", HxDataBase::save_setting()} });
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
case 261:
|
||||
debug_tool_response_event(type, {{"recording_prepend_time", HxDataBase::recording_prepend_time}});
|
||||
break;
|
||||
case 262:
|
||||
HxDataBase::recording_prepend_time = msginfo.value("recording_prepend_time").toInt();
|
||||
debug_tool_response_event(type, {{"status", HxDataBase::save_setting()}});
|
||||
break;
|
||||
|
||||
case 0xFFFF:
|
||||
adas_video_device.test();
|
||||
dsm_video_device.test();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
#include "HxUtils.h"
|
||||
#include "MvObjectEventDetect.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <opencv2/freetype.hpp>
|
||||
|
||||
#define ALGORITHM_TYPE_ADAS 0
|
||||
#define ALGORITHM_TYPE_BSD 1
|
||||
#define ALGORITHM_TYPE_DSM 2
|
||||
|
@ -31,37 +34,27 @@ public:
|
|||
*/
|
||||
static void connect_to_host(QString address, int port);
|
||||
|
||||
static void algorithm_alarm_event(QDateTime time, int channel, int level, int event_type, int detect_type, int left, int top, int right, int bottom, int distance, int speed, QString base64_string, QString filepath);
|
||||
|
||||
static CarInfoInput* get_car_info(void);
|
||||
|
||||
static QString get_video_frame_data(int type, int channel, int frame_id);
|
||||
/**
|
||||
* @brief alarm_upload_event
|
||||
* @param type
|
||||
* @param timestamp
|
||||
* @param channel
|
||||
* @param event_type
|
||||
* @param danger_level
|
||||
* @param object_info
|
||||
* @param object_number
|
||||
* @param face_land_marks
|
||||
* @param face_land_marks_number
|
||||
* @param left_line_type
|
||||
* @param right_line_type
|
||||
*/
|
||||
static void alarm_upload_event(int type, QDateTime timestamp, int channel, int event_type, int danger_level, ObjectPara *object_info, int object_number, CalibrationPoint *face_land_marks, int face_land_marks_number, LaneType left_line_type, LaneType right_line_type);
|
||||
|
||||
/**
|
||||
* @brief 获取报警检测时间
|
||||
* @param type
|
||||
* @param channel
|
||||
* @brief get_car_info
|
||||
* @return
|
||||
*/
|
||||
static bool get_alarm_detection_timestamp(int type, int channel);
|
||||
|
||||
/**
|
||||
* @brief 生成报警图片
|
||||
* @param type 报警类型
|
||||
* @param channel 视频通道
|
||||
* @param frame_id 视频帧编号
|
||||
* @return 返回 图片路径
|
||||
*/
|
||||
static QString build_alarm_image(int type, int channel, int frame_id);
|
||||
|
||||
/**
|
||||
* @brief 生成报警视频
|
||||
* @param type 报警类型
|
||||
* @param channel 视频通道
|
||||
* @param frame_id 视频帧编号
|
||||
* @return 返回 视频路径
|
||||
*/
|
||||
static QString build_alarm_video(int type, int channel, int frame_id);
|
||||
static CarInfoInput* get_car_info(void);
|
||||
|
||||
/**
|
||||
* @brief enqueue_upload_file
|
||||
|
@ -101,10 +94,10 @@ private:
|
|||
QDateTime vehicle_status_update_time;
|
||||
|
||||
/* 边缘云 Socket (客户端) */
|
||||
HxSocketUtils* platform;
|
||||
HxSocket* platform;
|
||||
|
||||
/* DebugTool Socket (服务端) */
|
||||
HxSocketUtils* debug_tool;
|
||||
HxSocket* debug_tool;
|
||||
|
||||
/* 车辆状态信息 */
|
||||
CarInfoInput car_info;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QTcpSocket>
|
||||
#include <QTcpServer>
|
||||
#include <QDateTime>
|
||||
#include <QStorageInfo>
|
||||
#include <QCoreApplication>
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
|
@ -18,42 +19,30 @@
|
|||
#include "qamqpqueue.h"
|
||||
#endif
|
||||
|
||||
|
||||
class HxThread
|
||||
{
|
||||
public:
|
||||
static void sleep(int millisecond)
|
||||
{
|
||||
auto time = QTime::currentTime().addMSecs(millisecond);
|
||||
while( QTime::currentTime() < time )
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief SocketUtils socket 工具类
|
||||
* @brief Socket socket 工具类
|
||||
*/
|
||||
class HxSocketUtils : public QObject
|
||||
class HxSocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HxSocketUtils(quint16 port)
|
||||
HxSocket(quint16 port)
|
||||
{
|
||||
connect(&server, &QTcpServer::newConnection, this, &HxSocketUtils::new_connection);
|
||||
connect(&server, &QTcpServer::newConnection, this, &HxSocket::new_connection);
|
||||
server.listen(QHostAddress::Any, port);
|
||||
}
|
||||
|
||||
HxSocketUtils(QString address, int port)
|
||||
HxSocket(QString address, int port)
|
||||
{
|
||||
is_reconnect = true;
|
||||
|
||||
socket = new QTcpSocket();
|
||||
|
||||
connect(socket, &QTcpSocket::readyRead, this, &HxSocketUtils::ready_read);
|
||||
connect(socket, &QTcpSocket::readyRead, this, &HxSocket::ready_read);
|
||||
|
||||
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::QueuedConnection);
|
||||
|
||||
connect(this, &HxSocketUtils::reconnection_event, this, &HxSocketUtils::reconnection);
|
||||
connect(this, &HxSocket::reconnection_event, this, &HxSocket::reconnection);
|
||||
|
||||
/* 域名解析 */
|
||||
QHostInfo info = QHostInfo::fromName(address);
|
||||
|
@ -76,7 +65,7 @@ public slots:
|
|||
|
||||
socket = server.nextPendingConnection();
|
||||
|
||||
connect(socket, &QTcpSocket::readyRead, this, &HxSocketUtils::ready_read);
|
||||
connect(socket, &QTcpSocket::readyRead, this, &HxSocket::ready_read);
|
||||
|
||||
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::QueuedConnection);
|
||||
}
|
||||
|
@ -120,15 +109,9 @@ public slots:
|
|||
/* 等待连接 */
|
||||
if (!socket->waitForConnected(500))
|
||||
{
|
||||
/* 使用 QThread::msleep 延时,会使 Socket 出现接收不到事件信息 (槽无法响应) */
|
||||
// auto time = QTime::currentTime().addMSecs(10000);
|
||||
// while (QTime::currentTime() < time)
|
||||
// {
|
||||
// QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
// QThread::msleep(100);
|
||||
// }
|
||||
|
||||
HxThread::sleep(10000);
|
||||
auto time = QTime::currentTime().addMSecs(10000);
|
||||
while (QTime::currentTime() < time)
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||||
|
||||
emit reconnection_event();
|
||||
}
|
||||
|
@ -145,15 +128,16 @@ private:
|
|||
class HxDir
|
||||
{
|
||||
public:
|
||||
static bool mkdir(QString name)
|
||||
static bool mkpath(QString name)
|
||||
{
|
||||
return QDir().mkpath(name);
|
||||
}
|
||||
|
||||
static void mkdir(QStringList names)
|
||||
static void mkpath(QStringList names)
|
||||
{
|
||||
foreach (QString name, names) {
|
||||
HxDir::mkdir(name);
|
||||
foreach (QString name, names)
|
||||
{
|
||||
HxDir::mkpath(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,6 +145,17 @@ public:
|
|||
{
|
||||
return QDir(name).removeRecursively();
|
||||
}
|
||||
|
||||
static double free_size(QString rootPath)
|
||||
{
|
||||
foreach (const QStorageInfo &storage, QStorageInfo::mountedVolumes())
|
||||
{
|
||||
if (rootPath == storage.rootPath())
|
||||
return static_cast<double>(storage.bytesAvailable()) / 1024 / 1024 / 1024;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
class HxLog
|
||||
|
@ -194,20 +189,6 @@ public:
|
|||
class HxProcess
|
||||
{
|
||||
public:
|
||||
static int execute(QString command)
|
||||
{
|
||||
qDebug() << command;
|
||||
|
||||
auto array = command.split(" ");
|
||||
|
||||
QString program = array.at(0);
|
||||
QStringList arguments;
|
||||
for (int i = 1; i < array.count(); i++)
|
||||
arguments << array.at(i);
|
||||
|
||||
return QProcess::execute(program, arguments);
|
||||
}
|
||||
|
||||
static QString start(QString command)
|
||||
{
|
||||
auto array = command.split(" ");
|
||||
|
@ -226,7 +207,7 @@ public:
|
|||
};
|
||||
|
||||
#ifdef USE_RABBITMQ
|
||||
class HxRabbitMQUtils : public QObject
|
||||
class HxRabbitMQ : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@ -244,7 +225,7 @@ public:
|
|||
connect(&client, SIGNAL(connected()), this, SLOT(connected()));
|
||||
connect(&client, SIGNAL(disconnected()), this, SLOT(disconnected()));
|
||||
|
||||
connect(this, &HxRabbitMQUtils::publish, this, &HxRabbitMQUtils::send_message);
|
||||
connect(this, &HxRabbitMQ::publish, this, &HxRabbitMQ::send_message);
|
||||
|
||||
client.connectToHost();
|
||||
}
|
||||
|
|
|
@ -36,9 +36,41 @@ class HxVideoDecoder
|
|||
public:
|
||||
HxVideoDecoder(void) {}
|
||||
|
||||
#ifndef USE_ALGORITHM
|
||||
bool initialization(AVFormatContext* ifmt_ctx)
|
||||
static int duration(QString fullpath)
|
||||
{
|
||||
/* 始化网络设备 */
|
||||
avformat_network_init();
|
||||
|
||||
/* 初始化 */
|
||||
AVFormatContext *ifmt_ctx = avformat_alloc_context();
|
||||
|
||||
/* 打开输入文件 */
|
||||
if (avformat_open_input(&ifmt_ctx, fullpath.toUtf8().data(), nullptr, nullptr) < 0)
|
||||
return 0;
|
||||
|
||||
/* 获取流信息 */
|
||||
if (avformat_find_stream_info(ifmt_ctx, nullptr) < 0)
|
||||
{
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 这里获取的是微秒,需要转成秒 */
|
||||
int64_t tduration = ifmt_ctx->duration;
|
||||
|
||||
/* 打开文件流后,需要关闭,否则会一直占用视频文件,无法进行视频文件的后续操作 */
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
|
||||
/* 销毁 */
|
||||
avformat_free_context(ifmt_ctx);
|
||||
|
||||
return tduration / 1000000;
|
||||
}
|
||||
|
||||
#ifndef USE_ALGORITHM
|
||||
void initialization(AVFormatContext *ifmt_ctx)
|
||||
{
|
||||
status = false;
|
||||
auto video_stream_index = -1;
|
||||
for (uint i = 0; i < ifmt_ctx->nb_streams; i++)
|
||||
{
|
||||
|
@ -47,14 +79,14 @@ public:
|
|||
}
|
||||
|
||||
if (video_stream_index == -1)
|
||||
return false;
|
||||
return;
|
||||
|
||||
/* 配置解码器 */
|
||||
video_dec_ctx = avcodec_alloc_context3(nullptr);
|
||||
if (video_dec_ctx == nullptr)
|
||||
{
|
||||
printf("Could not allocate AVCodecContext");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 拷贝 */
|
||||
|
@ -63,14 +95,14 @@ public:
|
|||
/* 查找解码器 */
|
||||
auto codec = avcodec_find_decoder(video_dec_ctx->codec_id);
|
||||
if (!codec)
|
||||
return false;
|
||||
return;
|
||||
|
||||
/* 打开解码器 */
|
||||
if (avcodec_open2(video_dec_ctx, codec, nullptr) < 0)
|
||||
{
|
||||
codec = nullptr;
|
||||
avcodec_free_context(&video_dec_ctx);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
video_dec_frame = av_frame_alloc();
|
||||
|
@ -80,7 +112,7 @@ public:
|
|||
/* 通过指定像素格式、图像宽、图像高来计算所需的内存大小 */
|
||||
auto numBytes = av_image_get_buffer_size(AV_PIX_FMT_BGR24, video_dec_ctx->width, video_dec_ctx->height, 1);
|
||||
/* 创建 video_out_buffer */
|
||||
video_out_buffer = static_cast<uint8_t*>(av_malloc(static_cast<ulong>(numBytes) * sizeof(uint8_t)));
|
||||
video_out_buffer = static_cast<uint8_t *>(av_malloc(static_cast<ulong>(numBytes) * sizeof(uint8_t)));
|
||||
/* 填充数据 */
|
||||
av_image_fill_arrays(video_picture_frame->data, video_picture_frame->linesize, video_out_buffer, AV_PIX_FMT_BGR24, video_dec_ctx->width, video_dec_ctx->height, 1);
|
||||
|
||||
|
@ -102,11 +134,13 @@ public:
|
|||
nullptr /* 特定缩放算法需要的参数(?),默认为NULL */
|
||||
);
|
||||
|
||||
return true;
|
||||
status = true;
|
||||
}
|
||||
#else
|
||||
bool initialization(void)
|
||||
void initialization(void)
|
||||
{
|
||||
status = false;
|
||||
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
RK_U32 need_split = 1;
|
||||
|
@ -119,29 +153,29 @@ public:
|
|||
|
||||
HxLog::append("mpp", QString("mpp_create failed"));
|
||||
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 配置解器 按帧输入码流 */
|
||||
ret = mpp_mpi->control(mpp_ctx, MPP_DEC_SET_PARSER_SPLIT_MODE, (MppParam*)&need_split);
|
||||
ret = mpp_mpi->control(mpp_ctx, MPP_DEC_SET_PARSER_SPLIT_MODE, (MppParam *)&need_split);
|
||||
if (MPP_OK != ret)
|
||||
{
|
||||
release();
|
||||
|
||||
HxLog::append("mpp", QString("mpi->control failed"));
|
||||
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 配置解器 队列输入 */
|
||||
ret = mpp_mpi->control(mpp_ctx, MPP_SET_INPUT_BLOCK, (MppParam*)&need_split);
|
||||
ret = mpp_mpi->control(mpp_ctx, MPP_SET_INPUT_BLOCK, (MppParam *)&need_split);
|
||||
if (MPP_OK != ret)
|
||||
{
|
||||
release();
|
||||
|
||||
HxLog::append("mpp", QString("mpi->control failed"));
|
||||
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 初始化 MPP (固定为H264) */
|
||||
|
@ -152,10 +186,10 @@ public:
|
|||
|
||||
HxLog::append("mpp", QString("mpp_init failed"));
|
||||
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
status = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -191,7 +225,7 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
void decode(AVPacket* packet, cv::Mat* mat)
|
||||
void decode(AVPacket *packet, cv::Mat *mat)
|
||||
{
|
||||
#ifndef USE_ALGORITHM
|
||||
/* 发送数据到ffmepg,放到解码队列中 */
|
||||
|
@ -201,7 +235,7 @@ public:
|
|||
if (avcodec_receive_frame(video_dec_ctx, video_dec_frame) == 0)
|
||||
{
|
||||
/* 开始转换 */
|
||||
sws_scale(video_sws_context, static_cast<const uint8_t* const*>(video_dec_frame->data), video_dec_frame->linesize, 0, video_dec_ctx->height, video_picture_frame->data, video_picture_frame->linesize);
|
||||
sws_scale(video_sws_context, static_cast<const uint8_t *const *>(video_dec_frame->data), video_dec_frame->linesize, 0, video_dec_ctx->height, video_picture_frame->data, video_picture_frame->linesize);
|
||||
|
||||
(*mat) = cv::Mat(cv::Size(video_dec_ctx->width, video_dec_ctx->height), CV_8UC3);
|
||||
(*mat).data = video_out_buffer;
|
||||
|
@ -296,7 +330,7 @@ public:
|
|||
if (err_info)
|
||||
{
|
||||
qDebug("decoder_get_frame get err info:%d discard:%d.",
|
||||
mpp_frame_get_errinfo(mpp_frame), mpp_frame_get_discard(mpp_frame));
|
||||
mpp_frame_get_errinfo(mpp_frame), mpp_frame_get_discard(mpp_frame));
|
||||
}
|
||||
frame_count++;
|
||||
// qDebug("decode_get_frame get frame %d", frame_count);
|
||||
|
@ -305,29 +339,8 @@ public:
|
|||
{
|
||||
RK_U32 width = mpp_frame_get_width(mpp_frame);
|
||||
RK_U32 height = mpp_frame_get_height(mpp_frame);
|
||||
|
||||
MppBuffer mpp_buffer = mpp_frame_get_buffer(mpp_frame);
|
||||
|
||||
convert_to_mat(mpp_buffer, width, height, mat);
|
||||
|
||||
// RK_U32 h_stride = mpp_frame_get_hor_stride(mpp_frame);
|
||||
// RK_U32 v_stride = mpp_frame_get_ver_stride(mpp_frame);
|
||||
|
||||
// cv::Mat yuv_img(height * 3 / 2, width, CV_8UC1);
|
||||
// RK_U8 *base = (RK_U8 *)mpp_buffer_get_ptr(mpp_buffer);
|
||||
// RK_U8 *base_c = base + h_stride * v_stride;
|
||||
// int idx = 0;
|
||||
// for (int i = 0; i < height; i++, base += h_stride, idx += width)
|
||||
// {
|
||||
// memcpy(yuv_img.data + idx, base, width);
|
||||
// }
|
||||
// for (int i = 0; i < height / 2; i++, base_c += h_stride, idx += width)
|
||||
// {
|
||||
// memcpy(yuv_img.data + idx, base_c, width);
|
||||
// }
|
||||
|
||||
// (*mat) = cv::Mat(cv::Size(width, height), CV_8UC3);
|
||||
// cv::cvtColor(yuv_img, (*mat), CV_YUV420sp2RGB);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -405,36 +418,10 @@ private:
|
|||
return MPP_BUFFER_MODE_BUTT;
|
||||
}
|
||||
|
||||
return ((MppBufferGroupImpl*)group)->usage;
|
||||
return ((MppBufferGroupImpl *)group)->usage;
|
||||
}
|
||||
|
||||
int write_image_to_file(void* buf, const char* filename, int sw, int sh, int fmt, int index) {
|
||||
int size;
|
||||
// char filePath[100];
|
||||
// const char* outputFilePath = "%s/out%dw%d-h%d-%s.bin";
|
||||
|
||||
// snprintf(filePath, 100, outputFilePath,
|
||||
// path, index, sw, sh, translate_format_str(fmt));
|
||||
|
||||
FILE* file = fopen(filename, "wb+");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "open %s and write ok\n", filename);
|
||||
}
|
||||
|
||||
size = sw * sh * get_bpp_from_format(fmt);
|
||||
|
||||
fwrite(buf, size, 1, file);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool convert_to_mat(MppBuffer mpp_buffer, RK_U32 width, RK_U32 height, cv::Mat* mat)
|
||||
bool convert_to_mat(MppBuffer mpp_buffer, RK_U32 width, RK_U32 height, cv::Mat *mat)
|
||||
{
|
||||
int ret = 0;
|
||||
im_rect src_rect, dst_rect;
|
||||
|
@ -448,16 +435,18 @@ private:
|
|||
memset(&dst_img, 0, sizeof(dst_img));
|
||||
|
||||
src_img = wrapbuffer_virtualaddr(mpp_buffer_get_ptr(mpp_buffer), width, height, RK_FORMAT_YCbCr_420_SP);
|
||||
dst_img = wrapbuffer_virtualaddr(mat->data, width, height, RK_FORMAT_BGR_888);
|
||||
dst_img = wrapbuffer_virtualaddr(mat->data, width, height, RK_FORMAT_YCbCr_422_SP);
|
||||
|
||||
if (src_img.width == 0 || dst_img.width == 0) {
|
||||
if (src_img.width == 0 || dst_img.width == 0)
|
||||
{
|
||||
printf("%s, %s\n", __FUNCTION__, imStrError());
|
||||
return -1;
|
||||
}
|
||||
src_img.format = RK_FORMAT_YCbCr_420_SP;
|
||||
dst_img.format = RK_FORMAT_BGR_888;
|
||||
dst_img.format = RK_FORMAT_YCbCr_422_SP;
|
||||
ret = imcheck(src_img, dst_img, src_rect, dst_rect);
|
||||
if (IM_STATUS_NOERROR != ret) {
|
||||
if (IM_STATUS_NOERROR != ret)
|
||||
{
|
||||
printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
|
||||
return -1;
|
||||
}
|
||||
|
@ -468,21 +457,24 @@ private:
|
|||
}
|
||||
|
||||
#endif
|
||||
public:
|
||||
bool status = false;
|
||||
|
||||
private:
|
||||
#if USE_ALGORITHM
|
||||
MppCtx mpp_ctx;
|
||||
MppApi* mpp_mpi;
|
||||
MppApi *mpp_mpi;
|
||||
size_t max_usage;
|
||||
RK_U32 frame_count = 0, frame_num, eos;
|
||||
|
||||
/* 缓冲区管理器 */
|
||||
MppBufferGroup mpp_frame_group;
|
||||
#else
|
||||
uint8_t* video_out_buffer = nullptr;
|
||||
struct SwsContext* video_sws_context = nullptr;
|
||||
uint8_t *video_out_buffer = nullptr;
|
||||
struct SwsContext *video_sws_context = nullptr;
|
||||
|
||||
AVCodecContext* video_dec_ctx = nullptr;
|
||||
AVFrame* video_dec_frame = nullptr, * video_picture_frame = nullptr;
|
||||
AVCodecContext *video_dec_ctx = nullptr;
|
||||
AVFrame *video_dec_frame = nullptr, *video_picture_frame = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -1,58 +1,32 @@
|
|||
#include "HxVideoDevice.h"
|
||||
#include "HxDataBase.h"
|
||||
#include "HxUtils.h"
|
||||
|
||||
/* bsd算法结果处理函数 */
|
||||
void algorithm_alarm_callback(int nDataChannel, ObjectTrackEventResult* pObjectTrackEventResult, void* pPrivData)
|
||||
/* 算法报警处理函数 */
|
||||
void algorithm_detection_callback(int nDataChannel, ObjectTrackEventResult *pObjectTrackEventResult, void *pPrivData)
|
||||
{
|
||||
Q_UNUSED(nDataChannel);
|
||||
Q_UNUSED(pPrivData);
|
||||
|
||||
int algorithm_type = 0, channel = 0;
|
||||
QDateTime current_time = QDateTime::currentDateTime();
|
||||
|
||||
if (pObjectTrackEventResult->nEventType == 0)
|
||||
return;
|
||||
|
||||
if (nDataChannel == 0) /* ADAS */
|
||||
if (nDataChannel == 0)
|
||||
{
|
||||
if (!HxTaskDispatch::get_alarm_detection_timestamp(ALGORITHM_TYPE_ADAS, 0))
|
||||
return;
|
||||
|
||||
qDebug() << current_time.toString("[yyyy-MM-dd HH:mm:ss] ") << " Adas FrameId=" << pObjectTrackEventResult->nFrameId << " nEventType=" << pObjectTrackEventResult->nEventType;
|
||||
|
||||
|
||||
/* 生成报警图片 */
|
||||
auto image_path = HxTaskDispatch::build_alarm_image(ALGORITHM_TYPE_ADAS, 0, pObjectTrackEventResult->nFrameId);
|
||||
|
||||
/* 生成报警视频 */
|
||||
auto record_path = HxTaskDispatch::build_alarm_video(ALGORITHM_TYPE_ADAS, 0, pObjectTrackEventResult->nFrameId);
|
||||
|
||||
/* 上传 */
|
||||
HxTaskDispatch::algorithm_alarm_event(current_time, 0, 0, pObjectTrackEventResult->nEventType, 0, 0, 0, 0, 0, 0, 0, image_path, record_path);
|
||||
algorithm_type = ALGORITHM_TYPE_ADAS;
|
||||
}
|
||||
else if (nDataChannel == 2) /* DSM */
|
||||
else if (nDataChannel == 2)
|
||||
{
|
||||
if (!HxTaskDispatch::get_alarm_detection_timestamp(ALGORITHM_TYPE_DSM, 0))
|
||||
return;
|
||||
|
||||
qDebug() << current_time.toString("[yyyy-MM-dd HH:mm:ss] ") << " Dsm FrameId=" << pObjectTrackEventResult->nFrameId << " nEventType=" << pObjectTrackEventResult->nEventType;
|
||||
|
||||
/* 生成报警图片 */
|
||||
auto image_path = HxTaskDispatch::build_alarm_image(ALGORITHM_TYPE_DSM, 0, pObjectTrackEventResult->nFrameId);
|
||||
|
||||
/* 生成报警视频 */
|
||||
auto record_path = HxTaskDispatch::build_alarm_video(ALGORITHM_TYPE_DSM, 0, pObjectTrackEventResult->nFrameId);
|
||||
|
||||
/* 上传 */
|
||||
HxTaskDispatch::algorithm_alarm_event(current_time, 1, 0, pObjectTrackEventResult->nEventType, 0, 0, 0, 0, 0, 0, 0, image_path, record_path);
|
||||
algorithm_type = ALGORITHM_TYPE_DSM;
|
||||
}
|
||||
else if (nDataChannel == 1 || /* BSD-右前 */
|
||||
nDataChannel == 3 || /* BSD-右后 */
|
||||
nDataChannel == 4 || /* BSD-左前 */
|
||||
nDataChannel == 5 || /* BSD-左后 */
|
||||
nDataChannel == 6 || /* BSD-前 */
|
||||
nDataChannel == 7) /* BSD-后 */
|
||||
nDataChannel == 3 || /* BSD-右后 */
|
||||
nDataChannel == 4 || /* BSD-左前 */
|
||||
nDataChannel == 5 || /* BSD-左后 */
|
||||
nDataChannel == 6 || /* BSD-前 */
|
||||
nDataChannel == 7) /* BSD-后 */
|
||||
{
|
||||
int channel = 0;
|
||||
algorithm_type = ALGORITHM_TYPE_BSD;
|
||||
|
||||
switch (nDataChannel)
|
||||
{
|
||||
|
@ -75,78 +49,45 @@ void algorithm_alarm_callback(int nDataChannel, ObjectTrackEventResult* pObjectT
|
|||
channel = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!HxTaskDispatch::get_alarm_detection_timestamp(ALGORITHM_TYPE_BSD, channel))
|
||||
return;
|
||||
|
||||
qDebug("ProcessBsdAlgResult nDataChannel=%d,nFrameId=%d,nObjectNumber=%d,nEventType=%x,nDangerLevel=%d\n", nDataChannel, pObjectTrackEventResult->nFrameId, pObjectTrackEventResult->nObjectNumber, pObjectTrackEventResult->nEventType, pObjectTrackEventResult->nDangerLevel);
|
||||
|
||||
for (int i = 0; i < pObjectTrackEventResult->nObjectNumber; i++)
|
||||
{
|
||||
qDebug("pObjectTrackEventResult->objInfo[i].nDetectType=%d\n", pObjectTrackEventResult->objInfo[i].nDetectType);
|
||||
|
||||
qDebug("nLeft=%d,nTop=%d,nRight=%d,nBottom=%d\n", pObjectTrackEventResult->objInfo[i].nLeft, pObjectTrackEventResult->objInfo[i].nTop, pObjectTrackEventResult->objInfo[i].nRight, pObjectTrackEventResult->objInfo[i].nBottom);
|
||||
|
||||
if (pObjectTrackEventResult->objInfo[i].nDetectType == 0)
|
||||
continue;
|
||||
|
||||
/* 生成报警图片 */
|
||||
auto image_path = HxTaskDispatch::build_alarm_image(ALGORITHM_TYPE_BSD, channel, pObjectTrackEventResult->nFrameId);
|
||||
|
||||
/* 生成报警视频 */
|
||||
auto record_path = HxTaskDispatch::build_alarm_video(ALGORITHM_TYPE_BSD, channel, pObjectTrackEventResult->nFrameId);
|
||||
|
||||
/* 上传 */
|
||||
HxTaskDispatch::algorithm_alarm_event(current_time, channel,
|
||||
pObjectTrackEventResult->nDangerLevel,
|
||||
pObjectTrackEventResult->nEventType,
|
||||
pObjectTrackEventResult->objInfo[i].nDetectType,
|
||||
pObjectTrackEventResult->objInfo[i].nLeft,
|
||||
pObjectTrackEventResult->objInfo[i].nTop,
|
||||
pObjectTrackEventResult->objInfo[i].nRight,
|
||||
pObjectTrackEventResult->objInfo[i].nBottom,
|
||||
pObjectTrackEventResult->objInfo[i].fDist,
|
||||
pObjectTrackEventResult->objInfo[i].fVelo,
|
||||
image_path,
|
||||
record_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adas算法车道线结果处理函数
|
||||
void algorithm_lane_line_callback(DrawPointInfo* pPointInfo, void* pPrivData)
|
||||
{
|
||||
Q_UNUSED(pPrivData);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int i = 0; i < EVENT_WARN_NUM; i++)
|
||||
{
|
||||
printf("ProcessAdasAlgLaneLineResult pPointInfo->nPointCounters[i]=%d\n", pPointInfo->nPointCounters[i]);
|
||||
for (unsigned int j = 0; j < pPointInfo->nPointCounters[i]; j++)
|
||||
if ((pObjectTrackEventResult->nEventType >> i & 0x01) == 0x01)
|
||||
{
|
||||
printf("pSrcPointX=%d,pSrcPointY=%d\n", pPointInfo->pSrcPointX[i][j], pPointInfo->pSrcPointY[i][j]);
|
||||
HxTaskDispatch::alarm_upload_event(algorithm_type,
|
||||
current_time,
|
||||
channel,
|
||||
i + 1,
|
||||
pObjectTrackEventResult->nDangerLevel,
|
||||
pObjectTrackEventResult->objInfo,
|
||||
pObjectTrackEventResult->nObjectNumber,
|
||||
pObjectTrackEventResult->tFaceLandMarks,
|
||||
pObjectTrackEventResult->nFaceLandMarksNum,
|
||||
pObjectTrackEventResult->nLeftLineType,
|
||||
pObjectTrackEventResult->nRightLineType);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HxVideoDevice::HxVideoDevice(void)
|
||||
{
|
||||
detect_frame_buffer.u32Width = 1280;
|
||||
detect_frame_buffer.u32Height = 720;
|
||||
MvGetFrameBlkInfo(&detect_frame_buffer);
|
||||
m_detect_frame_buffer.u32Width = 1280;
|
||||
m_detect_frame_buffer.u32Height = 720;
|
||||
m_detect_frame_buffer.pu8VirAddr = (unsigned char *)calloc(m_detect_frame_buffer.u32Width * m_detect_frame_buffer.u32Height * 3, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
bgr_frame_buffer.u32Width = 1280;
|
||||
bgr_frame_buffer.u32Height = 720;
|
||||
MvGetFrameBlkInfo(&bgr_frame_buffer);
|
||||
HxVideoDevice::~HxVideoDevice(void)
|
||||
{
|
||||
free(m_detect_frame_buffer.pu8VirAddr);
|
||||
}
|
||||
|
||||
void HxVideoDevice::set(int type, QString address)
|
||||
{
|
||||
this->type = type;
|
||||
this->address = address;
|
||||
m_type = type;
|
||||
m_address = address;
|
||||
#if USE_ALGORITHM
|
||||
auto result = MvSetAlgResultFuncCallback(type, algorithm_alarm_callback, nullptr);
|
||||
auto result = MvSetAlgResultFuncCallback(m_type, algorithm_detection_callback, nullptr);
|
||||
if (result != 0)
|
||||
return;
|
||||
#endif
|
||||
|
@ -158,199 +99,165 @@ void HxVideoDevice::set(int type, QString address, BsdWarnRegion region)
|
|||
{
|
||||
Q_UNUSED(region);
|
||||
|
||||
this->type = type;
|
||||
this->address = address;
|
||||
this->detection_status = false;
|
||||
m_type = type;
|
||||
m_address = address;
|
||||
m_detection_status = false;
|
||||
|
||||
#if USE_ALGORITHM
|
||||
auto result = MvSetAlgResultFuncCallback(type, algorithm_alarm_callback, nullptr);
|
||||
auto result = MvSetAlgResultFuncCallback(m_type, algorithm_detection_callback, nullptr);
|
||||
if (result != 0)
|
||||
return;
|
||||
|
||||
MvSetBsdWarnRegion(type, ®ion);
|
||||
MvSetBsdWarnRegion(m_type, ®ion);
|
||||
#endif
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
void HxVideoDevice::set(bool status) { detection_status = status; }
|
||||
void HxVideoDevice::set(bool status) { m_detection_status = status; }
|
||||
|
||||
bool HxVideoDevice::get_alarm_detection_timestamp(void) { return alarm_detection_timestamp.secsTo(QDateTime::currentDateTime()) > 10; }
|
||||
|
||||
QString HxVideoDevice::snap()
|
||||
bool HxVideoDevice::determine_alarm_detection_timestamp(int event_type)
|
||||
{
|
||||
// QString filename = "";
|
||||
if (!m_alarm_detection_timestamps.contains(event_type))
|
||||
{
|
||||
m_alarm_detection_timestamps.insert(event_type, QDateTime::currentDateTime());
|
||||
return true;
|
||||
}
|
||||
|
||||
// record_frames_mutex.lock();
|
||||
// if (record_frames.size() > 0)
|
||||
// filename = record_frames.last();
|
||||
// record_frames_mutex.unlock();
|
||||
|
||||
// QFile file(filename);
|
||||
|
||||
// if (file.open(QIODevice::ReadOnly))
|
||||
// return file.readAll().toBase64();
|
||||
|
||||
// return "";
|
||||
|
||||
|
||||
Mat mat;
|
||||
|
||||
video_frame_mutex.lock();
|
||||
video_frame.copyTo(mat);
|
||||
video_frame_mutex.unlock();
|
||||
|
||||
return snap(mat);
|
||||
return m_alarm_detection_timestamps[event_type].secsTo(QDateTime::currentDateTime()) > HxDataBase::alarm_protect_timestamp.at(event_type).toInt();
|
||||
}
|
||||
|
||||
QString HxVideoDevice::build_image(int frame_id)
|
||||
void HxVideoDevice::create_alarm_data(int event_type, QString filename)
|
||||
{
|
||||
auto start_id = frame_id - video_fps * 5, end_id = frame_id + video_fps * 5;
|
||||
/* 更新报警检测时间戳 */
|
||||
m_alarm_detection_timestamps[event_type] = QDateTime::currentDateTime();
|
||||
|
||||
alarm_detection_timestamp = QDateTime::currentDateTime();
|
||||
/* 如果创建队列中存在该文件, 则不在重复创建 */
|
||||
if (m_records.contains(filename))
|
||||
return;
|
||||
|
||||
QString filename = QString("%1_%2_%3.jpg").arg(start_id > 0 ? start_id : 0).arg(end_id).arg(QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz"));
|
||||
/* 创建线程 */
|
||||
QtConcurrent::run([=](QDateTime _alarm_timestamp, QString _filename)
|
||||
{
|
||||
Mat mat;
|
||||
int frame_id = 0;
|
||||
VideoCapture capture;
|
||||
HxVideoWriter video_writer;
|
||||
|
||||
record_frames_mutex.lock();
|
||||
if (record_frames.contains(frame_id))
|
||||
QFile::copy(record_frames[frame_id], QString("%1/%2").arg(TEMPORARY_ALARM_DIRECTORY).arg(filename));
|
||||
record_frames_mutex.unlock();
|
||||
/* 添加文件名称, 表示正在创建 */
|
||||
m_records_mutex.lock();
|
||||
m_records.append(filename);
|
||||
m_records_mutex.unlock();
|
||||
|
||||
HxTaskDispatch::enqueue_upload_file(filename);
|
||||
sleep(HxDataBase::recording_prepend_time);
|
||||
|
||||
return QString("/%1/%2/alarm/%3").arg(QDateTime::currentDateTime().toString("yyyyMMdd"), HxDataBase::device_id, filename);
|
||||
}
|
||||
QQueue<HxVideoFrame> frames;
|
||||
|
||||
QString HxVideoDevice::build_video(int frame_id)
|
||||
{
|
||||
auto start_id = frame_id - video_fps * 5, end_id = frame_id + video_fps * 5;
|
||||
m_prerecorded_frames_mutex.lock();
|
||||
for (auto it = m_prerecorded_frames.begin(); it != m_prerecorded_frames.end(); ++it) {
|
||||
if(it->time > _alarm_timestamp.addSecs(-1 * (HxDataBase::recording_prepend_time + 1)) && it->time < _alarm_timestamp.addSecs(HxDataBase::recording_prepend_time + 1))
|
||||
frames.enqueue(it->copy());
|
||||
}
|
||||
m_prerecorded_frames_mutex.unlock();
|
||||
|
||||
QString filename = QString("%1_%2_%3.mp4").arg(start_id > 0 ? start_id : 0).arg(end_id).arg(QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz"));
|
||||
QString image_path = QString("%1/%2.jpg").arg(TEMPORARY_RECORD_DIRECTORY, _filename);
|
||||
QString record_path = QString("%1/%2.avi").arg(TEMPORARY_RECORD_DIRECTORY, _filename);
|
||||
QString _record_path = QString("%1/%2.mp4").arg(TEMPORARY_RECORD_DIRECTORY, _filename);
|
||||
|
||||
record_queue_mutex.lock();
|
||||
record_queue.enqueue(filename);
|
||||
record_queue_mutex.unlock();
|
||||
HxLog::append("recording", QString("%1 frames count=%2").arg(_record_path).arg(frames.count()));
|
||||
|
||||
return QString("/%1/%2/alarm/%3").arg(QDateTime::currentDateTime().toString("yyyyMMdd"), HxDataBase::device_id, filename);
|
||||
while(!frames.isEmpty())
|
||||
{
|
||||
frame_id++;
|
||||
|
||||
auto frame = frames.dequeue();
|
||||
|
||||
/* 如果文件未被打开 */
|
||||
if(!video_writer.open_status)
|
||||
{
|
||||
/* 查找关键帧 */
|
||||
if (frame.packet->flags & AV_PKT_FLAG_KEY)
|
||||
{
|
||||
HxLog::append("recording", QString("%1 find %2 (AV_PKT_FLAG_KEY)").arg(_record_path).arg(frame_id));
|
||||
|
||||
/* 打开(创建)文件 */
|
||||
video_writer.open(frame.ifmt_ctx, record_path);
|
||||
if(!video_writer.open_status)
|
||||
{
|
||||
video_writer.close();
|
||||
|
||||
frame.free();
|
||||
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 在打开的状态, 开始写入帧数据 */
|
||||
if(video_writer.open_status)
|
||||
{
|
||||
video_writer.send(frame.packet);
|
||||
}
|
||||
|
||||
frame.free();
|
||||
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
if(video_writer.open_status)
|
||||
{
|
||||
video_writer.close();
|
||||
|
||||
if(!QFile::exists(record_path))
|
||||
goto END;
|
||||
|
||||
HxLog::append("recording", QString("%1 create success").arg(_record_path));
|
||||
|
||||
capture = VideoCapture(record_path.toUtf8().data());
|
||||
|
||||
if(capture.isOpened())
|
||||
{
|
||||
capture.set(CAP_PROP_POS_FRAMES, static_cast<int>(capture.get(CV_CAP_PROP_FRAME_COUNT)) / 2);
|
||||
|
||||
if(capture.read(mat))
|
||||
{
|
||||
vector <int> compression_params;
|
||||
compression_params.push_back(IMWRITE_JPEG_QUALITY);
|
||||
compression_params.push_back(90);
|
||||
if(imwrite(image_path.toUtf8().data(), mat, compression_params))
|
||||
HxTaskDispatch::enqueue_upload_file(_filename+".jpg");
|
||||
}
|
||||
|
||||
capture.release();
|
||||
}
|
||||
|
||||
QFile::rename(record_path, _record_path);
|
||||
|
||||
HxTaskDispatch::enqueue_upload_file(_filename+".mp4");
|
||||
|
||||
END:
|
||||
while(!frames.isEmpty())
|
||||
frames.dequeue().free();
|
||||
|
||||
/* 删除文件表示, 待验证 */
|
||||
m_records_mutex.lock();
|
||||
m_records.removeAll(_filename);
|
||||
m_records_mutex.unlock();
|
||||
} },
|
||||
m_alarm_detection_timestamps[event_type], filename);
|
||||
}
|
||||
|
||||
void HxVideoDevice::test(void)
|
||||
{
|
||||
ObjectTrackEventResult pObjectTrackEventResult;
|
||||
pObjectTrackEventResult.nFrameId = record_frames.lastKey();
|
||||
pObjectTrackEventResult.nEventType = EVENT_PCW;
|
||||
pObjectTrackEventResult.nFrameId = 0;
|
||||
pObjectTrackEventResult.nEventType = m_type == 0 ? (ObjectEventType)(EVENT_PCW | EVENT_HMW) : EVENT_YAWN;
|
||||
pObjectTrackEventResult.nObjectNumber = 1;
|
||||
pObjectTrackEventResult.objInfo[0].nDetectType = PEDESTRIAN_TYPE;
|
||||
algorithm_alarm_callback(0, &pObjectTrackEventResult, nullptr);
|
||||
algorithm_detection_callback(0, &pObjectTrackEventResult, nullptr);
|
||||
}
|
||||
|
||||
vector<uint8_t> HxVideoDevice::compress(Mat frame, int quality)
|
||||
{
|
||||
vector<uint8_t> buffer;
|
||||
|
||||
vector<int> compress_params;
|
||||
compress_params.push_back(IMWRITE_JPEG_QUALITY);
|
||||
compress_params.push_back(quality);
|
||||
|
||||
imencode(".jpg", frame, buffer, compress_params);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
QString HxVideoDevice::snap(Mat frame) { return frame.data == nullptr ? "" : snap(compress(frame, 50)); }
|
||||
|
||||
QString HxVideoDevice::snap(vector<uint8_t> buffer) { return QString(QByteArray::fromRawData((const char*)buffer.data(), buffer.size()).toBase64()); }
|
||||
|
||||
void HxVideoDevice::recording_creation_task(void)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (record_queue.size() > 0)
|
||||
{
|
||||
record_queue_mutex.lock();
|
||||
auto filename = record_queue.dequeue();
|
||||
record_queue_mutex.unlock();
|
||||
|
||||
HxLog::append("recording", QString("type=%1, count=%2, %3 creation task start").arg(type).arg(record_queue.size()).arg(filename));
|
||||
|
||||
auto data = filename.split("_");
|
||||
auto start_id = data[0].toInt(), end_id = data[1].toInt();
|
||||
|
||||
while (true)
|
||||
{
|
||||
record_frames_mutex.lock();
|
||||
auto first_key = record_frames.firstKey();
|
||||
auto last_key = record_frames.lastKey();
|
||||
record_frames_mutex.unlock();
|
||||
|
||||
if (last_key < first_key)
|
||||
{
|
||||
HxLog::append("recording", QString("%1 not found last id, creation failed").arg(filename));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* 判断最新的视频帧是否超过设定的时间 */
|
||||
if (last_key >= end_id)
|
||||
{
|
||||
record_frames_mutex.lock();
|
||||
auto _record_frames = record_frames;
|
||||
_record_frames.detach();
|
||||
record_frames_mutex.unlock();
|
||||
|
||||
QString fullpath = QString("%1/%2").arg(TEMPORARY_ALARM_DIRECTORY).arg(filename);
|
||||
|
||||
VideoWriter writer(fullpath.toUtf8().data(), CV_FOURCC('m', 'p', '4', 'v'), video_fps, Size(video_width, video_height), true);
|
||||
|
||||
for (int i = start_id; i <= end_id; i++)
|
||||
{
|
||||
if (_record_frames.contains(i))
|
||||
{
|
||||
auto __frame = imread(_record_frames[i].toUtf8().data(), CV_LOAD_IMAGE_COLOR);
|
||||
|
||||
writer.write(__frame);
|
||||
|
||||
HxLog::append("recording", QString("%1 write frame id:%2").arg(filename).arg(i));
|
||||
}
|
||||
}
|
||||
|
||||
writer.release();
|
||||
|
||||
HxTaskDispatch::enqueue_upload_file(filename);
|
||||
|
||||
HxLog::append("recording", QString("%1 creation success").arg(type).arg(filename));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
msleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
msleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
void HxVideoDevice::video_frame_queue_check(void)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
/* 缓存队列超过30s, 删除掉头数据 */
|
||||
record_frames_mutex.lock();
|
||||
while (record_frames.count() > video_fps * 300)
|
||||
{
|
||||
auto filename = record_frames.first();
|
||||
QFile::remove(filename);
|
||||
record_frames.remove(record_frames.firstKey());
|
||||
msleep(1);
|
||||
}
|
||||
record_frames_mutex.unlock();
|
||||
|
||||
msleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void HxVideoDevice::video_frame_read_process()
|
||||
void HxVideoDevice::read_process(void)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
|
@ -358,7 +265,7 @@ void HxVideoDevice::video_frame_read_process()
|
|||
|
||||
int error = 0;
|
||||
|
||||
AVDictionary* avdic = nullptr;
|
||||
AVDictionary *avdic = nullptr;
|
||||
|
||||
/* 减少卡顿或者花屏现象,相当于增加或扩大了缓冲区,给予编码和发送足够的时间 */
|
||||
av_dict_set(&avdic, "buffer_size", "1024000", 0);
|
||||
|
@ -375,7 +282,7 @@ void HxVideoDevice::video_frame_read_process()
|
|||
|
||||
ifmt_ctx = avformat_alloc_context();
|
||||
|
||||
error = avformat_open_input(&ifmt_ctx, address.toUtf8().data(), nullptr, &avdic);
|
||||
error = avformat_open_input(&ifmt_ctx, m_address.toUtf8().data(), nullptr, &avdic);
|
||||
|
||||
av_dict_free(&avdic);
|
||||
|
||||
|
@ -383,7 +290,7 @@ void HxVideoDevice::video_frame_read_process()
|
|||
{
|
||||
avformat_free_context(ifmt_ctx);
|
||||
|
||||
HxLog::append("videolivestream", QString("type=%1, avformat_open_input failed, errorcode=%2").arg(type).arg(error));
|
||||
HxLog::append("videolivestream", QString("type=%1, avformat_open_input failed, errorcode=%2").arg(m_type).arg(error));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -394,48 +301,34 @@ void HxVideoDevice::video_frame_read_process()
|
|||
|
||||
avformat_free_context(ifmt_ctx);
|
||||
|
||||
HxLog::append("videolivestream", QString("type=%1, avformat_find_stream_info failed").arg(type));
|
||||
HxLog::append("videolivestream", QString("type=%1, avformat_find_stream_info failed").arg(m_type));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, address.toUtf8().data(), 0);
|
||||
av_dump_format(ifmt_ctx, 0, m_address.toUtf8().data(), 0);
|
||||
|
||||
video_stream_index = -1;
|
||||
auto m_video_stream_index = -1;
|
||||
for (uint i = 0; i < ifmt_ctx->nb_streams; i++)
|
||||
{
|
||||
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
{
|
||||
video_fps = ifmt_ctx->streams[i]->avg_frame_rate.num;
|
||||
video_width = ifmt_ctx->streams[i]->codecpar->width;
|
||||
video_height = ifmt_ctx->streams[i]->codecpar->height;
|
||||
video_stream_index = static_cast<int>(i);
|
||||
m_video_stream_index = static_cast<int>(i);
|
||||
|
||||
HxLog::append("videolivestream", QString("type=%1, video_fps=%2, video_width=%3, video_height=%4").arg(type).arg(video_fps).arg(video_width).arg(video_height));
|
||||
m_video_fps = ifmt_ctx->streams[i]->avg_frame_rate.num;
|
||||
|
||||
HxLog::append("videolivestream", QString("type=%1, video_fps=%2").arg(m_type).arg(m_video_fps));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (video_stream_index == -1)
|
||||
if (m_video_stream_index == -1)
|
||||
{
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
avformat_free_context(ifmt_ctx);
|
||||
|
||||
HxLog::append("videolivestream", QString("type=%1, not found video stream").arg(type));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool decoder_status = false;
|
||||
#if USE_ALGORITHM
|
||||
decoder_status = decoder.initialization();
|
||||
#else
|
||||
decoder_status = decoder.initialization(ifmt_ctx);
|
||||
#endif
|
||||
if (!decoder_status)
|
||||
{
|
||||
HxLog::append("videolivestream", QString("type=%1, decoder initialization failed").arg(type));
|
||||
HxLog::append("videolivestream", QString("type=%1, not found video stream").arg(m_type));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -447,22 +340,17 @@ void HxVideoDevice::video_frame_read_process()
|
|||
if (av_read_frame(ifmt_ctx, &packet) < 0)
|
||||
break;
|
||||
|
||||
if (packet.stream_index == video_stream_index)
|
||||
{
|
||||
Mat mat;
|
||||
decoder.decode(&packet, &mat);
|
||||
m_decoding_frames_mutex.lock();
|
||||
m_decoding_frames.enqueue(HxVideoFrame(ifmt_ctx, &packet));
|
||||
m_decoding_frames_mutex.unlock();
|
||||
|
||||
if (mat.data != nullptr)
|
||||
{
|
||||
video_frame_mutex.lock();
|
||||
mat.copyTo(video_frame);
|
||||
video_frame_mutex.unlock();
|
||||
}
|
||||
}
|
||||
m_prerecorded_frames_mutex.lock();
|
||||
m_prerecorded_frames.enqueue(HxVideoFrame(ifmt_ctx, &packet));
|
||||
m_prerecorded_frames_mutex.unlock();
|
||||
|
||||
av_packet_unref(&packet);
|
||||
|
||||
msleep(1000 / video_fps);
|
||||
msleep(1000 / m_video_fps);
|
||||
}
|
||||
|
||||
if (ifmt_ctx != nullptr)
|
||||
|
@ -471,137 +359,91 @@ void HxVideoDevice::video_frame_read_process()
|
|||
avformat_free_context(ifmt_ctx);
|
||||
ifmt_ctx = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decoder.release();
|
||||
void HxVideoDevice::decoding_process(void)
|
||||
{
|
||||
Mat mat;
|
||||
int m_frame_id = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
msleep(10);
|
||||
|
||||
if (m_decoding_frames.isEmpty())
|
||||
continue;
|
||||
|
||||
m_decoding_frames_mutex.lock();
|
||||
auto frame = m_decoding_frames.dequeue();
|
||||
m_decoding_frames_mutex.unlock();
|
||||
|
||||
if (!m_video_decoder.status)
|
||||
{
|
||||
#if USE_ALGORITHM
|
||||
m_video_decoder.initialization();
|
||||
#else
|
||||
if (ifmt_ctx != nullptr)
|
||||
m_video_decoder.initialization(ifmt_ctx);
|
||||
#endif
|
||||
if (!m_video_decoder.status)
|
||||
{
|
||||
HxLog::append("videolivestream", QString("type=%1, decoder initialization failed").arg(m_type));
|
||||
|
||||
goto frame_free;
|
||||
}
|
||||
}
|
||||
|
||||
/* 获取YUV数据 */
|
||||
m_video_decoder.decode(frame.packet, &mat);
|
||||
|
||||
if (mat.data != nullptr)
|
||||
{
|
||||
/* 是否开始进行分析 */
|
||||
if (m_detection_status)
|
||||
{
|
||||
/* 获取车速 */
|
||||
auto car_info = HxTaskDispatch::get_car_info();
|
||||
|
||||
if (car_info->fVelocity >= 10)
|
||||
{
|
||||
m_detect_frame_buffer.nFrameId = m_frame_id; // 帧号
|
||||
m_detect_frame_buffer.u64PTS = QDateTime::currentMSecsSinceEpoch(); // 时间戳(毫秒)
|
||||
m_detect_frame_buffer.pu8VirAddr = mat.data;
|
||||
|
||||
#if USE_ALGORITHM
|
||||
MvObjectEventDetect(this->m_type, &m_detect_frame_buffer, car_info);
|
||||
#endif
|
||||
m_frame_id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
frame_free:
|
||||
frame.free();
|
||||
}
|
||||
}
|
||||
|
||||
void HxVideoDevice::run()
|
||||
{
|
||||
/* 启动 录像创建任务 */
|
||||
QtConcurrent::run(this, &HxVideoDevice::recording_creation_task);
|
||||
|
||||
/* 创建 缓存队列监控线程 */
|
||||
QtConcurrent::run(this, &HxVideoDevice::video_frame_queue_check);
|
||||
|
||||
/* 创建 视频读取线程 */
|
||||
QtConcurrent::run(this, &HxVideoDevice::video_frame_read_process);
|
||||
QtConcurrent::run(this, &HxVideoDevice::read_process);
|
||||
|
||||
QDateTime time = QDateTime::currentDateTime();
|
||||
/* 创建 录像 线程 */
|
||||
QtConcurrent::run(this, &HxVideoDevice::decoding_process);
|
||||
|
||||
while (true)
|
||||
{
|
||||
// if(time.secsTo(QDateTime::currentDateTime()) >= (1000/video_fps))
|
||||
/* 判断是否超过预录时长 */
|
||||
if (!m_prerecorded_frames.isEmpty())
|
||||
{
|
||||
time = QDateTime::currentDateTime();
|
||||
|
||||
Mat mat;
|
||||
|
||||
video_frame_mutex.lock();
|
||||
video_frame.copyTo(mat);
|
||||
video_frame_mutex.unlock();
|
||||
|
||||
if (mat.data != nullptr)
|
||||
while (QDateTime::currentDateTime() > m_prerecorded_frames.first().time.addSecs(60))
|
||||
{
|
||||
QString filename = QString("%1/%2_%3_%4.jpg").arg(TEMPORARY_VIDEO_DIRECTORY).arg(QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz")).arg(type).arg(frame_id);
|
||||
|
||||
vector<int> compress_params;
|
||||
compress_params.push_back(IMWRITE_JPEG_QUALITY);
|
||||
compress_params.push_back(90);
|
||||
imwrite(filename.toUtf8().data(), mat, compress_params);
|
||||
|
||||
record_frames_mutex.lock();
|
||||
record_frames.insert(frame_id, filename);
|
||||
record_frames_mutex.unlock();
|
||||
|
||||
if (detection_status)
|
||||
{
|
||||
auto car_info = HxTaskDispatch::get_car_info();
|
||||
|
||||
if (car_info->fVelocity > 10)
|
||||
{
|
||||
bgr_frame_buffer.nFrameId = frame_id; // 帧号
|
||||
bgr_frame_buffer.u64PTS = QDateTime::currentMSecsSinceEpoch(); // 时间戳(毫秒)
|
||||
|
||||
memcpy(bgr_frame_buffer.pu8VirAddr, mat.data, 1280 * 720 * 3);
|
||||
|
||||
MvConvertImage(&bgr_frame_buffer, &detect_frame_buffer); // bgr->nv16
|
||||
#if USE_ALGORITHM
|
||||
MvObjectEventDetect(this->type, &detect_frame_buffer, car_info);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
frame_id++;
|
||||
m_prerecorded_frames_mutex.lock();
|
||||
m_prerecorded_frames.dequeue().free();
|
||||
m_prerecorded_frames_mutex.unlock();
|
||||
}
|
||||
}
|
||||
msleep(15);
|
||||
|
||||
msleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
int HxVideoDevice::MvGetFrameBlkInfo(VideoFrameDataInfo* pImageDataInfo)
|
||||
{
|
||||
Q_UNUSED(pImageDataInfo);
|
||||
|
||||
#if USE_ALGORITHM
|
||||
if (pImageDataInfo == NULL)
|
||||
return -1;
|
||||
|
||||
pImageDataInfo->pu8VirAddr = (unsigned char*)calloc(pImageDataInfo->u32Width * pImageDataInfo->u32Height * 3, sizeof(unsigned char));
|
||||
if (pImageDataInfo->pu8VirAddr == NULL)
|
||||
return -1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HxVideoDevice::MvReleaseFrameBlkInfo(VideoFrameDataInfo* pImageDataInfo)
|
||||
{
|
||||
Q_UNUSED(pImageDataInfo);
|
||||
|
||||
#if USE_ALGORITHM
|
||||
if (pImageDataInfo == NULL)
|
||||
return -1;
|
||||
|
||||
if (pImageDataInfo->pu8VirAddr == NULL)
|
||||
return -1;
|
||||
|
||||
free(pImageDataInfo->pu8VirAddr);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HxVideoDevice::MvConvertImage(VideoFrameDataInfo* pSrcImageDataInfo, VideoFrameDataInfo* pDstImageDataInfo)
|
||||
{
|
||||
Q_UNUSED(pSrcImageDataInfo);
|
||||
Q_UNUSED(pDstImageDataInfo);
|
||||
|
||||
#if USE_ALGORITHM
|
||||
rga_buffer_t src;
|
||||
rga_buffer_t dst;
|
||||
|
||||
src = wrapbuffer_virtualaddr(pSrcImageDataInfo->pu8VirAddr, pSrcImageDataInfo->u32Width, pSrcImageDataInfo->u32Height, RK_FORMAT_BGR_888);
|
||||
dst = wrapbuffer_virtualaddr(pDstImageDataInfo->pu8VirAddr, pDstImageDataInfo->u32Width, pDstImageDataInfo->u32Height, RK_FORMAT_YCbCr_420_SP);
|
||||
|
||||
if (src.width == 0 || dst.width == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
src.format = RK_FORMAT_BGR_888;
|
||||
dst.format = RK_FORMAT_YCbCr_422_SP;
|
||||
|
||||
IM_STATUS STATUS;
|
||||
STATUS = imcvtcolor(src, dst, src.format, dst.format);
|
||||
if (STATUS != IM_STATUS_SUCCESS)
|
||||
{
|
||||
qDebug("imcvtcolor error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pDstImageDataInfo->u64PTS = pSrcImageDataInfo->u64PTS;
|
||||
pDstImageDataInfo->nFrameId = pSrcImageDataInfo->nFrameId;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef HXVIDEODEVICE_H
|
||||
#define HXVIDEODEVICE_H
|
||||
|
||||
|
||||
#include <QtConcurrent>
|
||||
#include <QThread>
|
||||
#include <QDateTime>
|
||||
|
@ -10,12 +9,10 @@
|
|||
|
||||
#include "HxTaskDispatch.h"
|
||||
|
||||
#include "HxDataBase.h"
|
||||
#include "HxVideoWriter.h"
|
||||
#include "HxVideoDecoder.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
//#include "HxMpp.h"
|
||||
|
||||
#if USE_ALGORITHM
|
||||
#include "rga.h"
|
||||
#include "im2d.hpp"
|
||||
|
@ -29,75 +26,143 @@ extern "C"
|
|||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
typedef struct __HxVideoFrame
|
||||
{
|
||||
QDateTime time;
|
||||
|
||||
AVFormatContext *ifmt_ctx;
|
||||
|
||||
AVPacket *packet;
|
||||
|
||||
__HxVideoFrame() {}
|
||||
|
||||
__HxVideoFrame(AVFormatContext *ifmt_ctx, AVPacket *packet)
|
||||
{
|
||||
this->time = QDateTime::currentDateTime();
|
||||
this->ifmt_ctx = ifmt_ctx;
|
||||
this->packet = av_packet_clone(packet);
|
||||
}
|
||||
|
||||
__HxVideoFrame(QDateTime time, AVFormatContext *ifmt_ctx, AVPacket *packet)
|
||||
{
|
||||
this->time = time;
|
||||
this->ifmt_ctx = ifmt_ctx;
|
||||
this->packet = av_packet_clone(packet);
|
||||
}
|
||||
|
||||
__HxVideoFrame copy() { return __HxVideoFrame(this->time, this->ifmt_ctx, this->packet); }
|
||||
|
||||
void free()
|
||||
{
|
||||
ifmt_ctx = nullptr;
|
||||
|
||||
if (packet)
|
||||
{
|
||||
av_packet_unref(packet);
|
||||
av_packet_free(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
} HxVideoFrame;
|
||||
|
||||
class HxVideoDevice : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HxVideoDevice(void);
|
||||
|
||||
~HxVideoDevice(void);
|
||||
|
||||
/**
|
||||
* @brief 设置
|
||||
* @param type 算法通道类型
|
||||
* @param address 摄像头地址
|
||||
*/
|
||||
void set(int type, QString address);
|
||||
|
||||
/**
|
||||
* @brief 设置
|
||||
* @param type 算法通道类型
|
||||
* @param address 摄像头地址
|
||||
* @param region BSD报警区域
|
||||
*/
|
||||
void set(int type, QString address, BsdWarnRegion region);
|
||||
|
||||
/**
|
||||
* @brief 设置算法检测状态
|
||||
* @param status 状态 true: 允许执行; false: 禁止执行
|
||||
*/
|
||||
void set(bool status);
|
||||
bool get_alarm_detection_timestamp(void);
|
||||
QString snap(void);
|
||||
|
||||
QString build_image(int frame_id);
|
||||
QString build_video(int frame_id);
|
||||
/**
|
||||
* @brief 判断报警检测时间
|
||||
* @param event_type 报警类型
|
||||
* @return true: 超过设置阈值; false: 未超过设置阈值
|
||||
*/
|
||||
bool determine_alarm_detection_timestamp(int event_type);
|
||||
|
||||
/**
|
||||
* @brief 创建报警数据(视频与图片)
|
||||
* @param event_type 报警类型
|
||||
* @param filename 文件名称
|
||||
*/
|
||||
void create_alarm_data(int event_type, QString filename);
|
||||
|
||||
/**
|
||||
* @brief 测试
|
||||
*/
|
||||
void test(void);
|
||||
|
||||
private:
|
||||
vector<uint8_t> compress(Mat frame, int quality);
|
||||
QString snap(Mat frame);
|
||||
QString snap(vector<uint8_t> data);
|
||||
void recording_creation_task(void);
|
||||
void video_frame_queue_check(void);
|
||||
/* 读取线程 */
|
||||
void read_process(void);
|
||||
|
||||
void video_frame_read_process(void);
|
||||
void video_decoder_packet(AVPacket packet);
|
||||
/* 解码线程 */
|
||||
void decoding_process(void);
|
||||
|
||||
protected:
|
||||
void run() override;
|
||||
;
|
||||
|
||||
private:
|
||||
int MvGetFrameBlkInfo(VideoFrameDataInfo *pImageDataInfo);
|
||||
int MvReleaseFrameBlkInfo(VideoFrameDataInfo *pImageDataInfo);
|
||||
int MvConvertImage(VideoFrameDataInfo *pSrcImageDataInfo, VideoFrameDataInfo *pDstImageDataInfo);
|
||||
/* 算法通道类型 */
|
||||
int m_type;
|
||||
|
||||
private:
|
||||
int type;
|
||||
int frame_id = 0;
|
||||
QString address = "";
|
||||
QDateTime alarm_detection_timestamp = QDateTime::currentDateTime();
|
||||
bool detection_status = true;
|
||||
/* 视频帧率 */
|
||||
int m_video_fps = 25;
|
||||
|
||||
QMutex record_queue_mutex;
|
||||
QQueue<QString> record_queue;
|
||||
/* 视频地址(RTSP流) */
|
||||
QString m_address = "";
|
||||
|
||||
VideoFrameDataInfo detect_frame_buffer;
|
||||
VideoFrameDataInfo bgr_frame_buffer;
|
||||
/* 报警检测时间 */
|
||||
QMap<int, QDateTime> m_alarm_detection_timestamps;
|
||||
|
||||
// QMutex video_frames_mutex;
|
||||
// QQueue<Mat> video_frames;
|
||||
/* 检测状态(是否送帧给算法的标识) */
|
||||
bool m_detection_status = true;
|
||||
|
||||
QMutex video_frame_mutex;
|
||||
Mat video_frame;
|
||||
/* 正在创建的录像文件 */
|
||||
QMutex m_records_mutex;
|
||||
QList<QString> m_records;
|
||||
|
||||
QMutex record_frames_mutex;
|
||||
QMap<int, QString> record_frames;
|
||||
/* 视频图像帧信息 */
|
||||
VideoFrameDataInfo m_detect_frame_buffer;
|
||||
|
||||
int video_fps = 25;
|
||||
int video_width = 0, video_height = 0;
|
||||
int video_stream_index = 0;
|
||||
bool connect_status;
|
||||
/* FFmpeg */
|
||||
AVFormatContext *ifmt_ctx;
|
||||
|
||||
HxVideoDecoder decoder;
|
||||
/* 解码帧队列及锁 */
|
||||
QMutex m_decoding_frames_mutex;
|
||||
QQueue<HxVideoFrame> m_decoding_frames;
|
||||
|
||||
// uint8_t *video_out_buffer = nullptr;
|
||||
// struct SwsContext *video_sws_context = nullptr;
|
||||
/* 预录帧队列及锁 */
|
||||
QMutex m_prerecorded_frames_mutex;
|
||||
QQueue<HxVideoFrame> m_prerecorded_frames;
|
||||
|
||||
// AVCodecContext *video_dec_ctx = nullptr;
|
||||
// AVFrame *video_dec_frame = nullptr, *video_picture_frame = nullptr;
|
||||
/* 视频打包类 */
|
||||
HxVideoWriter m_video_writer;
|
||||
|
||||
/* 视频解码类 */
|
||||
HxVideoDecoder m_video_decoder;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
239
app/HxVideoWriter.h
Normal file
239
app/HxVideoWriter.h
Normal file
|
@ -0,0 +1,239 @@
|
|||
#ifndef HXVIDEOWRITER_H
|
||||
#define HXVIDEOWRITER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavutil/time.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libswresample/swresample.h"
|
||||
#include <libavutil/audio_fifo.h>
|
||||
}
|
||||
|
||||
class HxVideoWriter
|
||||
{
|
||||
public:
|
||||
HxVideoWriter() : open_status(false) {}
|
||||
|
||||
void open(AVFormatContext *ifmt_ctx, QString filename)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
video_index = -1;
|
||||
audio_index = -1;
|
||||
|
||||
video_frame_index = 0;
|
||||
audio_frame_index = 0;
|
||||
|
||||
ofmt_ctx = nullptr;
|
||||
|
||||
video_dec_stream = nullptr;
|
||||
audio_dec_stream = nullptr;
|
||||
|
||||
/* 查找流中视频与音频位置 */
|
||||
if (ifmt_ctx->nb_streams > 2)
|
||||
{
|
||||
m_error = QObject::tr("数据流异常");
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < ifmt_ctx->nb_streams; i++)
|
||||
{
|
||||
if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
{
|
||||
video_index = static_cast<int>(i);
|
||||
|
||||
video_dec_stream = ifmt_ctx->streams[i];
|
||||
}
|
||||
else if (ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||
{
|
||||
audio_index = static_cast<int>(i);
|
||||
|
||||
audio_dec_stream = ifmt_ctx->streams[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (video_index == -1)
|
||||
{
|
||||
m_error = QObject::tr("未找到视频流");
|
||||
return;
|
||||
}
|
||||
|
||||
avformat_alloc_output_context2(&ofmt_ctx, nullptr, nullptr, filename.toStdString().data());
|
||||
|
||||
if (!ofmt_ctx)
|
||||
{
|
||||
m_error = QObject::tr("无法打开输出文件");
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < ifmt_ctx->nb_streams; i++)
|
||||
{
|
||||
/* 根据输入流创建输出流 */
|
||||
AVCodec *codec = avcodec_find_decoder(ifmt_ctx->streams[i]->codecpar->codec_id);
|
||||
|
||||
AVStream *out_stream = avformat_new_stream(ofmt_ctx, codec);
|
||||
if (!out_stream)
|
||||
{
|
||||
m_error = QObject::tr("无法创建输出流");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 复制AVCodecContext的设置 */
|
||||
AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
|
||||
ret = avcodec_parameters_to_context(codec_ctx, ifmt_ctx->streams[i]->codecpar);
|
||||
if (ret < 0)
|
||||
{
|
||||
m_error = QObject::tr("未能将输入流中的codepar复制到编解码器上下文");
|
||||
avcodec_free_context(&codec_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
codec_ctx->codec_tag = 0;
|
||||
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
ret = avcodec_parameters_from_context(out_stream->codecpar, codec_ctx);
|
||||
if (ret < 0)
|
||||
{
|
||||
m_error = QObject::tr("无法将编解码器上下文复制到输出流codepar上下文");
|
||||
avcodec_free_context(&codec_ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
avcodec_free_context(&codec_ctx);
|
||||
}
|
||||
|
||||
ofmt_ctx->streams[video_index]->time_base = {1, 25};
|
||||
|
||||
av_dump_format(ofmt_ctx, 0, filename.toStdString().data(), 1);
|
||||
|
||||
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
|
||||
{
|
||||
ret = avio_open(&ofmt_ctx->pb, filename.toStdString().data(), AVIO_FLAG_WRITE);
|
||||
if (ret < 0)
|
||||
{
|
||||
m_error = QObject::tr("无法打开输出文件");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ret = avformat_write_header(ofmt_ctx, nullptr);
|
||||
if (ret < 0)
|
||||
{
|
||||
m_error = QObject::tr("无法写入文件头信息");
|
||||
return;
|
||||
}
|
||||
|
||||
open_status = true;
|
||||
}
|
||||
|
||||
void send(AVPacket *packet)
|
||||
{
|
||||
auto out_stream = ofmt_ctx->streams[packet->stream_index];
|
||||
|
||||
if (packet->stream_index == video_index)
|
||||
{
|
||||
auto pts = av_rescale_q_rnd(packet->pts, video_dec_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
|
||||
auto dts = av_rescale_q_rnd(packet->dts, video_dec_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
|
||||
|
||||
if (video_frame_index == 0)
|
||||
{
|
||||
video_pts = pts < 0 ? 0 : pts;
|
||||
video_dts = dts < 0 ? 0 : dts;
|
||||
}
|
||||
else if (video_frame_index == 1)
|
||||
{
|
||||
if (video_pts > pts)
|
||||
video_pts = pts;
|
||||
else
|
||||
video_pts = pts - video_pts;
|
||||
|
||||
if (video_dts > dts)
|
||||
video_dts = dts;
|
||||
else
|
||||
video_dts = dts - video_dts;
|
||||
}
|
||||
|
||||
packet->pts = video_pts * video_frame_index;
|
||||
packet->dts = video_dts * video_frame_index;
|
||||
packet->duration = 0;
|
||||
|
||||
video_frame_index++;
|
||||
}
|
||||
else if (packet->stream_index == audio_index)
|
||||
{
|
||||
auto pts = av_rescale_q_rnd(packet->pts, audio_dec_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
|
||||
auto dts = av_rescale_q_rnd(packet->dts, audio_dec_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
|
||||
|
||||
if (audio_frame_index == 1 && pts > 0)
|
||||
{
|
||||
audio_pts = pts - audio_pts;
|
||||
audio_dts = dts - audio_dts;
|
||||
}
|
||||
else if (audio_frame_index == 0)
|
||||
{
|
||||
audio_pts = pts < 0 ? 0 : pts;
|
||||
audio_dts = dts < 0 ? 0 : dts;
|
||||
}
|
||||
|
||||
packet->pts = audio_pts * audio_frame_index;
|
||||
packet->dts = audio_dts * audio_frame_index;
|
||||
packet->duration = 0;
|
||||
|
||||
audio_frame_index++;
|
||||
}
|
||||
|
||||
auto ret = av_interleaved_write_frame(ofmt_ctx, packet);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
// HxTrace::debug_write_line("VideoWrite", QString("Error muxing packet, ret = %1").arg(ret));
|
||||
|
||||
qDebug() << "Error muxing packet";
|
||||
// 这里是否需要做处理 ???
|
||||
}
|
||||
}
|
||||
|
||||
void close()
|
||||
{
|
||||
// Write file trailer
|
||||
if (open_status)
|
||||
av_write_trailer(ofmt_ctx);
|
||||
|
||||
video_pts = 0;
|
||||
video_dts = 0;
|
||||
audio_pts = 0;
|
||||
audio_dts = 0;
|
||||
|
||||
video_frame_index = 0;
|
||||
audio_frame_index = 0;
|
||||
|
||||
/* close output */
|
||||
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
|
||||
avio_close(ofmt_ctx->pb);
|
||||
|
||||
avformat_free_context(ofmt_ctx);
|
||||
}
|
||||
|
||||
QString error() { return m_error; }
|
||||
|
||||
public:
|
||||
bool open_status;
|
||||
|
||||
private:
|
||||
QString m_error;
|
||||
|
||||
int video_index, audio_index;
|
||||
int video_frame_index, audio_frame_index;
|
||||
long long video_pts, video_dts, audio_pts, audio_dts;
|
||||
|
||||
AVFormatContext *ofmt_ctx;
|
||||
AVStream *video_dec_stream, *audio_dec_stream;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -23,7 +23,7 @@ CONFIG += c++11
|
|||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
# Input
|
||||
HEADERS += HxDataBase.h HxTaskDispatch.h HxUtils.h HxVideoDevice.h HxVideoDecoder.h
|
||||
HEADERS += HxDataBase.h HxTaskDispatch.h HxUtils.h HxVideoDevice.h HxVideoDecoder.h HxVideoWriter.h
|
||||
SOURCES += HxDataBase.cpp HxTaskDispatch.cpp HxVideoDevice.cpp main.cpp
|
||||
|
||||
#DEFINES += USE_RABBITMQ
|
||||
|
@ -56,6 +56,8 @@ unix {
|
|||
LIBS += -L$$PWD/external/ -lObjectEventDetect
|
||||
PRE_TARGETDEPS += $$PWD/external/libObjectEventDetect.a
|
||||
|
||||
LIBS += -L$$PWD/external/npu -lrknn_api
|
||||
|
||||
LIBS += /usr/lib/librga.so
|
||||
LIBS += /usr/local/lib/librockchip_mpp.so
|
||||
}
|
||||
|
@ -67,4 +69,4 @@ unix {
|
|||
win32 {
|
||||
LIBS += D:/Library/opencv/build/install/x64/mingw/lib/libopencv_*.a
|
||||
LIBS += -LD:/Library/ffmpeg/4.4.4/lib -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswresample -lswscale
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#include <HxDataBase.h>
|
||||
#include "HxTaskDispatch.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication a(argc, argv);
|
||||
|
@ -16,9 +14,8 @@ int main(int argc, char *argv[])
|
|||
HxLog::append("application", "startup");
|
||||
|
||||
/* 创建数据缓存目录 */
|
||||
HxDir::mkdir({{TEMPORARY_LOG_DIRECTORY},
|
||||
{TEMPORARY_VIDEO_DIRECTORY},
|
||||
{TEMPORARY_ALARM_DIRECTORY}});
|
||||
HxDir::mkpath({{TEMPORARY_LOG_DIRECTORY},
|
||||
{TEMPORARY_RECORD_DIRECTORY}});
|
||||
|
||||
/* 设置最大线程个数 */
|
||||
QThreadPool::globalInstance()->setMaxThreadCount(100);
|
||||
|
|
Loading…
Reference in New Issue
Block a user