#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 = "< VideoDevice::compress(Mat frame, int quality) { vector buffer; vector 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 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; }