实现视频旋转及翻转指令控制。

This commit is contained in:
luocai 2024-11-13 14:25:22 +08:00
parent bf3ad2be2f
commit f55d3aa9df
6 changed files with 210 additions and 23 deletions

View File

@ -164,6 +164,35 @@ void Application::updateShieldedAreaPoints(const QList<QPointF> &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, void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway,
const QString &dns) { const QString &dns) {
if (!m_device.expired()) { if (!m_device.expired()) {
@ -180,6 +209,8 @@ void Application::updateNetworkInfomation(bool dhcp, const QString &ip, const QS
void Application::connectToDevice(int index) { void Application::connectToDevice(int index) {
if (!m_device.expired()) { if (!m_device.expired()) {
auto device = m_device.lock(); 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::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
disconnect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea); disconnect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea);
disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); disconnect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
@ -202,6 +233,8 @@ void Application::connectToDevice(int index) {
auto device = m_devices->device(index); auto device = m_devices->device(index);
m_device = device; 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::openDoorAreaChanged, this, &Application::onDeviceOpenDoorArea);
connect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea); connect(device.get(), &DeviceConnection::shieldedAreaChanged, this, &Application::onDeviceShieldedArea);
connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea); connect(device.get(), &DeviceConnection::antiClipAreaChanged, this, &Application::onDeviceAntiClipArea);
@ -220,16 +253,20 @@ void Application::connectToDevice(int index) {
} }
}); });
device->setLiveStreamEnabled(true); device->setLiveStreamEnabled(true);
auto area = device->area(); auto info = device->infomation();
m_currentOpenDoorAreaWay = area.openDoorAreaWay; m_currentOpenDoorAreaWay = info.openDoorAreaWay;
m_currentOpenDoorAreaPoints = area.openDoorArea; m_currentOpenDoorAreaPoints = info.openDoorArea;
m_currentShieldedAreaEnabled = area.shieldedAreaEnabled; m_currentShieldedAreaEnabled = info.shieldedAreaEnabled;
m_currentShieldedAreaPoints = area.shieldedArea; m_currentShieldedAreaPoints = info.shieldedArea;
m_currentAntiClipAreaEnabled = area.antiClipAreaEnabled; m_currentAntiClipAreaEnabled = info.antiClipAreaEnabled;
m_currentAntiClipAreaPoints = area.antiClipArea; m_currentAntiClipAreaPoints = info.antiClipArea;
m_currentNetworkInfomation = device->networkInfomation(); m_currentNetworkInfomation = device->networkInfomation();
m_currentFirmware = device->infomation().firmwareVersion; m_currentFirmware = device->infomation().firmwareVersion;
m_currentDeviceConnected = device->isConnected(); m_currentDeviceConnected = device->isConnected();
m_currentDeviceFlip = info.flip;
m_currentDeviceRotation = info.rotation;
emit currentDeviceRotationChanged();
emit currentDeviceFlipChanged();
emit currentOpenDoorAreaPointsChanged(); emit currentOpenDoorAreaPointsChanged();
emit currentShieldedAreaPointsChanged(); emit currentShieldedAreaPointsChanged();
emit currentAntiClipAreaPointsChanged(); emit currentAntiClipAreaPointsChanged();
@ -274,6 +311,13 @@ void Application::onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QLis
setCurrentOpenDoorAreaPoints(points); 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) { void Application::onDeviceShieldedArea(bool enabled, const QList<QPointF> &points) {
setCurrentShieldedAreaEnabled(enabled); setCurrentShieldedAreaEnabled(enabled);
setCurrentShieldedAreaPoints(points); setCurrentShieldedAreaPoints(points);

View File

@ -40,6 +40,10 @@ class Application : public QObject {
NetworkInfomation currentNetworkInfomation READ currentNetworkInfomation NOTIFY currentNetworkInfomationChanged) NetworkInfomation currentNetworkInfomation READ currentNetworkInfomation NOTIFY currentNetworkInfomationChanged)
Q_PROPERTY(QString currentFirmware MEMBER m_currentFirmware NOTIFY currentFirmwareChanged) Q_PROPERTY(QString currentFirmware MEMBER m_currentFirmware NOTIFY currentFirmwareChanged)
Q_PROPERTY(bool currentDeviceConnected MEMBER m_currentDeviceConnected NOTIFY currentDeviceConnectedChanged) Q_PROPERTY(bool currentDeviceConnected MEMBER m_currentDeviceConnected NOTIFY currentDeviceConnectedChanged)
Q_PROPERTY(bool currentDeviceFlip READ currentDeviceFlip WRITE setCurrentDeviceFlip NOTIFY currentDeviceFlipChanged)
Q_PROPERTY(int currentDeviceRotation READ currentDeviceRotation WRITE setCurrentDeviceRotation NOTIFY
currentDeviceRotationChanged)
friend class Amass::Singleton<Application>; friend class Amass::Singleton<Application>;
public: public:
@ -64,6 +68,12 @@ public:
QList<QPointF> currentAntiClipAreaPoints() const; QList<QPointF> currentAntiClipAreaPoints() const;
void setCurrentAntiClipAreaPoints(const QList<QPointF> &points); void setCurrentAntiClipAreaPoints(const QList<QPointF> &points);
bool currentDeviceFlip() const;
void setCurrentDeviceFlip(bool flip);
int currentDeviceRotation() const;
void setCurrentDeviceRotation(int rotation);
Q_INVOKABLE void updateOpenDoorAreaPoints(const QList<QPointF> &points); Q_INVOKABLE void updateOpenDoorAreaPoints(const QList<QPointF> &points);
Q_INVOKABLE void updateAntiClipAreaPoints(const QList<QPointF> &points); Q_INVOKABLE void updateAntiClipAreaPoints(const QList<QPointF> &points);
Q_INVOKABLE void updateShieldedAreaPoints(const QList<QPointF> &points); Q_INVOKABLE void updateShieldedAreaPoints(const QList<QPointF> &points);
@ -88,10 +98,14 @@ signals:
void currentFirmwareChanged(); void currentFirmwareChanged();
void currentDeviceConnectedChanged(); void currentDeviceConnectedChanged();
void currentDeviceOtaProgressChanged(bool status, int progress, const QString &message); void currentDeviceOtaProgressChanged(bool status, int progress, const QString &message);
void currentDeviceFlipChanged();
void currentDeviceRotationChanged();
void newMessage(int type, const QString &title, const QString &message); void newMessage(int type, const QString &title, const QString &message);
protected: protected:
Application(int &argc, char **argv); Application(int &argc, char **argv);
void onDeviceRotationChanged(int rotation);
void onDeviceFlipChanged(bool flip);
void onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QList<QPointF> &points); void onDeviceOpenDoorArea(DeviceConnection::AreaWay way, const QList<QPointF> &points);
void onDeviceShieldedArea(bool enabled, const QList<QPointF> &points); void onDeviceShieldedArea(bool enabled, const QList<QPointF> &points);
void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points); void onDeviceAntiClipArea(bool enabled, const QList<QPointF> &points);
@ -118,6 +132,8 @@ private:
NetworkInfomation m_currentNetworkInfomation; NetworkInfomation m_currentNetworkInfomation;
QString m_currentFirmware; QString m_currentFirmware;
bool m_currentDeviceConnected = false; bool m_currentDeviceConnected = false;
bool m_currentDeviceFlip = false;
int m_currentDeviceRotation = 0;
}; };
#endif // APPLICATION_H #endif // APPLICATION_H

