1, Foreword
After a lapse of more than a year, the onvif kernel of the video surveillance system is rewritten again. On the one hand, it is compatible with Qt6, on the other hand, it is classified according to function to improve efficiency. The overall logical idea is the same. The main change is that Qt6 no longer supports the QtXmlPatterns module (in fact, this module is gradually prompted as an abandoned module in later versions of Qt5). The data in onvif protocol communication are xml data with namespace. It is most appropriate to use the QtXmlPatterns module to parse, Now it's all changed to use the most original and basic QtXml module to analyze. After all, QtXml module must be there all the time. It's a fairly basic module. There will be Qt7 or Qt100 in the future.
Previously, the PTZ control has realized relative and absolute movement. Later, after testing the cameras of dozens of manufacturers, it is found that some camera manufacturers do not fully support the onvif protocol and get through some protocols. For example, the PTZ control only supports continuous movement. In fact, most of the real scenes need continuous movement, which looks very smooth, In the past, when the continuous movement command was not implemented, the PTZ control used relative movement by default. In order to achieve the effect of continuous movement, a timer was set up to continuously execute the command to simulate continuous movement. The effect is not very ideal. It looks strange. Sometimes it pauses. Recently, it was found that there was a continuous movement command, which is comfortable. The wire slides to burst, Press the corresponding azimuth to trigger continuous movement and release the automatic stop.
Main functions of onvif
- Search for equipment and obtain equipment information, such as manufacturer, model, etc.
- Get multiple profile information of the device.
- Obtain the video stream address rtsp, resolution and other parameters of the corresponding configuration file.
- Pan tilt control, moving up, down, left and right, zoom in and out, relative and absolute movement.
- Obtain the preset bit information and trigger the preset bit.
- Subscribe to events and receive various messages from the device, especially alarm events, such as the alarm of IO port.
- Capture the current picture of the device.
- Obtain, create and delete user information.
- Obtain device and network configuration information, such as IP address, etc.
- Gets and sets NTP time synchronization.
- Gets and sets the device time.
- Restart the device.
Processing flow of onvif
- Bind multicast IP (239.255.255.250) and port (3702) to send data search equipment in fixed xml format.
- Parse the received data in xml format to get the Onvif address of the device.
- Send the corresponding data to the Onvif address, and take out the corresponding node data after receiving the data.
- Request the Onvif address to obtain the Media address and Ptz address. The Media address is used to obtain the detailed configuration file, and the Ptz address is used for Ptz control.
- PTZ control is to send corresponding data to PTZ address.
- If user authentication is set, the user token information needs to be sent together, and authentication processing needs to be performed every time.
- The received data is not standard xml data and cannot be processed according to normal node parsing. It can only be done with QXmlQuery.
- The data returned by the equipment of each manufacturer may not be completely consistent, but they are basically inconsistent. It is necessary to fuzzy search the node value.
- The underlying protocol resolution is specially adopted, because soap is too bulky, the function name is too alternative, and it is deliberately lightweight.
- Two necessary tools, Onvif Device Manager and Onvif Device Test Tool.
2, Functional features
(1) Software module
- Video monitoring module, various docking small window sub modules, including equipment list, graphic alarm, window information, PTZ control, preset position, cruise setting, equipment control, suspension map, web browsing, etc.
- Video playback module, including local playback, remote playback, device playback, picture playback, video upload, etc.
- Electronic map module, including picture map, online map, offline map, path planning, etc.
- Log query module, including local log, device log, etc.
- System setting module, including system setting (basic setting, video parameters, database setting, map configuration, serial port configuration, etc.), VCR management, camera management, polling configuration, user management, etc.
(2) Basic functions
- Support various video streams (rtsp, rtmp, http, etc.), video files (mp4, rmvb, avi, etc.) and local USB camera playback.
- Support multi screen switching, including 1, 4, 6, 8, 9, 13, 16, 25, 36 and 64 screen switching.
- Full screen switching is supported, including right-click menu, toolbar button and shortcut key (alt+enter full screen, esc exit full screen).
- Support video polling, including 1, 4, 9 and 16 picture polling, and set polling packet (polling plan), polling interval, code stream type, etc.
- Support onvif protocol, including device search, PTZ control and device control (picture parameters, proofreading time, system restart, capturing pictures, etc.).
- Permission management is supported. Different users can correspond to different module permissions, such as deleting logs, shutting down the system, etc.
- The database supports a variety of, including sqlite, mysql, sqlserver, postgresql, oracle, NPC gold warehouse, etc.
- The local USB camera supports setting parameters such as resolution and frame rate.
- All docking modules automatically generate corresponding menus to control display and hiding. Right click in the title bar to pop up.
- It supports displaying all modules, hiding all modules, resetting normal layout and resetting full screen layout.
- Double click the device to pop up the real-time preview video, which supports picture map, online map, offline map, etc.
- Drag the camera node to the corresponding window to play video, and drag local files to play directly.
- To delete a video, you can right-click to delete it, close the hoverbar to delete it, and drag it outside the video monitoring panel to delete it.
- The device button on the picture map can be dragged freely to automatically save the location information. Baidu map can click to obtain longitude and latitude information to update the device location.
- Any channel in the video monitoring panel form supports drag switching and instant response.
- It encapsulates Baidu map, view switching, motion track, equipment point position, mouse click to obtain longitude and latitude, etc.
- Double click the node, drag the node, drag the window to exchange positions and other operations will automatically update and save the last playback address, and the software will open the automatic application next time.
- The volume bar control in the lower right corner is automatically hidden when the focus is lost, and the volume bar has a mute icon.
- Support video screenshots. You can specify a single or all channel screenshots. There is also a screenshot button on the small toolbar at the bottom.
- Support timeout automatic hiding of mouse pointer and automatic full screen mechanism.
- It supports onvif PTZ control and can move PTZ cameras up, down, left and right, including reset and focal length adjustment.
- Support any onvif camera, including but not limited to Haikang, Dahua, Yushi, Tiandi Weiye, Huawei, etc.
- Video can be saved, with options of regular storage or single file storage, and optional storage interval.
- The video stream communication mode tcp+udp can be set, and the video decoding modes such as speed priority, quality priority and equalization can be set.
- The Chinese name, English name, LOGO icon, etc. of the software can be set.
- The stored video files can be exported to the specified directory and uploaded to the server in batches.
(3) Characteristic function
- The main interface adopts docked form mode, and various components are added in the form of small modules, which can be added by any module.
- The docking module can drag any position to embed and suspend, and supports maximizing the full screen and multi screen.
- Dual layout file storage mechanism. The normal mode and full screen mode correspond to different layout schemes and are automatically switched and saved. For example, the full screen mode can highlight several modules and display them transparently in the specified position, which is more sci-fi and modern.
- The original onvif protocol mechanism adopts the underlying protocol parsing (udp broadcast search + http request execution command), which is lighter, easy to understand, easy to learn and expand, and does not rely on any third-party components, such as gsoap.
- The original data import and export mechanism can export data instantly without relying on any components across platforms.
- Built in multiple original components, the universe is super valuable, including data import and export components (export to xls, pdf, printing), database components (database management thread, automatic data cleaning thread, universal paging, data request, etc.), map components, video monitoring components, file multithreading transceiver components, onvif communication components, general browser kernel components, etc.
- Custom information box + error box + query box + prompt box in the lower right corner (including multiple formats), etc.
- Exquisite skin change, up to 17 sets of skin styles can be changed at will, and all styles are unified, including menu, etc.
- Multiple buttons can be added to the video control suspension bar, and buttons can also be added to the small toolbar at the bottom of the monitoring interface.
- Double click the camera node to automatically play videos. Double click the node to automatically add videos one by one. You will automatically skip to the next node. Double click the parent node to automatically add all videos under the node. Main code stream and sub code stream can be selected.
- For video recorder management and camera management, you can add, delete, modify, import and export printing information, and immediately apply the new equipment information to generate a tree list without restarting.
- A variety of cores can be freely switched. ffmpeg, vlc, mpv, etc. can be set in pro. ffmpeg is recommended, with the most cross platforms. The libraries compiled on linux and mac platforms are provided by default.
- Hard decoding is supported, and hard decoding types (qsv, dxva2, d3d11va, etc.) can be set.
- opengl is used to draw video by default, with ultra-low CPU resource occupation. It supports yuyv and nv12 formats, which is very awesome.
- Highly customizable, users can easily derive their own functions on this basis, such as adding custom modules, adding operation modes, robot monitoring, UAV monitoring, excavator monitoring, etc.
- Support xp, win7, win10, linux, mac, various domestic systems (UOS, bid winning Kirin, Galaxy Kirin, etc.), embedded linux and other systems.
- Complete notes, clear project structure, super detailed and complete use and development manual, accurate to the functional description of each code file, and continuously iterative versions.
3, Experience address
- Experience address: https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g Extraction code: 01jf file name: bin_video_system.zip.
- Domestic sites: https://gitee.com/feiyangqingyun
- International sites: https://github.com/feiyangqingyun
- Personal homepage: https://blog.csdn.net/feiyangqingyun
- Zhihu homepage: https://www.zhihu.com/people/feiyangqingyun/
4, Renderings
5, Core code
#include "frmipcptz.h" #include "ui_frmipcptz.h" #include "quihelper.h" #include "devicehelper.h" #include "deviceonvif.h" frmIpcPtz::frmIpcPtz(QWidget *parent) : QWidget(parent), ui(new Ui::frmIpcPtz) { ui->setupUi(this); this->initForm(); this->initIcon(); } frmIpcPtz::~frmIpcPtz() { delete ui; } bool frmIpcPtz::eventFilter(QObject *watched, QEvent *event) { //Press the mouse to specify that the release will stop automatically if (event->type() == QEvent::MouseButtonPress) { int type = 255; if (watched == ui->btnPtzZoomIn) { type = 9; } else if (watched == ui->btnPtzZoomOut) { type = 10; } else if (watched == ui->btnPtzFocusIn) { type = 11; } else if (watched == ui->btnPtzFocusOut) { type = 12; } else if (watched == ui->btnPtzApertureIn) { type = 13; } else if (watched == ui->btnPtzApertureOut) { type = 14; } QMetaObject::invokeMethod(this, "ptzControl", Qt::QueuedConnection, Q_ARG(int, type)); } else if (event->type() == QEvent::MouseButtonRelease) { QMetaObject::invokeMethod(this, "ptzControl", Qt::QueuedConnection, Q_ARG(int, 255)); } return QWidget::eventFilter(watched, event); } void frmIpcPtz::initForm() { //Install event filter recognition release automatic stop ui->btnPtzZoomIn->installEventFilter(this); ui->btnPtzZoomOut->installEventFilter(this); //Bind PTZ instrument panel press and release events ui->gaugeCloud->setAutoRepeat(false); connect(ui->gaugeCloud, SIGNAL(mousePressed(int, QString)), this, SLOT(mousePressed(int, QString))); connect(ui->gaugeCloud, SIGNAL(mouseReleased(int, QString)), this, SLOT(mouseReleased(int, QString))); //Associated style change signal auto reset Icon connect(AppEvent::Instance(), SIGNAL(changeStyle()), this, SLOT(initIcon())); } void frmIpcPtz::initIcon() { //Set graphic font int fontSize = 15; IconHelper::setIcon(ui->btnPtzZoomIn, 0xf067, fontSize); IconHelper::setIcon(ui->btnPtzZoomOut, 0xf068, fontSize); IconHelper::setIcon(ui->btnPtzFocusIn, 0xf067, fontSize); IconHelper::setIcon(ui->btnPtzFocusOut, 0xf068, fontSize); IconHelper::setIcon(ui->btnPtzApertureIn, 0xf067, fontSize); IconHelper::setIcon(ui->btnPtzApertureOut, 0xf068, fontSize); } void frmIpcPtz::mousePressed(int position, const QString &strPosition) { DeviceHelper::addMsg(QString("Press PTZ %1").arg(strPosition)); QMetaObject::invokeMethod(this, "ptzControl", Qt::QueuedConnection, Q_ARG(int, position)); } void frmIpcPtz::mouseReleased(int position, const QString &strPosition) { DeviceHelper::addMsg(QString("Loosen the pan tilt %1").arg(strPosition)); QMetaObject::invokeMethod(this, "ptzControl", Qt::QueuedConnection, Q_ARG(int, 255)); } void frmIpcPtz::ptzControl(int position) { //Calculate speed, convert to decimal double step = (double)ui->sliderPtzStep->value() / 10; //Send PTZ control command according to different parts pressed //1. The range of X, y and z is between 0-1. //2. x is a negative number, indicating left turn, and x is a positive number, indicating right turn. //3. y is a negative number, indicating downward rotation, and y is a positive number, indicating upward rotation. //4. z is a positive number, which means closer, and z is a negative number, which means farther. //5. Realize PTZ control through the combination of x and y. //6. Focus control is realized through the combination of z. //0-8 indicates bottom / lower left corner / left / upper left corner / top / upper right corner / right / lower right corner / middle in turn if (position == 0) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, 0.0, -step, 0.0); } else if (position == 1) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, -step, -step, 0.0); } else if (position == 2) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, -step, 0.0, 0.0); } else if (position == 3) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, -step, step, 0.0); } else if (position == 4) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, 0.0, step, 0.0); } else if (position == 5) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, step, step, 0.0); } else if (position == 6) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, step, 0.0, 0.0); } else if (position == 7) { DeviceOnvif::ptzControl(3, AppData::CurrentUrl, step, -step, 0.0); } else if (position == 8) { //Stop before reset DeviceOnvif::ptzControl(0, AppData::CurrentUrl, 0.0, 0.0, 0.0); //DeviceOnvif::ptzControl(1, AppData::CurrentUrl, 0.0, 0.0, 0.0); } else if (position == 9) { //Zoom+ DeviceOnvif::ptzControl(3, AppData::CurrentUrl, 0.0, 0.0, step); } else if (position == 10) { //Zoom- DeviceOnvif::ptzControl(3, AppData::CurrentUrl, 0.0, 0.0, -step); } else if (position == 11) { //Zoom+ } else if (position == 12) { //Zoom- } else if (position == 13) { //Aperture+ } else if (position == 14) { //Aperture- } else { //stop it DeviceOnvif::ptzControl(0, AppData::CurrentUrl, 0.0, 0.0, 0.0); } }