407 lines
14 KiB
C++
407 lines
14 KiB
C++
#include "HxVideoDevice.h"
|
|
|
|
/* bsd算法结果处理函数 */
|
|
void algorithm_alarm_callback(int nDataChannel, ObjectTrackEventResult *pObjectTrackEventResult, void *pPrivData)
|
|
{
|
|
Q_UNUSED(nDataChannel);
|
|
Q_UNUSED(pPrivData);
|
|
|
|
if (pObjectTrackEventResult->nEventType == 0)
|
|
return;
|
|
|
|
if (nDataChannel == 0) /* ADAS */
|
|
{
|
|
printf("ProcessAdasAlgResult nDataChannel=%d,nFrameId=%d,nObjectNumber=%d,nEventType=%x\n", nDataChannel, pObjectTrackEventResult->nFrameId, pObjectTrackEventResult->nObjectNumber, pObjectTrackEventResult->nEventType);
|
|
|
|
/* 生成报警图片 */
|
|
auto base64_string = TaskDispatch::build_alarm_image(ALGORITHM_TYPE_ADAS, 0, pObjectTrackEventResult->nFrameId);
|
|
|
|
/* 生成报警视频 */
|
|
auto filename = TaskDispatch::build_alarm_video(ALGORITHM_TYPE_ADAS, 0, pObjectTrackEventResult->nFrameId);
|
|
|
|
/* 上传 */
|
|
TaskDispatch::algorithm_alarm_event(0, 0, pObjectTrackEventResult->nEventType, 0, 0, 0, 0, 0, 0, 0, base64_string, filename);
|
|
}
|
|
else if (nDataChannel == 2) /* DSM */
|
|
{
|
|
printf("ProcessDsmAlgResult nDataChannel=%d,nFrameId=%d,nObjectNumber=%d,nEventType=%x\n", nDataChannel, pObjectTrackEventResult->nFrameId, pObjectTrackEventResult->nObjectNumber, pObjectTrackEventResult->nEventType);
|
|
|
|
/* 生成报警图片 */
|
|
auto base64_string = TaskDispatch::build_alarm_image(ALGORITHM_TYPE_DSM, 0, pObjectTrackEventResult->nFrameId);
|
|
|
|
/* 生成报警视频 */
|
|
auto filename = TaskDispatch::build_alarm_video(ALGORITHM_TYPE_DSM, 0, pObjectTrackEventResult->nFrameId);
|
|
|
|
/* 上传 */
|
|
TaskDispatch::algorithm_alarm_event(1, 0, pObjectTrackEventResult->nEventType, 0, 0, 0, 0, 0, 0, 0, base64_string, filename);
|
|
}
|
|
else if (nDataChannel == 1 || /* BSD-右前 */
|
|
nDataChannel == 3 || /* BSD-右后 */
|
|
nDataChannel == 4 || /* BSD-左前 */
|
|
nDataChannel == 5 || /* BSD-左后 */
|
|
nDataChannel == 6 || /* BSD-前 */
|
|
nDataChannel == 7) /* BSD-后 */
|
|
{
|
|
int channel = 0;
|
|
|
|
switch (nDataChannel)
|
|
{
|
|
case 6:
|
|
channel = 0;
|
|
break;
|
|
case 7:
|
|
channel = 1;
|
|
break;
|
|
case 4:
|
|
channel = 2;
|
|
break;
|
|
case 1:
|
|
channel = 3;
|
|
break;
|
|
case 5:
|
|
channel = 4;
|
|
break;
|
|
case 3:
|
|
channel = 5;
|
|
break;
|
|
}
|
|
|
|
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 base64_string = TaskDispatch::build_alarm_image(ALGORITHM_TYPE_BSD, channel, pObjectTrackEventResult->nFrameId);
|
|
|
|
/* 生成报警视频 */
|
|
auto filename = TaskDispatch::build_alarm_video(ALGORITHM_TYPE_BSD, channel, pObjectTrackEventResult->nFrameId);
|
|
|
|
/* 上传 */
|
|
TaskDispatch::algorithm_alarm_event(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,
|
|
base64_string,
|
|
filename);
|
|
}
|
|
}
|
|
}
|
|
|
|
VideoDevice::VideoDevice(void)
|
|
{
|
|
detect_frame_buffer.u32Width = 1280;
|
|
detect_frame_buffer.u32Height = 720;
|
|
MvGetFrameBlkInfo(&detect_frame_buffer);
|
|
|
|
bgr_frame_buffer.u32Width = 1280;
|
|
bgr_frame_buffer.u32Height = 720;
|
|
MvGetFrameBlkInfo(&bgr_frame_buffer);
|
|
}
|
|
|
|
void VideoDevice::set(int type, QString address)
|
|
{
|
|
this->type = type;
|
|
this->address = address;
|
|
#if USE_ALGORITHM
|
|
auto result = MvSetAlgResultFuncCallback(type, algorithm_alarm_callback, nullptr);
|
|
if (result != 0)
|
|
return;
|
|
#endif
|
|
|
|
start();
|
|
}
|
|
|
|
void VideoDevice::set(int type, QString address, BsdWarnRegion region)
|
|
{
|
|
Q_UNUSED(region);
|
|
|
|
this->type = type;
|
|
this->address = address;
|
|
this->detection_status = false;
|
|
|
|
#if USE_ALGORITHM
|
|
auto result = MvSetAlgResultFuncCallback(type, algorithm_alarm_callback, nullptr);
|
|
if (result != 0)
|
|
return;
|
|
|
|
MvSetBsdWarnRegion(type, ®ion);
|
|
#endif
|
|
|
|
start();
|
|
}
|
|
|
|
void VideoDevice::set(bool status) { detection_status = status; }
|
|
|
|
QString VideoDevice::snap() { return snap(video_frame); }
|
|
|
|
QString VideoDevice::build_image(int id)
|
|
{
|
|
if (video_frames_string.contains(id))
|
|
return snap(video_frames_string[id]);
|
|
|
|
return "";
|
|
}
|
|
|
|
QString VideoDevice::build_video(int id)
|
|
{
|
|
QString url = QString("ftp://%3/%4/%5/alarm/").arg(DataBase::ftp_address, QDateTime::currentDateTime().toString("yyyyMMdd"), DataBase::device_id);
|
|
QString filename = QString("%1.mp4").arg(QDateTime::currentDateTime().toString("yyyyMMddHHmmsszzz"));
|
|
|
|
QtConcurrent::run([=]()
|
|
{
|
|
if(video_frames_string.contains(id))
|
|
{
|
|
frame_mutex.lock();
|
|
auto first_key = video_frames_string.firstKey();
|
|
frame_mutex.unlock();
|
|
|
|
auto start_id = id - frame_fps * 10, end_id = id + frame_fps * 10;
|
|
|
|
start_id = start_id < first_key ? first_key : start_id;
|
|
|
|
qDebug() << "build video; start id = "<<start_id << " end id = " << end_id;
|
|
|
|
while(true)
|
|
{
|
|
frame_mutex.lock();
|
|
auto last_key = video_frames_string.lastKey();
|
|
frame_mutex.unlock();
|
|
|
|
// qDebug() << " end id = " << end_id << " last id = "<< last_key;
|
|
|
|
/* 判断最新的视频帧是否超过设定的时间 */
|
|
if(last_key >= end_id)
|
|
{
|
|
frame_mutex.lock();
|
|
auto _video_frames_string = video_frames_string;
|
|
_video_frames_string.detach();
|
|
frame_mutex.unlock();
|
|
|
|
VideoWriter writer(filename.toUtf8().data(), CV_FOURCC('m', 'p', '4', 'v'), frame_fps, Size(video_capture.get(CV_CAP_PROP_FRAME_WIDTH), video_capture.get(CV_CAP_PROP_FRAME_HEIGHT)), true);
|
|
|
|
for(int i = start_id; i <= end_id; i++)
|
|
{
|
|
auto __frame = imdecode(_video_frames_string[i], CV_LOAD_IMAGE_COLOR);
|
|
|
|
writer.write(__frame);
|
|
|
|
msleep(frame_fps);
|
|
|
|
qDebug() << " write "<< filename <<". frame id = " << i;
|
|
}
|
|
|
|
writer.release();
|
|
|
|
qDebug() << "video build finish";
|
|
|
|
HxProcessUtils::execute(QString("curl -u %1:%2 %3 --ftp-create-dirs -T %4")
|
|
.arg(DataBase::ftp_username,
|
|
DataBase::ftp_password,
|
|
url,
|
|
filename));
|
|
|
|
QFile::remove(filename);
|
|
|
|
return;
|
|
}
|
|
msleep(100);
|
|
}
|
|
} });
|
|
|
|
return url + filename;
|
|
}
|
|
|
|
void VideoDevice::test(void)
|
|
{
|
|
ObjectTrackEventResult pObjectTrackEventResult = {0};
|
|
pObjectTrackEventResult.nFrameId = video_frames_string.lastKey();
|
|
pObjectTrackEventResult.nEventType = EVENT_PCW;
|
|
pObjectTrackEventResult.nObjectNumber = 1;
|
|
pObjectTrackEventResult.objInfo[0].nDetectType = PEDESTRIAN_TYPE;
|
|
algorithm_alarm_callback(0, &pObjectTrackEventResult, nullptr);
|
|
}
|
|
|
|
vector<uint8_t> VideoDevice::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 VideoDevice::snap(Mat frame)
|
|
{
|
|
if (frame.data != nullptr)
|
|
return snap(compress(frame, 50));
|
|
|
|
return "";
|
|
}
|
|
|
|
QString VideoDevice::snap(vector<uint8_t> buffer)
|
|
{
|
|
QByteArray byteArray = QByteArray::fromRawData((const char *)buffer.data(), buffer.size());
|
|
|
|
return QString(byteArray.toBase64());
|
|
}
|
|
|
|
void VideoDevice::video_frame_queue_check()
|
|
{
|
|
if (video_frames_string.count() > frame_fps * 30)
|
|
{
|
|
frame_mutex.lock();
|
|
video_frames_string.remove(video_frames_string.firstKey());
|
|
frame_mutex.unlock();
|
|
}
|
|
}
|
|
|
|
void VideoDevice::read_frame()
|
|
{
|
|
if (address.isEmpty())
|
|
return;
|
|
|
|
if (detection_status)
|
|
{
|
|
if (!video_capture.isOpened())
|
|
{
|
|
video_capture = VideoCapture(address.toUtf8().data());
|
|
|
|
frame_fps = video_capture.get(CV_CAP_PROP_FPS);
|
|
|
|
qDebug() << address << " open";
|
|
}
|
|
|
|
auto car = TaskDispatch::get_car_info();
|
|
|
|
if (car->fVelocity >= 10)
|
|
{
|
|
if (!video_capture.read(video_frame))
|
|
{
|
|
qDebug() << address << " close";
|
|
|
|
video_capture.release();
|
|
|
|
return;
|
|
}
|
|
|
|
if (video_frame.data != nullptr)
|
|
{
|
|
frame_mutex.lock();
|
|
video_frames_string.insert(frame_id, compress(video_frame, 80));
|
|
frame_mutex.unlock();
|
|
|
|
#if USE_ALGORITHM
|
|
bgr_frame_buffer.nFrameId = frame_id; // 帧号
|
|
bgr_frame_buffer.u64PTS = QDateTime::currentMSecsSinceEpoch(); // 时间戳(毫秒)
|
|
|
|
memcpy(bgr_frame_buffer.pu8VirAddr, video_frame.data, 1280 * 720 * 3);
|
|
|
|
MvConvertImage(&bgr_frame_buffer, &detect_frame_buffer); // bgr->nv16
|
|
|
|
MvObjectEventDetect(this->type, &detect_frame_buffer, TaskDispatch::get_car_info());
|
|
#endif
|
|
|
|
frame_id++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void VideoDevice::run()
|
|
{
|
|
frame_id = 0;
|
|
|
|
while (true)
|
|
{
|
|
video_frame_queue_check();
|
|
|
|
read_frame();
|
|
|
|
msleep(1);
|
|
}
|
|
}
|
|
|
|
int VideoDevice::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 VideoDevice::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 VideoDevice::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;
|
|
}
|