One, foreword

After the whole onVIf module has most of the functions, in addition to the demo click button can be performed to obtain the result display, the final application to the video monitoring, click on the button and the system background automatic operation is different things, such as OnVIf time correction and event subscription. It would not be silly to provide buttons on the interface of the monitoring system for users to click before executing. What should be done most is to provide two switches in the system Settings, such as automatic time correction and event subscription, so that these functions can be easily opened. After it is enabled, it will be automatically processed after the monitoring system is started, such as time correction processing and subscription events for cameras one by one. In order to achieve automatic application immediately after adding cameras, it is specially changed to actively instantiate DeviceOnvif class when opening camera video picture (each camera corresponds to an instance).

The first approach is to use a timer to handle to the specified command queue, found behind bad speed control, after all, the influence of the network and the network environment, network request sometimes 100 milliseconds completes, sometimes need to 300 milliseconds, although network request has set the timeout time (the time set to 2 to 3 seconds, Guarantee requests have enough return), this time is a little big, if the request timeout to set the timer on the network, equipment quantity a lot of time is too slow, is some dozens of equipment, monitoring and control system to deal with at the same pace as the snail get on the horse, and each camera has a multiple instructions to deal with such as automatic calibration, event subscription, etc.

A mechanism that can do the fastest speed line, the answer is, of course, isn’t that what the threads are good at do, hard dry, how long the rest free msleep control, good network environment cases, 20 equipment instructions within 1 s basically completed, which can meet the needs of users, after all, after the user to open the software, There is a high probability that you don’t want to wait too long, just like you can see that all the camera time is automatically calibrated, and if you make a camera alarm, it can be reported immediately through onVIf protocol, and all the things that should be handled are handled as soon as possible.

QNetworkAccessManager class if not initially in the thread of the new, you will be prompted not in other threads, which requires in threads run function call QMetaObject: : invokeMethod to perform the corresponding processing, A universal method is to put all the work that needs to be executed in the work function, and make an iswork flag bit. At the beginning of the process, set the flag bit iswork=true, and at the end of the process, iswork=false. In run, check whether the flag bit is false. Call the work function. This avoids the error of executing other thread-like object functions in a thread.

Basic processing ideas

  • Query information about all cameras.
  • Filter the camera information to find all the ones with onvif addresses. Only the ones with onvif addresses need to be processed.
  • Finds the device class object with the current onvif address from the DeviceOnvif linked list. This method also shoulders out the new instance if no corresponding instance is found.
  • Turn the corresponding processing into a command instruction queue, identified by the ONvif address, and hand it over to the onvifThread thread class for special processing.
  • All methods are handled by corresponding methods in the instance, and corresponding methods such as time correction, event subscription, capture, and so on are called on the instance.
  • After processing, the corresponding result signal is sent out. The corresponding three parameters respectively represent onVIF address, instruction and result data (QVariant type).

3. Online documentation

Feiyangqingyun. Gitee. IO/qwidgetdemo…

Four, effect drawing

Five, core code

#include "onvifthread.h"

QScopedPointer<OnvifThread> OnvifThread::self;
OnvifThread *OnvifThread::Instance(a)
{
    if (self.isNull()) {
        static QMutex mutex;
        QMutexLocker locker(&mutex);
        if (self.isNull()) {
            self.reset(newOnvifThread); }}return self.data(a); } OnvifThread::OnvifThread(QObject *parent) : QThread(parent)
{
    stopped = false;
    working = false;
}

OnvifThread::~OnvifThread()
{
    this->stop(a);this->wait(a); }void OnvifThread::run(a)
{
    while(! stopped) {// Check if you are working
        if(! working) {// Execute asynchronously
            QMetaObject::invokeMethod(this."work");
        }

        // You can adjust the rest time
        msleep(100);
    }

    stopped = false;
    working = false;
}

void OnvifThread::stop(a)
{
    stopped = true;
}

void OnvifThread::work(a)
{
    // Set the working flag bit
    working = true;

    if (devices.count(a) >0) {
        mutex.lock(a); OnvifDevice *device = devices.takeFirst(a); QString cmd = cmds.takeFirst(a); QVariant data = datas.takeFirst(a); mutex.unlock(a); QList<QVariant> list = data.toList(a); QString url = device->getOnvifAddr(a); QString ip = OnvifHelper::getIP(url);
        if (cmd == "remove") {
            bool ok = OnvifHelper::onvifDevices.removeOne(device);
            device->deleteLater(a);qDebug() << TIMEMS << "Perform object removal" << ip << ok;
        } else if (cmd == "systemReboot") {
            QString result = device->systemReboot(a);qDebug() << TIMEMS << "Remote Restart device" << ip << result;
        } else if (cmd == "setDateTime") {
            // Set the date and time string directly, or trigger NTP synchronization
            bool ok = device->setDateTime(QDateTime::currentDateTime().toUTC());
            //bool ok = device->setDateTime(QDateTime::currentDateTime().toUTC(), true);
            qDebug() << TIMEMS << "Set device time" << ip << ok;
        } else if (cmd == "getEvent") {
            QString result = device->getEvent(a);qDebug() << TIMEMS << "Subscribe to alarm Events" << ip << result;
        } else if (cmd == "getProfile") {
            QString result = device->getProfile(a);qDebug() << TIMEMS << "Get configuration file" << ip << result;
        } else if (cmd == "snapImage") {
            QImage image = device->snapImage(device->getProfile());
            emit receiveImage(url, image);
            qDebug() << TIMEMS << "Manual photo capture"<< ip << (! image.isNull());
        } else if (cmd == "getVideoSource") {
            QString result = device->getVideoSource(a);emit receiveResult(url, cmd, result);
            qDebug() << TIMEMS << "Get video parameters" << ip << result;
        } else if (cmd == "getImageSetting") {
            int brightness, colorSaturation, contrast;
            QString result = device->getImageSetting(brightness, colorSaturation, contrast);
            QVariant data = (QList<QVariant>() << brightness << colorSaturation << contrast);
            emit receiveResult(url, cmd, data);
            qDebug() << TIMEMS << "Get image parameters" << ip << result;
        } else if (cmd == "setImageSetting") {
            int brightness = list.at(0).toInt(a);int colorSaturation = list.at(1).toInt(a);int contrast = list.at(2).toInt(a);bool ok = device->setImageSetting(brightness, colorSaturation, contrast);
            qDebug() << TIMEMS << "Set image parameters" << ip << ok;
        }
    }

    working = false;
}

void OnvifThread::append(const OnvifDeviceUser &deviceUser, const QString &cmd, const QVariant &data)
{
    mutex.lock(a);// Unbind and rebind events first
    OnvifDevice *device = OnvifHelper::getOnvifDevice(deviceUser);
    disconnect(device, SIGNAL(receiveEvent(QString, OnvifEventInfo)), this.SIGNAL(receiveEvent(QString, OnvifEventInfo)));
    connect(device, SIGNAL(receiveEvent(QString, OnvifEventInfo)), this.SIGNAL(receiveEvent(QString, OnvifEventInfo)));

    // Add to queue for processing
    devices << device;
    cmds << cmd;
    datas << data;

    mutex.unlock(a); }Copy the code