View File

@ -73,10 +73,6 @@ void DeviceConnection::connect(const Infomation &infomation) {
m_h264Socket->connectToHost(infomation.ip, 8000); m_h264Socket->connectToHost(infomation.ip, 8000);
} }
DeviceConnection::Area DeviceConnection::area() const {
return m_area;
}
NetworkInfomation DeviceConnection::networkInfomation() const { NetworkInfomation DeviceConnection::networkInfomation() const {
return m_networkInfomation; return m_networkInfomation;
} }
@ -262,6 +258,44 @@ void DeviceConnection::requestResolution(Resolution resolution) {
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::updateRotation(int rotation) {
Task task;
task.command = "a23imagerotate_setdata";
task.task = [this, rotation]() {
boost::json::object request;
request["func"] = "a23imagerotate_setdata";
request["deviceid"] = "0";
boost::json::object data;
data["value"] = std::to_string(rotation);
request["data"] = std::move(data);
auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size());
LOG(info) << "updateRotation: " << text;
};
if (m_requests.empty()) {
task.task();
}
m_requests.push(task);
}
void DeviceConnection::updateFlip(bool flip) {
Task task;
task.command = "a04imageflipping_setdata";
task.task = [this, flip]() {
boost::json::object request;
request["func"] = "a04imageflipping_setdata";
request["deviceid"] = "0";
boost::json::object data;
data["value"] = flip ? "2" : "1";
request["data"] = std::move(data);
auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size());
};
if (m_requests.empty()) {
task.task();
}
m_requests.push(task);
}
void DeviceConnection::requestVersion() { void DeviceConnection::requestVersion() {
Task task; Task task;
task.command = "a15devicedetail_getdata"; task.command = "a15devicedetail_getdata";
@ -281,6 +315,27 @@ void DeviceConnection::requestVersion() {
m_requests.push(task); m_requests.push(task);
} }
void DeviceConnection::requestVideoInformation() {
constexpr const char *commands[] = {"a23imagerotate_getdata", "a04imageflipping_getdata"};
for (auto command : commands) {
Task task;
task.command = command;
task.task = [this, command]() {
boost::json::object request;
request["func"] = command;
request["deviceid"] = "0";
boost::json::object data;
request["data"] = std::move(data);
auto text = boost::json::serialize(request);
m_commandSocket->write(text.data(), text.size());
};
if (m_requests.empty()) {
task.task();
}
m_requests.push(task);
}
}
void DeviceConnection::requestNetworkInfomation() { void DeviceConnection::requestNetworkInfomation() {
Task task; Task task;
task.command = "netconfig_getdata"; task.command = "netconfig_getdata";
@ -457,8 +512,8 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
} else if (value == "2") { } else if (value == "2") {
way = Quadrangle; way = Quadrangle;
} }
m_area.openDoorAreaWay = way; m_infomation.openDoorAreaWay = way;
m_area.openDoorArea = points; m_infomation.openDoorArea = points;
emit openDoorAreaChanged(way, points); emit openDoorAreaChanged(way, points);
} else if (function == "a03opendoor4_getdata") { } else if (function == "a03opendoor4_getdata") {
auto &data = reply.at("data").as_object(); auto &data = reply.at("data").as_object();
@ -472,8 +527,8 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
point.setY(obj.at("y").as_double()); point.setY(obj.at("y").as_double());
points.push_back(point); points.push_back(point);
} }
m_area.shieldedAreaEnabled = value == "1"; m_infomation.shieldedAreaEnabled = value == "1";
m_area.shieldedArea = points; m_infomation.shieldedArea = points;
emit shieldedAreaChanged(value == "1", points); emit shieldedAreaChanged(value == "1", points);
} else if (function == "a03opendoor5_getdata") { } else if (function == "a03opendoor5_getdata") {
auto &data = reply.at("data").as_object(); auto &data = reply.at("data").as_object();
@ -487,8 +542,8 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
point.setY(obj.at("y").as_double()); point.setY(obj.at("y").as_double());
points.push_back(point); points.push_back(point);
} }
m_area.antiClipAreaEnabled = value == "1"; m_infomation.antiClipAreaEnabled = value == "1";
m_area.antiClipArea = points; m_infomation.antiClipArea = points;
emit antiClipAreaChanged(value == "1", points); emit antiClipAreaChanged(value == "1", points);
} else if (function == "netconfig_getdata") { } else if (function == "netconfig_getdata") {
auto &data = reply.at("data").as_object(); auto &data = reply.at("data").as_object();
@ -579,6 +634,40 @@ QString DeviceConnection::handleCommand(const std::string_view &replyText, const
} }
emit otaProgressChanged(false, m_otaProgress, tip); emit otaProgressChanged(false, m_otaProgress, tip);
} }
} else if (function == "a23imagerotate_getdata") {
// {"data":{"value":"2"},"deviceid":"0","flag":"ok","func":"a23imagerotate_getdata"}
auto &data = reply.at("data").as_object();
auto &value = data.at("value").as_string();
m_infomation.rotation = std::stoi(static_cast<std::string>(value));
emit rotationChanged(m_infomation.rotation);
} else if (function == "a04imageflipping_getdata") {
// {"data":{"value":"1"},"deviceid":"0","flag":"ok","func":"a04imageflipping_getdata"}
auto &data = reply.at("data").as_object();
auto &value = data.at("value").as_string();
m_infomation.flip = value == "2";
emit flipChanged(m_infomation.flip);
} else if (function == "a04imageflipping_setdata") {
if ((task != nullptr) && (task->command.toStdString() == function)) {
if (task->timeoutTimer) {
task->timeoutTimer->stop();
}
bool status = true;
if (task->future) {
task->future->reportFinished(&status);
}
}
requestVideoInformation();
} else if (function == "a23imagerotate_setdata") {
if ((task != nullptr) && (task->command.toStdString() == function)) {
if (task->timeoutTimer) {
task->timeoutTimer->stop();
}
bool status = true;
if (task->future) {
task->future->reportFinished(&status);
}
}
requestVideoInformation();
} else { } else {
LOG(warning) << "unknown reply: " << replyText; LOG(warning) << "unknown reply: " << replyText;
} }
@ -593,6 +682,7 @@ void DeviceConnection::onConnected() {
requestShieldedArea(); requestShieldedArea();
requestAntiClipArea(); requestAntiClipArea();
requestNetworkInfomation(); requestNetworkInfomation();
requestVideoInformation();
emit connected(); emit connected();
m_timerId = startTimer(2500); m_timerId = startTimer(2500);
if (m_otaProgress == 99) { if (m_otaProgress == 99) {

View File

@ -34,11 +34,10 @@ public:
QString softwareVersion; QString softwareVersion;
QString firmwareVersion; QString firmwareVersion;
QString ip; QString ip;
};
Q_ENUM(AreaWay)
class Area { int rotation = 0;
public: bool flip = false;
QList<QPointF> openDoorArea; QList<QPointF> openDoorArea;
AreaWay openDoorAreaWay; AreaWay openDoorAreaWay;
@ -48,6 +47,7 @@ public:
QList<QPointF> antiClipArea; QList<QPointF> antiClipArea;
bool antiClipAreaEnabled; bool antiClipAreaEnabled;
}; };
Q_ENUM(AreaWay)
using H264FrameCallback = std::function<void(const char *data, uint32_t size)>; using H264FrameCallback = std::function<void(const char *data, uint32_t size)>;
DeviceConnection(QObject *parent = nullptr); DeviceConnection(QObject *parent = nullptr);
@ -60,7 +60,6 @@ public:
void setLiveStreamEnabled(bool enabled); void setLiveStreamEnabled(bool enabled);
NetworkInfomation networkInfomation() const; NetworkInfomation networkInfomation() const;
Area area() const;
void requestOpenDoorArea(); void requestOpenDoorArea();
QFuture<bool> updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points); QFuture<bool> updateOpenDoorAreaPoints(AreaWay way, const QList<QPointF> &points);
@ -73,6 +72,9 @@ public:
QFuture<bool> updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway, QFuture<bool> updateNetworkInfomation(bool dhcp, const QString &ip, const QString &netmask, const QString &gateway,
const QString &dns); const QString &dns);
void requestVersion(); void requestVersion();
void requestVideoInformation();
void updateRotation(int rotation);
void updateFlip(bool flip);
/** /**
* @brief OTA, * @brief OTA,
@ -91,6 +93,8 @@ signals:
void openDoorAreaChanged(AreaWay way, const QList<QPointF> &points); void openDoorAreaChanged(AreaWay way, const QList<QPointF> &points);
void shieldedAreaChanged(bool enabled, const QList<QPointF> &points); void shieldedAreaChanged(bool enabled, const QList<QPointF> &points);
void antiClipAreaChanged(bool enabled, const QList<QPointF> &points); void antiClipAreaChanged(bool enabled, const QList<QPointF> &points);
void rotationChanged(int rotation);
void flipChanged(bool flip);
void networkInfomationChanged(const NetworkInfomation &info); void networkInfomationChanged(const NetworkInfomation &info);
void firmwareChanged(const QString &firmware); void firmwareChanged(const QString &firmware);
void otaProgressChanged(bool status, int progress, const QString &message); void otaProgressChanged(bool status, int progress, const QString &message);
@ -133,7 +137,6 @@ private:
std::queue<Task> m_requests; std::queue<Task> m_requests;
int m_timerId = -1; int m_timerId = -1;
int heartbeats = 0; int heartbeats = 0;
Area m_area;
NetworkInfomation m_networkInfomation; NetworkInfomation m_networkInfomation;
QString m_firmware; QString m_firmware;
}; };

View File

@ -16,6 +16,9 @@ Item {
property color antiClipAreaColor: "blue" property color antiClipAreaColor: "blue"
property var antiClipAreaPoints: [] property var antiClipAreaPoints: []
property bool antiClipAreaEnabled: false property bool antiClipAreaEnabled: false
property alias flip: flipSwitch.checked
property alias videoRotation: rotateComboBox.currentIndex
Item { Item {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -246,6 +249,35 @@ Item {
columns: 2 columns: 2
spacing: 10 spacing: 10
verticalItemAlignment: Qt.AlignVCenter verticalItemAlignment: Qt.AlignVCenter
Label { text: qsTr("图像: ") }
Row {
enabled: root.enabled
Label {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("旋转")
}
Item {width: 10; height:10}
ComboBox {
id: rotateComboBox
model: ["0°","90°","180°","270°"]
onCurrentIndexChanged: {
App.currentDeviceRotation = rotateComboBox.currentIndex
}
}
Item {width: 70; height:10}
Label {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("翻转")
}
Item {width: 10; height:10}
Switch {
id: flipSwitch
onToggled: App.currentDeviceFlip=flipSwitch.checked
}
}
Label { Label {
text: qsTr("开门区域: ") text: qsTr("开门区域: ")
} }

View File

@ -119,6 +119,8 @@ ApplicationWindow {
shieldedAreaPoints: App.currentShieldedAreaPoints shieldedAreaPoints: App.currentShieldedAreaPoints
antiClipAreaEnabled: App.currentAntiClipAreaEnabled antiClipAreaEnabled: App.currentAntiClipAreaEnabled
antiClipAreaPoints: App.currentAntiClipAreaPoints antiClipAreaPoints: App.currentAntiClipAreaPoints
flip: App.currentDeviceFlip
videoRotation: App.currentDeviceRotation
} }
NetworkSettingPopup { NetworkSettingPopup {