nx_metadata_sdk 1.0 Metadata SDK

device_agent.h
1 // Copyright 2018-present Network Optix, Inc. Licensed under MPL 2.0: www.mozilla.org/MPL/2.0/
2
3 #pragma once
4
5 #include <thread>
6 #include <atomic>
7 #include <memory>
8 #include <condition_variable>
9 #include <vector>
10 #include <string>
11 #include <deque>
12
13 #include <nx/sdk/analytics/helpers/video_frame_processing_device_agent.h>
14 #include <nx/sdk/analytics/helpers/pixel_format.h>
15
16 #include "engine.h"
17 #include "objects/random.h"
18
19 namespace nx {
20 namespace vms_server_plugins {
21 namespace analytics {
22 namespace stub {
23
24 class DeviceAgent: public nx::sdk::analytics::VideoFrameProcessingDeviceAgent
25 {
26 public:
27 DeviceAgent(Engine* engine, const nx::sdk::IDeviceInfo* deviceInfo);
28 virtual ~DeviceAgent() override;
29
30 protected:
31 virtual void getPluginSideSettings(
32 nx::sdk::Result<const nx::sdk::ISettingsResponse*>* outResult) const override;
33
34 virtual void doSetNeededMetadataTypes(
35 nx::sdk::Result<void>* outValue,
36 const nx::sdk::analytics::IMetadataTypes* neededMetadataTypes) override;
37
38 virtual std::string manifestString() const override;
39
40 virtual nx::sdk::Result<const nx::sdk::IStringMap*> settingsReceived() override;
41
42 virtual bool pushCompressedVideoFrame(
43 const nx::sdk::analytics::ICompressedVideoPacket* videoFrame) override;
44
45 virtual bool pushUncompressedVideoFrame(
46 const nx::sdk::analytics::IUncompressedVideoFrame* videoFrame) override;
47
48 virtual bool pullMetadataPackets(
49 std::vector<nx::sdk::analytics::IMetadataPacket*>* metadataPackets) override;
50
51 private:
52 nx::sdk::analytics::IMetadataPacket* cookSomeEvents();
53 std::vector<nx::sdk::analytics::IMetadataPacket*> cookSomeObjects();
54
55 int64_t usSinceEpoch() const;
56
57 void processVideoFrame(const nx::sdk::analytics::IDataPacket* videoFrame, const char* func);
58
59 bool checkVideoFrame(const nx::sdk::analytics::IUncompressedVideoFrame* frame) const;
60
61 bool checkVideoFramePlane(
62 const nx::sdk::analytics::IUncompressedVideoFrame* frame,
63 const nx::sdk::analytics::PixelFormatDescriptor* pixelFormatDescriptor,
64 int plane) const;
65
66 void dumpSomeFrameBytes(
67 const nx::sdk::analytics::IUncompressedVideoFrame* frame,
68 int plane) const;
69
70 void startFetchingMetadata(const nx::sdk::analytics::IMetadataTypes* metadataTypes);
71
72 void stopFetchingMetadata();
73
74 void processEvents();
75
76 void processPluginDiagnosticEvents();
77
78 void setObjectCount(int objectCount);
79
80 void cleanUpTimestampQueue();
81
82 void parseSettings();
83
84 template<typename ObjectType>
85 void setIsObjectTypeGenerationNeeded(bool isObjectTypeGenerationNeeded)
86 {
87 if (isObjectTypeGenerationNeeded)
88 {
89 m_objectGenerator.registerObjectFactory<ObjectType>(
90 []() { return std::make_unique<ObjectType>(); });
91 }
92 else
93 {
94 m_objectGenerator.unregisterObjectFactory<ObjectType>();
95 }
96 }
97
98 void updateObjectGenerationParameters();
99
100 void updateEventGenerationParameters();
101
102 private:
103 Engine* const m_engine;
104
105 std::atomic<bool> m_terminated{false};
106
107 std::unique_ptr<std::thread> m_pluginDiagnosticEventThread;
108 std::mutex m_pluginDiagnosticEventGenerationLoopMutex;
109 std::condition_variable m_pluginDiagnosticEventGenerationLoopCondition;
110 std::atomic<bool> m_needToThrowPluginDiagnosticEvents{false};
111
112 std::unique_ptr<std::thread> m_eventThread;
113 std::mutex m_eventGenerationLoopMutex;
114 std::condition_variable m_eventGenerationLoopCondition;
115 std::atomic<bool> m_eventsNeeded{false};
116
117 int m_frameCounter = 0;
118 std::string m_eventTypeId;
119
120 std::deque<int64_t> m_frameTimestampQueue;
121 int64_t m_lastVideoFrameTimestampUs = 0;
122
123 struct DeviceAgentSettings
124 {
125 bool needToGenerateObjects()
126 {
127 return generateCars
128 || generateTrucks
129 || generatePedestrians
130 || generateHumanFaces
131 || generateBicycles;
132 }
133
134 std::atomic<bool> generateEvents{true};
135
136 std::atomic<bool> generateCars{true};
137 std::atomic<bool> generateTrucks{true};
138 std::atomic<bool> generatePedestrians{true};
139 std::atomic<bool> generateHumanFaces{true};
140 std::atomic<bool> generateBicycles{true};
141
142 std::atomic<int> generateObjectsEveryNFrames{1};
143 std::atomic<int> numberOfObjectsToGenerate{1};
144
145 std::atomic<bool> generatePreviews{true};
146
147 std::atomic<bool> throwPluginDiagnosticEvents{false};
148 std::atomic<bool> leakFrames{false};
149
150 std::atomic<std::chrono::milliseconds> additionalFrameProcessingDelay{
151 std::chrono::milliseconds::zero()};
152
153 std::atomic<std::chrono::milliseconds> overallMetadataDelay{
154 std::chrono::milliseconds::zero()};
155
156 std::atomic<int> numberOfFramesBeforePreviewGeneration{30};
157 };
158
159 DeviceAgentSettings m_deviceAgentSettings;
160
161 struct EventContext
162 {
163 int currentEventTypeIndex = 0;
164 bool isCurrentEventActive = false;
165 };
166
167 EventContext m_eventContext;
168
169 struct ObjectContext
170 {
171 ObjectContext() = default;
172 ObjectContext(std::unique_ptr<AbstractObject> object): object(std::move(object)) {}
173
174 ObjectContext& operator=(std::unique_ptr<AbstractObject>&& otherObject)
175 {
176 reset();
177 object = std::move(otherObject);
178 return *this;
179 }
180
181 void reset()
182 {
183 object.reset();
184 isPreviewGenerated = false;
185 frameCounter = 0;
186 }
187
188 bool operator!() const { return !object; }
189
190 std::unique_ptr<AbstractObject> object;
191 bool isPreviewGenerated = false;
192 int frameCounter = 0;
193 };
194
195 std::mutex m_objectGenerationMutex;
196 RandomObjectGenerator m_objectGenerator;
197 std::vector<ObjectContext> m_objectContexts;
198 };
199
200 const std::string kLineCrossingEventType = "nx.stub.lineCrossing";
201 const std::string kObjectInTheAreaEventType = "nx.stub.objectInTheArea";
202 const std::string kLoiteringEventType = "nx.stub.loitering";
203 const std::string kIntrusionEventType = "nx.stub.intrusion";
204 const std::string kGunshotEventType = "nx.stub.gunshot";
205 const std::string kSuspiciousNoiseEventType = "nx.stub.suspiciousNoise";
206 const std::string kSoundRelatedEventGroup = "nx.stub.soundRelatedEvent";
207
208 } // namespace stub
209 } // namespace analytics
210 } // namespace vms_server_plugins
211 } // namespace nx
nx::vms_server_plugins::analytics::stub::DeviceAgent::pushCompressedVideoFrame
virtual bool pushCompressedVideoFrame(const nx::sdk::analytics::ICompressedVideoPacket *videoFrame) override
Definition: device_agent.cpp:225
nx::vms_server_plugins::analytics::stub::DeviceAgent::settingsReceived
virtual nx::sdk::Result< const nx::sdk::IStringMap * > settingsReceived() override
Definition: device_agent.cpp:181
nx::vms_server_plugins::analytics::stub::RandomObjectGenerator
Definition: random.h:25
nx::sdk::analytics::IMetadataPacket
Definition: i_metadata_packet.h:16
nx::vms_server_plugins::analytics::stub::DeviceAgent::pushUncompressedVideoFrame
virtual bool pushUncompressedVideoFrame(const nx::sdk::analytics::IUncompressedVideoFrame *videoFrame) override
Definition: device_agent.cpp:237
nx::sdk::analytics::ICompressedVideoPacket
Definition: i_compressed_video_packet.h:16
nx::vms_server_plugins::analytics::stub::DeviceAgent::manifestString
virtual std::string manifestString() const override
Definition: device_agent.cpp:135
nx::sdk::analytics::IMetadataTypes
Definition: i_metadata_types.h:13
nx::sdk::Result< void >
Definition: result.h:81
nx::sdk::IDeviceInfo
Definition: i_device_info.h:14
nx::vms_server_plugins::analytics::stub::Engine
Definition: engine.h:21
nx::sdk::Result
Definition: result.h:47
nx
Definition: apple_utils.h:6
nx::sdk::analytics::VideoFrameProcessingDeviceAgent
Definition: video_frame_processing_device_agent.h:37
nx::sdk::analytics::PixelFormatDescriptor
Definition: pixel_format.h:26
nx::sdk::analytics::IUncompressedVideoFrame
Definition: i_uncompressed_video_frame.h:13
nx::sdk::analytics::IDataPacket
Definition: i_data_packet.h:16
nx::vms_server_plugins::analytics::stub::DeviceAgent
Definition: device_agent.h:24