@@ -143,3 +143,66 @@ void SimpleCaptureBalanced::requestComplete(Request *request)
if (queueRequest(request))
loop_->exit(-EINVAL);
}
+
+/* SimpleCaptureUnbalanced */
+
+SimpleCaptureUnbalanced::SimpleCaptureUnbalanced(std::shared_ptr<Camera> camera)
+ : SimpleCapture(camera)
+{
+}
+
+Results::Result SimpleCaptureUnbalanced::capture(unsigned int numRequests)
+{
+ Results::Result ret = start();
+ if (ret.first != Results::Pass)
+ return ret;
+
+ Stream *stream = config_->at(0).stream();
+ const std::vector<std::unique_ptr<FrameBuffer>> &buffers = allocator_->buffers(stream);
+
+ captureCount_ = 0;
+ captureLimit_ = numRequests;
+
+ /* Queue the recommended number of reqeuests. */
+ std::vector<std::unique_ptr<libcamera::Request>> requests;
+ for (const std::unique_ptr<FrameBuffer> &buffer : buffers) {
+ std::unique_ptr<Request> request = camera_->createRequest();
+ if (!request) {
+ stop();
+ return { Results::Fail, "Can't create request" };
+ }
+
+ if (request->addBuffer(stream, buffer.get())) {
+ stop();
+ return { Results::Fail, "Can't set buffer for request" };
+ }
+
+ if (camera_->queueRequest(request.get()) < 0) {
+ stop();
+ return { Results::Fail, "Failed to queue request" };
+ }
+
+ requests.push_back(std::move(request));
+ }
+
+ /* Run capture session. */
+ loop_ = new EventLoop();
+ int status = loop_->exec();
+ stop();
+ delete loop_;
+
+ return { status ? Results::Fail : Results::Pass, "Unbalanced capture of " + std::to_string(numRequests) + " requests" };
+}
+
+void SimpleCaptureUnbalanced::requestComplete(Request *request)
+{
+ captureCount_++;
+ if (captureCount_ >= captureLimit_) {
+ loop_->exit(0);
+ return;
+ }
+
+ request->reuse(Request::ReuseBuffers);
+ if (camera_->queueRequest(request))
+ loop_->exit(-EINVAL);
+}
@@ -51,4 +51,18 @@ private:
unsigned int captureLimit_;
};
+class SimpleCaptureUnbalanced : public SimpleCapture
+{
+public:
+ SimpleCaptureUnbalanced(std::shared_ptr<libcamera::Camera> camera);
+
+ Results::Result capture(unsigned int numRequests);
+
+private:
+ void requestComplete(libcamera::Request *request) override;
+
+ unsigned int captureCount_;
+ unsigned int captureLimit_;
+};
+
#endif /* __LC_COMPLIANCE_SIMPLE_CAPTURE_H__ */
@@ -31,6 +31,18 @@ Results::Result testRequestBalance(std::shared_ptr<Camera> camera,
return { Results::Pass, "Balanced capture of " + std::to_string(numRequests) + " requests with " + std::to_string(startCycles) + " start cycles" };
}
+Results::Result testRequestUnbalance(std::shared_ptr<Camera> camera,
+ StreamRole role, unsigned int numRequests)
+{
+ SimpleCaptureUnbalanced capture(camera);
+
+ Results::Result ret = capture.configure(role);
+ if (ret.first != Results::Pass)
+ return ret;
+
+ return capture.capture(numRequests);
+}
+
Results testSingleStream(std::shared_ptr<Camera> camera)
{
const std::vector<std::pair<std::string, StreamRole>> roles = {
@@ -69,6 +81,17 @@ Results testSingleStream(std::shared_ptr<Camera> camera)
std::cout << "* Test multiple start/stop cycles" << std::endl;
for (unsigned int num : numRequests)
results.add(testRequestBalance(camera, role.second, 3, num));
+
+ /*
+ * Test unbalanced stop
+ *
+ * Makes sure the camera supports a stop with requests queued.
+ * Example failure is a camera that does not handle cancelation
+ * of buffers coming back from the video device while stopping.
+ */
+ std::cout << "* Test unbalanced stop" << std::endl;
+ for (unsigned int num : numRequests)
+ results.add(testRequestUnbalance(camera, role.second, num));
}
return results;
Add a test which stops a camera while requests are still queued. This intents to test cleanup paths where requests are dequeued from video devices in an uncompleted state. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> --- src/lc-compliance/simple_capture.cpp | 63 ++++++++++++++++++++++++++++ src/lc-compliance/simple_capture.h | 14 +++++++ src/lc-compliance/single_stream.cpp | 23 ++++++++++ 3 files changed, 100 insertions(+)