384 lines
15 KiB
C++
384 lines
15 KiB
C++
#include "Application.h"
|
|
#include "BoostLog.h"
|
|
#include "Configuration.h"
|
|
#include "H264Palyer.h"
|
|
#include "Settings.h"
|
|
#include "VideoFrameProvider.h"
|
|
#include <QFileInfo>
|
|
#include <QFont>
|
|
#include <QGuiApplication>
|
|
#include <QQmlApplicationEngine>
|
|
#include <QQmlContext>
|
|
|
|
std::ostream &operator<<(std::ostream &os, const ImageFormat &format) {
|
|
switch (format) {
|
|
case ImageFormat::Jpeg:
|
|
os << "Jpeg";
|
|
break;
|
|
case ImageFormat::YUV:
|
|
os << "YUV";
|
|
break;
|
|
default:
|
|
os << "Unknown";
|
|
break;
|
|
}
|
|
return os;
|
|
}
|
|
|
|
Application::Application(int &argc, char **argv)
|
|
: m_app(std::make_shared<QGuiApplication>(argc, argv)), m_videoFrameProvider(new VideoFrameProvider()),
|
|
m_player(std::make_shared<H264Palyer>()), m_devices(new DeviceListModel(this)),
|
|
m_collector(new DataCollection(this)) {
|
|
using namespace Amass;
|
|
|
|
m_settings = Singleton<Settings>::instance<Construct>();
|
|
m_settings->load();
|
|
m_collector->setImageFormat(m_settings->imageFormat(), m_settings->imageQuality());
|
|
|
|
QFont font;
|
|
font.setPointSize(16);
|
|
font.setFamily("微软雅黑");
|
|
m_app->setFont(font);
|
|
m_app->setApplicationName(APPLICATION_NAME);
|
|
m_app->setApplicationVersion(QString("v%1").arg(APP_VERSION));
|
|
m_player->open();
|
|
}
|
|
|
|
DeviceConnection::AreaWay Application::currentOpenDoorAreaWay() const {
|
|
return m_currentOpenDoorAreaWay;
|
|
}
|
|
|
|
void Application::setCurrentOpenDoorAreaWay(DeviceConnection::AreaWay way) {
|
|
if (m_currentOpenDoorAreaWay == way) return;
|
|
m_currentOpenDoorAreaWay = way;
|
|
if (m_currentOpenDoorAreaWay == DeviceConnection::Quadrangle) {
|
|
if ((m_currentOpenDoorAreaPoints.size() < 4) || (m_currentOpenDoorAreaPoints == FullArea)) {
|
|
m_currentOpenDoorAreaPoints.clear();
|
|
m_currentOpenDoorAreaPoints << QPointF(68, 6) << QPointF(570, 6) << QPointF(570, 354) << QPointF(68, 354);
|
|
emit currentOpenDoorAreaPointsChanged();
|
|
}
|
|
} else if (m_currentOpenDoorAreaWay == DeviceConnection::FullArea) {
|
|
m_currentOpenDoorAreaPoints.clear();
|
|
m_currentOpenDoorAreaPoints = FullArea;
|
|
emit currentOpenDoorAreaPointsChanged();
|
|
}
|
|
|
|
emit currentOpenDoorAreaWayChanged();
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, m_currentOpenDoorAreaPoints);
|
|
}
|
|
}
|
|
|
|
QList<QPointF> Application::currentOpenDoorAreaPoints() const {
|
|
return m_currentOpenDoorAreaPoints;
|
|
}
|
|
|
|
void Application::setCurrentOpenDoorAreaPoints(const QList<QPointF> &points) {
|
|
if (m_currentOpenDoorAreaPoints != points) {
|
|
m_currentOpenDoorAreaPoints = points;
|
|
emit currentOpenDoorAreaPointsChanged();
|
|
}
|
|
}
|
|
|
|
NetworkInfomation Application::currentNetworkInfomation() const {
|
|
return m_currentNetworkInfomation;
|
|
}
|
|
|
|
bool Application::currentShieldedAreaEnabled() const {
|
|
return m_currentShieldedAreaEnabled;
|
|
}
|
|
|
|
void Application::setCurrentShieldedAreaEnabled(bool enabled) {
|
|
if (m_currentShieldedAreaEnabled != enabled) {
|
|
m_currentShieldedAreaEnabled = enabled;
|
|
emit currentShieldedAreaEnabledChanged();
|
|
|
|
if (m_currentShieldedAreaPoints.size() < 4) {
|
|
m_currentShieldedAreaPoints.clear();
|
|
m_currentShieldedAreaPoints << QPointF(6, 6) << QPointF(40, 60) << QPointF(590, 6) << QPointF(630, 60);
|
|
emit currentShieldedAreaPointsChanged();
|
|
}
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, m_currentShieldedAreaPoints);
|
|
}
|
|
}
|
|
}
|
|
|
|
QList<QPointF> Application::currentShieldedAreaPoints() const {
|
|
return m_currentShieldedAreaPoints;
|
|
}
|
|
|
|
void Application::setCurrentShieldedAreaPoints(const QList<QPointF> &points) {
|
|
if (m_currentShieldedAreaPoints != points) {
|
|
m_currentShieldedAreaPoints = points;
|
|
emit currentShieldedAreaPointsChanged();
|
|
}
|
|
}
|
|
|
|
bool Application::currentAntiClipAreaEnabled() const {
|
|
return m_currentAntiClipAreaEnabled;
|
|
}
|
|
|
|
void Application::setCurrentAntiClipAreaEnabled(bool enabled) {
|
|
if (m_currentAntiClipAreaEnabled != enabled) {
|
|
m_currentAntiClipAreaEnabled = enabled;
|
|
emit currentAntiClipAreaEnabledChanged();
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, m_currentAntiClipAreaPoints);
|
|
}
|
|
}
|
|
}
|
|
|
|
QList<QPointF> Application::currentAntiClipAreaPoints() const {
|
|
return m_currentAntiClipAreaPoints;
|
|
}
|
|
|
|
void Application::setCurrentAntiClipAreaPoints(const QList<QPointF> &points) {
|
|
if (m_currentAntiClipAreaPoints != points) {
|
|
m_currentAntiClipAreaPoints = points;
|
|
emit currentAntiClipAreaPointsChanged();
|
|
}
|
|
}
|
|
|
|
void Application::updateOpenDoorAreaPoints(const QList<QPointF> &points) {
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateOpenDoorAreaPoints(m_currentOpenDoorAreaWay, points);
|
|
}
|
|
}
|
|
|
|
void Application::updateAntiClipAreaPoints(const QList<QPointF> &points) {
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateAntiClipAreaPoints(m_currentAntiClipAreaEnabled, points);
|
|
}
|
|
}
|
|
|
|
void Application::updateShieldedAreaPoints(const QList<QPointF> &points) {
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateShieldedAreaPoints(m_currentShieldedAreaEnabled, points);
|
|
}
|
|
}
|
|
|
|
bool Application::currentDeviceFlip() const {
|
|
return m_currentDeviceFlip;
|
|
}
|
|
void Application::setCurrentDeviceFlip(bool flip) {
|
|
if (m_currentDeviceFlip != flip) {
|
|
m_currentDeviceFlip = flip;
|
|
emit currentDeviceFlipChanged();
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateFlip(flip);
|
|
}
|
|
}
|
|
}
|
|
|
|
int Application::currentDeviceRotation() const {
|
|
return m_currentDeviceRotation;
|
|
}
|
|
|
|
void Application::setCurrentDeviceRotation(int rotation) {
|
|
if (m_currentDeviceRotation != rotation) {
|
|
m_currentDeviceRotation = rotation;
|
|
emit currentDeviceRotationChanged();
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
device->updateRotation(rotation);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway,
|
|
const QString &dns) {
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
if (device->isConnected()) {
|
|
device->updateNetworkInfomation(dhcp, ip, netmask, gateway, dns);
|
|
emit newMessage(1, "网络设置", "设置成功,请等待设备重新上线!");
|
|
} else {
|
|
emit newMessage(2, "网络设置", "设备已离线!");
|
|
}
|
|
}
|
|
}
|
|
|
|
void Application::connectToDevice(int index) {
|
|
if (!m_device.expired()) {
|
|
auto device = m_device.lock();
|
|
disconnect(device.get(), &DeviceConnection::rotationChanged, this, &Application::onDeviceRotationChanged);
|
|
disconnect(device.get(), &DeviceConnection::flipChanged, this, &Application::onDeviceFlipChanged);
|
|
disconnect(device.get(), &DeviceConnection::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
|
|
disconnect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea);
|
|
disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
|
|
disconnect(device.get(), &DeviceConnection::networkInfomationChanged, this,
|
|
&Application::onDeviceNetworkInfomation);
|
|
disconnect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware);
|
|
disconnect(device.get(), &DeviceConnection::otaProgressChanged, this,
|
|
&Application::currentDeviceOtaProgressChanged);
|
|
disconnect(device.get(), &DeviceConnection::connected, this, &Application::onDeviceConnected);
|
|
disconnect(device.get(), &DeviceConnection::disconnected, this, &Application::onDeviceDisconnected);
|
|
|
|
device->setH264FrameCallback(DeviceConnection::H264FrameCallback());
|
|
device->setLiveStreamEnabled(false);
|
|
if (!m_currentFirmware.isEmpty()) {
|
|
m_currentFirmware.clear();
|
|
}
|
|
m_currentDeviceConnected = false;
|
|
}
|
|
if (index >= 0) {
|
|
auto device = m_devices->device(index);
|
|
m_device = device;
|
|
|
|
connect(device.get(), &DeviceConnection::rotationChanged, this, &Application::onDeviceRotationChanged);
|
|
connect(device.get(), &DeviceConnection::flipChanged, this, &Application::onDeviceFlipChanged);
|
|
connect(device.get(), &DeviceConnection::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
|
|
connect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea);
|
|
connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
|
|
connect(device.get(), &DeviceConnection::networkInfomationChanged, this,
|
|
&Application::onDeviceNetworkInfomation);
|
|
connect(device.get(), &DeviceConnection::firmwareChanged, this, &Application::onDeviceFirmware);
|
|
connect(device.get(), &DeviceConnection::otaProgressChanged, this,
|
|
&Application::currentDeviceOtaProgressChanged);
|
|
connect(device.get(), &DeviceConnection::connected, this, &Application::onDeviceConnected);
|
|
connect(device.get(), &DeviceConnection::disconnected, this, &Application::onDeviceDisconnected);
|
|
device->setH264FrameCallback([this](const char *data, uint32_t size) {
|
|
auto image = m_player->decode((const uint8_t *)data, size);
|
|
if (image) {
|
|
m_videoFrameProvider->setImage(*image);
|
|
emit newVideoFrame();
|
|
}
|
|
});
|
|
device->setLiveStreamEnabled(true);
|
|
auto info = device->infomation();
|
|
m_currentOpenDoorAreaWay = info.openDoorAreaWay;
|
|
m_currentOpenDoorAreaPoints = info.openDoorArea;
|
|
m_currentShieldedAreaEnabled = info.shieldedAreaEnabled;
|
|
m_currentShieldedAreaPoints = info.shieldedArea;
|
|
m_currentAntiClipAreaEnabled = info.antiClipAreaEnabled;
|
|
m_currentAntiClipAreaPoints = info.antiClipArea;
|
|
m_currentNetworkInfomation = device->networkInfomation();
|
|
m_currentFirmware = device->infomation().firmwareVersion;
|
|
m_currentDeviceConnected = device->isConnected();
|
|
m_currentDeviceFlip = info.flip;
|
|
m_currentDeviceRotation = info.rotation;
|
|
emit currentDeviceRotationChanged();
|
|
emit currentDeviceFlipChanged();
|
|
emit currentOpenDoorAreaPointsChanged();
|
|
emit currentShieldedAreaPointsChanged();
|
|
emit currentAntiClipAreaPointsChanged();
|
|
emit currentOpenDoorAreaWayChanged();
|
|
emit currentShieldedAreaEnabledChanged();
|
|
emit currentAntiClipAreaEnabledChanged();
|
|
emit currentNetworkInfomationChanged();
|
|
}
|
|
emit currentFirmwareChanged();
|
|
emit currentDeviceConnectedChanged();
|
|
}
|
|
|
|
void Application::startSearchDevice() {
|
|
connectToDevice(-1);
|
|
m_devices->startSearchDevice();
|
|
}
|
|
|
|
void Application::upgradeDevice(const QString &file) {
|
|
if (m_device.expired()) return;
|
|
auto device = m_device.lock();
|
|
auto infomation = device->infomation();
|
|
auto versionPrefix = infomation.softwareVersion.left(7);
|
|
constexpr auto version = "RD_T009_V21R003B013";
|
|
QFileInfo fileInfo(file);
|
|
QString baseName = fileInfo.baseName();
|
|
int position = baseName.indexOf(versionPrefix);
|
|
if (position < 0 || ((baseName.length() - position) < std::strlen(version))) {
|
|
emit newMessage(2, "OTA升级", "文件名格式不合法!");
|
|
LOG(error) << "baseName: " << baseName.toStdString() << ", position: " << position;
|
|
return;
|
|
}
|
|
QString firmware = baseName.mid(position);
|
|
if (device->isConnected()) {
|
|
device->requestOta(firmware, file);
|
|
} else {
|
|
emit newMessage(2, "OTA升级", "设备已离线,请重新连接设备!");
|
|
}
|
|
}
|
|
|
|
void Application::onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QList<QPointF> &points) {
|
|
setCurrentOpenDoorAreaWay(way);
|
|
setCurrentOpenDoorAreaPoints(points);
|
|
}
|
|
|
|
void Application::onDeviceRotationChanged(int rotation) {
|
|
setCurrentDeviceRotation(rotation);
|
|
}
|
|
void Application::onDeviceFlipChanged(bool flip) {
|
|
setCurrentDeviceFlip(flip);
|
|
}
|
|
|
|
void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) {
|
|
setCurrentShieldedAreaEnabled(enabled);
|
|
setCurrentShieldedAreaPoints(points);
|
|
}
|
|
|
|
void Application::onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points) {
|
|
setCurrentAntiClipAreaEnabled(enabled);
|
|
setCurrentAntiClipAreaPoints(points);
|
|
}
|
|
|
|
void Application::onDeviceNetworkInfomation(const NetworkInfomation &info) {
|
|
m_currentNetworkInfomation = info;
|
|
emit currentNetworkInfomationChanged();
|
|
}
|
|
|
|
void Application::onDeviceFirmware(const QString &firmware) {
|
|
if (m_currentFirmware != firmware) {
|
|
m_currentFirmware = firmware;
|
|
emit currentFirmwareChanged();
|
|
}
|
|
}
|
|
|
|
void Application::onDeviceConnected() {
|
|
m_currentDeviceConnected = true;
|
|
emit currentDeviceConnectedChanged();
|
|
}
|
|
|
|
void Application::onDeviceDisconnected() {
|
|
m_currentDeviceConnected = false;
|
|
emit currentDeviceConnectedChanged();
|
|
m_collector->stop();
|
|
}
|
|
|
|
int Application::exec() {
|
|
QQmlApplicationEngine engine;
|
|
engine.addImageProvider("videoframe", m_videoFrameProvider);
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
QObject::connect(
|
|
&engine, &QQmlApplicationEngine::objectCreationFailed, this, []() { QCoreApplication::exit(-1); },
|
|
Qt::QueuedConnection);
|
|
engine.loadFromModule("AntiClipSettings", "Main");
|
|
#else
|
|
qmlRegisterSingletonInstance("AntiClipSettings", 1, 0, "App", this);
|
|
qmlRegisterUncreatableType<DeviceConnection>("AntiClipSettings", 1, 0, "DeviceConnection",
|
|
"Only created in C++...");
|
|
engine.load("qrc:/qt/qml/AntiClipSettings/qml/Main.qml");
|
|
#endif
|
|
bool isQt5 = (QT_VERSION < QT_VERSION_CHECK(6, 0, 0));
|
|
engine.rootContext()->setContextProperty("isQt5", isQt5);
|
|
return m_app->exec();
|
|
}
|
|
|
|
Application *Application::create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) {
|
|
Application *ret = nullptr;
|
|
auto app = Amass::Singleton<Application>::instance();
|
|
if (app) {
|
|
ret = app.get();
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
QJSEngine::setObjectOwnership(ret, QJSEngine::CppOwnership);
|
|
#endif
|
|
}
|
|
return ret;
|
|
}
|