|
3 | 3 | #include <catch2/catch_all.hpp> |
4 | 4 | #include <catch2/catch_test_macros.hpp> |
5 | 5 | #include <catch2/generators/catch_generators.hpp> |
| 6 | +#include <chrono> |
6 | 7 |
|
7 | 8 | #include "depthai/capabilities/ImgFrameCapability.hpp" |
8 | 9 | #include "depthai/common/CameraBoardSocket.hpp" |
@@ -163,3 +164,111 @@ TEST_CASE("Test how default FPS is generated for a specific output") { |
163 | 164 | REQUIRE(benchmarkReport->fps == Catch::Approx(FPS_TO_SET).margin(FPS_TO_SET * 0.1)); |
164 | 165 | } |
165 | 166 | } |
| 167 | + |
| 168 | +TEST_CASE("Camera pool sizes") { |
| 169 | + auto firstDevice = dai::Device::getFirstAvailableDevice(); |
| 170 | + auto isRvc4 = std::get<1>(firstDevice).platform == X_LINK_RVC4; |
| 171 | + for(const int overrideQueueSize : (isRvc4 ? std::vector<int>{-1, 2, 17, 3, 50, 4, 5} : std::vector<int>{-1, 2, 17, 3, 4, 5})) { |
| 172 | + std::cout << "Testing num frames = " << overrideQueueSize << "\n" << std::flush; |
| 173 | + dai::Pipeline pipeline; |
| 174 | + std::map<dai::CameraBoardSocket, std::vector<std::tuple<int, int, float>>> streamsRvc4{ |
| 175 | + // Has to be (for now): |
| 176 | + // - without FpsRegulator (different fps per same sensor)(different fps on different sensors also doesn't work right now) |
| 177 | + // - without ManipResizer so size should be supported by ISP directly |
| 178 | + {dai::CameraBoardSocket::CAM_A, {{640, 480, 30.0f}, {1920, 1440, 30.0f}}}, |
| 179 | + {dai::CameraBoardSocket::CAM_B, {{640, 400, 30.0f}, {1280, 800, 30.0f}}}, |
| 180 | + {dai::CameraBoardSocket::CAM_C, {{640, 400, 30.0f}, {1280, 800, 30.0f}}}, |
| 181 | + }; |
| 182 | + // RVC2 is more RAM bound so use smaller sizes for the test |
| 183 | + std::map<dai::CameraBoardSocket, std::vector<std::tuple<int, int, float>>> streamsRvc2{ |
| 184 | + // Has to be (for now): |
| 185 | + // - not a size supported directly by ISP as then isp is passed trough and the isp pool size value is used not the outputs pool size |
| 186 | + {dai::CameraBoardSocket::CAM_A, {{300, 300, 30.0f}}}, |
| 187 | + {dai::CameraBoardSocket::CAM_B, {{300, 300, 30.0f}, {200, 200, 30.0f}}}, |
| 188 | + {dai::CameraBoardSocket::CAM_C, {{200, 200, 30.0f}}}, |
| 189 | + }; |
| 190 | + auto streams = isRvc4 ? streamsRvc4 : streamsRvc2; |
| 191 | + std::vector<std::shared_ptr<dai::MessageQueue>> outQueues; |
| 192 | + std::vector<int> outQueuesCounter; |
| 193 | + std::vector<std::shared_ptr<dai::node::Camera>> cameras; |
| 194 | + auto script = pipeline.create<dai::node::Script>(); |
| 195 | + // Default size of the pool for RVC2 is 3 and RVC4 is 7 |
| 196 | + int queueSize = overrideQueueSize == -1 ? (isRvc4 ? 7 : 3) : overrideQueueSize; |
| 197 | + for(const auto& [socket, resolutions] : streams) { |
| 198 | + auto camera = pipeline.create<dai::node::Camera>()->build(socket); |
| 199 | + camera->properties.maxSizePoolOutputs = 1 * 1024 * 1024 * 1024; // 1G size limit to only test num frames limitation |
| 200 | + if(overrideQueueSize != -1) { |
| 201 | + camera->properties.numFramesPoolOutputs = overrideQueueSize; |
| 202 | + } |
| 203 | + for(const auto& resolution : resolutions) { |
| 204 | + std::string theKey = std::to_string(outQueues.size()); |
| 205 | + std::string inputName = "in" + theKey; |
| 206 | + std::string outputName = "out" + theKey; |
| 207 | + camera->requestOutput({std::get<0>(resolution), std::get<1>(resolution)}, std::nullopt, dai::ImgResizeMode::CROP, std::get<2>(resolution)) |
| 208 | + ->link(script->inputs[inputName]); |
| 209 | + script->inputs[inputName].setBlocking(false); |
| 210 | + script->inputs[inputName].setMaxSize(1000); |
| 211 | + outQueues.push_back(script->outputs[outputName].createOutputQueue()); |
| 212 | + outQueuesCounter.push_back(0); |
| 213 | + } |
| 214 | + cameras.push_back(camera); |
| 215 | + } |
| 216 | + int timeToBlock = 20; |
| 217 | + std::string scriptContent = isRvc4 ? R"( |
| 218 | + from depthai import BenchmarkReport)" |
| 219 | + : ""; |
| 220 | + scriptContent += R"( |
| 221 | + import time |
| 222 | +
|
| 223 | + all_frames=[] |
| 224 | + max_id = )" + std::to_string(outQueues.size() - 1) |
| 225 | + + R"( |
| 226 | + start_time = time.time() |
| 227 | + while time.time() - start_time < )" |
| 228 | + + std::to_string(timeToBlock) + R"(: |
| 229 | + for idx in range(max_id + 1): |
| 230 | + the_key = str(idx) |
| 231 | + frame = node.inputs["in" + the_key].tryGet() |
| 232 | + if frame is not None: |
| 233 | + all_frames.append(frame) |
| 234 | + out = BenchmarkReport() |
| 235 | + node.outputs["out" + the_key].send(out) |
| 236 | + all_frames = [] |
| 237 | + while True: |
| 238 | + for idx in range(max_id + 1): |
| 239 | + the_key = str(idx) |
| 240 | + frame = node.inputs["in" + the_key].tryGet() |
| 241 | + if frame is not None: |
| 242 | + out = BenchmarkReport() |
| 243 | + node.outputs["out" + the_key].send(out) |
| 244 | + )"; |
| 245 | + script->setScript(scriptContent); |
| 246 | + pipeline.start(); |
| 247 | + auto startTime = std::chrono::steady_clock::now(); |
| 248 | + // Keep frames in script node and check Camera node stops sending frames after buffer limit is hit |
| 249 | + while(std::chrono::duration<double>(std::chrono::steady_clock::now() - startTime).count() < timeToBlock - 5) { |
| 250 | + for(int idx = 0; idx < outQueues.size(); ++idx) { |
| 251 | + auto frame = outQueues[idx]->tryGet(); |
| 252 | + if(frame) { |
| 253 | + ++outQueuesCounter[idx]; |
| 254 | + } |
| 255 | + } |
| 256 | + } |
| 257 | + std::cout << "Got the first part frames\n" << std::flush; |
| 258 | + for(const auto& count : outQueuesCounter) { |
| 259 | + REQUIRE(count == queueSize); |
| 260 | + } |
| 261 | + // Check stream still works after script node unblocks the Camera node |
| 262 | + while(std::chrono::duration<double>(std::chrono::steady_clock::now() - startTime).count() < timeToBlock + 30) { |
| 263 | + for(int idx = 0; idx < outQueues.size(); ++idx) { |
| 264 | + auto frame = outQueues[idx]->tryGet(); |
| 265 | + if(frame) { |
| 266 | + ++outQueuesCounter[idx]; |
| 267 | + } |
| 268 | + } |
| 269 | + } |
| 270 | + for(const auto& count : outQueuesCounter) { |
| 271 | + REQUIRE(count > queueSize + 200); |
| 272 | + } |
| 273 | + } |
| 274 | +} |
0 commit comments