[libcamera-devel] [PATCH v2] libcamera, android, cam, gstreamer, qcam, v4l2: Reuse Request
Paul Elder
paul.elder at ideasonboard.com
Tue Sep 29 11:52:00 CEST 2020
Allow reuse of the Request object by implementing a reset() function.
This means that the applications now have the responsibility of freeing
the Request objects, so make all libcamera users (cam, qcam,
v4l2-compat, gstreamer, android) do so.
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
Changes in v2:
- clear controls_ and metadata_ and validator_ in Request::reset()
- use unique_ptr on application side, prior to queueRequest, and use
regular pointer for completion handler
- make qcam's reuse request nicer
- update Camera::queueRequest() and Camera::createRequest() documentation
- add documentation for Request::reset()
- make v4l2-compat reuse request
- make gstreamer and android use the new createRequest API, though they
do not actually reuse the requests
- I haven't yet tested android
---
include/libcamera/camera.h | 2 +-
include/libcamera/request.h | 2 ++
src/android/camera_device.cpp | 8 +++++-
src/cam/capture.cpp | 19 ++++++------
src/cam/capture.h | 3 ++
src/gstreamer/gstlibcamerasrc.cpp | 6 ++--
src/libcamera/camera.cpp | 15 ++++------
src/libcamera/request.cpp | 24 ++++++++++++++++
src/qcam/main_window.cpp | 48 +++++++++++++++++++------------
src/qcam/main_window.h | 26 +++++------------
src/v4l2/v4l2_camera.cpp | 38 +++++++++++++++++-------
src/v4l2/v4l2_camera.h | 4 ++-
test/camera/buffer_import.cpp | 15 +++++-----
test/camera/capture.cpp | 15 +++++-----
test/camera/statemachine.cpp | 9 ++----
15 files changed, 141 insertions(+), 93 deletions(-)
diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 272c12c3..e4036b63 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -93,7 +93,7 @@ public:
std::unique_ptr<CameraConfiguration> generateConfiguration(const StreamRoles &roles = {});
int configure(CameraConfiguration *config);
- Request *createRequest(uint64_t cookie = 0);
+ std::unique_ptr<Request> createRequest(uint64_t cookie = 0);
int queueRequest(Request *request);
int start();
diff --git a/include/libcamera/request.h b/include/libcamera/request.h
index 5976ac50..9f615a24 100644
--- a/include/libcamera/request.h
+++ b/include/libcamera/request.h
@@ -38,6 +38,8 @@ public:
Request &operator=(const Request &) = delete;
~Request();
+ void reset();
+
ControlList &controls() { return *controls_; }
ControlList &metadata() { return *metadata_; }
const BufferMap &buffers() const { return bufferMap_; }
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index 70d77a17..7f288617 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -1395,8 +1395,13 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
new Camera3RequestDescriptor(camera3Request->frame_number,
camera3Request->num_output_buffers);
- Request *request =
+ std::unique_ptr<Request> r =
camera_->createRequest(reinterpret_cast<uint64_t>(descriptor));
+ Request *request = r.release();
+ if (!request) {
+ LOG(HAL, Error) << "Failed to create request";
+ return -ENOMEM;
+ }
for (unsigned int i = 0; i < descriptor->numBuffers; ++i) {
CameraStream *cameraStream =
@@ -1593,6 +1598,7 @@ void CameraDevice::requestComplete(Request *request)
callbacks_->process_capture_result(callbacks_, &captureResult);
delete descriptor;
+ delete request;
}
std::string CameraDevice::logPrefix() const
diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp
index 5510c009..5b9238e2 100644
--- a/src/cam/capture.cpp
+++ b/src/cam/capture.cpp
@@ -65,6 +65,8 @@ int Capture::run(const OptionsParser::Options &options)
writer_ = nullptr;
}
+ requests_.clear();
+
delete allocator;
return ret;
@@ -92,9 +94,8 @@ int Capture::capture(FrameBufferAllocator *allocator)
* example pushing a button. For now run all streams all the time.
*/
- std::vector<Request *> requests;
for (unsigned int i = 0; i < nbuffers; i++) {
- Request *request = camera_->createRequest();
+ std::unique_ptr<Request> request = camera_->createRequest();
if (!request) {
std::cerr << "Can't create request" << std::endl;
return -ENOMEM;
@@ -117,7 +118,7 @@ int Capture::capture(FrameBufferAllocator *allocator)
writer_->mapBuffer(buffer.get());
}
- requests.push_back(request);
+ requests_.push_back(std::move(request));
}
ret = camera_->start();
@@ -126,8 +127,8 @@ int Capture::capture(FrameBufferAllocator *allocator)
return ret;
}
- for (Request *request : requests) {
- ret = camera_->queueRequest(request);
+ for (std::unique_ptr<Request> &request : requests_) {
+ ret = camera_->queueRequest(request.get());
if (ret < 0) {
std::cerr << "Can't queue request" << std::endl;
camera_->stop();
@@ -156,7 +157,7 @@ void Capture::requestComplete(Request *request)
if (request->status() == Request::RequestCancelled)
return;
- const Request::BufferMap &buffers = request->buffers();
+ const Request::BufferMap buffers = request->buffers();
/*
* Compute the frame rate. The timestamp is arbitrarily retrieved from
@@ -206,11 +207,7 @@ void Capture::requestComplete(Request *request)
* Create a new request and populate it with one buffer for each
* stream.
*/
- request = camera_->createRequest();
- if (!request) {
- std::cerr << "Can't create request" << std::endl;
- return;
- }
+ request->reset();
for (auto it = buffers.begin(); it != buffers.end(); ++it) {
const Stream *stream = it->first;
diff --git a/src/cam/capture.h b/src/cam/capture.h
index 0aebdac9..45e5e8a9 100644
--- a/src/cam/capture.h
+++ b/src/cam/capture.h
@@ -9,6 +9,7 @@
#include <memory>
#include <stdint.h>
+#include <vector>
#include <libcamera/buffer.h>
#include <libcamera/camera.h>
@@ -43,6 +44,8 @@ private:
EventLoop *loop_;
unsigned int captureCount_;
unsigned int captureLimit_;
+
+ std::vector<std::unique_ptr<libcamera::Request>> requests_;
};
#endif /* __CAM_CAPTURE_H__ */
diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index 1bfc2e2f..ca223df6 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -74,6 +74,8 @@ RequestWrap::~RequestWrap()
if (item.second)
gst_buffer_unref(item.second);
}
+
+ delete request_;
}
void RequestWrap::attachBuffer(GstBuffer *buffer)
@@ -266,7 +268,8 @@ gst_libcamera_src_task_run(gpointer user_data)
GstLibcameraSrc *self = GST_LIBCAMERA_SRC(user_data);
GstLibcameraSrcState *state = self->state;
- Request *request = state->cam_->createRequest();
+ std::unique_ptr<Request> request_unique = state->cam_->createRequest();
+ Request *request = request_unique.release();
auto wrap = std::make_unique<RequestWrap>(request);
for (GstPad *srcpad : state->srcpads_) {
GstLibcameraPool *pool = gst_libcamera_pad_get_pool(srcpad);
@@ -281,7 +284,6 @@ gst_libcamera_src_task_run(gpointer user_data)
* queueing this one due to lack of buffers.
*/
delete request;
- request = nullptr;
break;
}
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index ae16a64a..8c2bbc76 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -833,21 +833,23 @@ int Camera::configure(CameraConfiguration *config)
* handler, and is completely opaque to libcamera.
*
* The ownership of the returned request is passed to the caller, which is
- * responsible for either queueing the request or deleting it.
+ * responsible for either queueing the request or deleting it. The caller
+ * continues to own the request after queueing it, so deleting the request
+ * is the responsibility of the application after the request completes.
*
* \context This function is \threadsafe. It may only be called when the camera
* is in the Configured or Running state as defined in \ref camera_operation.
*
* \return A pointer to the newly created request, or nullptr on error
*/
-Request *Camera::createRequest(uint64_t cookie)
+std::unique_ptr<Request> Camera::createRequest(uint64_t cookie)
{
int ret = p_->isAccessAllowed(Private::CameraConfigured,
Private::CameraRunning);
if (ret < 0)
return nullptr;
- return new Request(this, cookie);
+ return std::make_unique<Request>(this, cookie);
}
/**
@@ -863,9 +865,6 @@ Request *Camera::createRequest(uint64_t cookie)
* Once the request has been queued, the camera will notify its completion
* through the \ref requestCompleted signal.
*
- * Ownership of the request is transferred to the camera. It will be deleted
- * automatically after it completes.
- *
* \context This function is \threadsafe. It may only be called when the camera
* is in the Running state as defined in \ref camera_operation.
*
@@ -974,13 +973,11 @@ int Camera::stop()
* \param[in] request The request that has completed
*
* This function is called by the pipeline handler to notify the camera that
- * the request has completed. It emits the requestCompleted signal and deletes
- * the request.
+ * the request has completed. It emits the requestCompleted signal.
*/
void Camera::requestComplete(Request *request)
{
requestCompleted.emit(request);
- delete request;
}
} /* namespace libcamera */
diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp
index 60b30692..dd3040fe 100644
--- a/src/libcamera/request.cpp
+++ b/src/libcamera/request.cpp
@@ -85,6 +85,30 @@ Request::~Request()
delete validator_;
}
+/*
+ * \brief Reset the request
+ *
+ * Reset the request, to allow it to be reused and requeued without
+ * destruction. All contents of the request will be reset, so any references
+ * previously returned by the request will become invalid.
+ */
+void Request::reset()
+{
+ bufferMap_.clear();
+ pending_.clear();
+
+ status_ = RequestPending;
+ cancelled_ = false;
+
+ delete metadata_;
+ delete controls_;
+ delete validator_;
+
+ validator_ = new CameraControlValidator(camera_);
+ controls_ = new ControlList(controls::controls, validator_);
+ metadata_ = new ControlList(controls::controls);
+}
+
/**
* \fn Request::controls()
* \brief Retrieve the request's ControlList
diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index 985743f3..c2f8b175 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -367,7 +367,6 @@ void MainWindow::toggleCapture(bool start)
int MainWindow::startCapture()
{
StreamRoles roles = StreamKeyValueParser::roles(options_[OptStream]);
- std::vector<Request *> requests;
int ret;
/* Verify roles are supported. */
@@ -486,7 +485,7 @@ int MainWindow::startCapture()
while (!freeBuffers_[vfStream_].isEmpty()) {
FrameBuffer *buffer = freeBuffers_[vfStream_].dequeue();
- Request *request = camera_->createRequest();
+ std::unique_ptr<Request> request = camera_->createRequest();
if (!request) {
qWarning() << "Can't create request";
ret = -ENOMEM;
@@ -499,7 +498,7 @@ int MainWindow::startCapture()
goto error;
}
- requests.push_back(request);
+ requests_.push_back(std::move(request));
}
/* Start the title timer and the camera. */
@@ -518,8 +517,8 @@ int MainWindow::startCapture()
camera_->requestCompleted.connect(this, &MainWindow::requestComplete);
/* Queue all requests. */
- for (Request *request : requests) {
- ret = camera_->queueRequest(request);
+ for (std::unique_ptr<Request> &request : requests_) {
+ ret = camera_->queueRequest(request.get());
if (ret < 0) {
qWarning() << "Can't queue request";
goto error_disconnect;
@@ -535,8 +534,7 @@ error_disconnect:
camera_->stop();
error:
- for (Request *request : requests)
- delete request;
+ requests_.clear();
for (auto &iter : mappedBuffers_) {
const MappedBuffer &buffer = iter.second;
@@ -580,6 +578,8 @@ void MainWindow::stopCapture()
}
mappedBuffers_.clear();
+ requests_.clear();
+
delete allocator_;
isCapturing_ = false;
@@ -701,7 +701,7 @@ void MainWindow::requestComplete(Request *request)
*/
{
QMutexLocker locker(&mutex_);
- doneQueue_.enqueue({ request->buffers(), request->metadata() });
+ doneQueue_.enqueue(request);
}
QCoreApplication::postEvent(this, new CaptureEvent);
@@ -714,8 +714,7 @@ void MainWindow::processCapture()
* if stopCapture() has been called while a CaptureEvent was posted but
* not processed yet. Return immediately in that case.
*/
- CaptureRequest request;
-
+ Request *request;
{
QMutexLocker locker(&mutex_);
if (doneQueue_.isEmpty())
@@ -725,11 +724,19 @@ void MainWindow::processCapture()
}
/* Process buffers. */
- if (request.buffers_.count(vfStream_))
- processViewfinder(request.buffers_[vfStream_]);
+ if (request->buffers().count(vfStream_)) {
+ {
+ QMutexLocker locker(&mutex_);
+ freeQueue_.enqueue(request);
+ }
+ Request::BufferMap buffers = request->buffers();
+ processViewfinder(buffers[vfStream_]);
+ }
- if (request.buffers_.count(rawStream_))
- processRaw(request.buffers_[rawStream_], request.metadata_);
+ if (request->buffers().count(rawStream_)) {
+ Request::BufferMap buffers = request->buffers();
+ processRaw(buffers[rawStream_], request->metadata());
+ }
}
void MainWindow::processViewfinder(FrameBuffer *buffer)
@@ -754,12 +761,17 @@ void MainWindow::processViewfinder(FrameBuffer *buffer)
void MainWindow::queueRequest(FrameBuffer *buffer)
{
- Request *request = camera_->createRequest();
- if (!request) {
- qWarning() << "Can't create request";
- return;
+ Request *request;
+ {
+ QMutexLocker locker(&mutex_);
+ if (freeQueue_.isEmpty())
+ return;
+
+ request = freeQueue_.dequeue();
}
+ request->reset();
+
request->addBuffer(vfStream_, buffer);
if (captureRaw_) {
diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
index 5c61a4df..64bcfebc 100644
--- a/src/qcam/main_window.h
+++ b/src/qcam/main_window.h
@@ -8,6 +8,7 @@
#define __QCAM_MAIN_WINDOW_H__
#include <memory>
+#include <vector>
#include <QElapsedTimer>
#include <QIcon>
@@ -22,6 +23,7 @@
#include <libcamera/camera_manager.h>
#include <libcamera/controls.h>
#include <libcamera/framebuffer_allocator.h>
+#include <libcamera/request.h>
#include <libcamera/stream.h>
#include "../cam/stream_options.h"
@@ -41,23 +43,6 @@ enum {
OptStream = 's',
};
-class CaptureRequest
-{
-public:
- CaptureRequest()
- {
- }
-
- CaptureRequest(const Request::BufferMap &buffers,
- const ControlList &metadata)
- : buffers_(buffers), metadata_(metadata)
- {
- }
-
- Request::BufferMap buffers_;
- ControlList metadata_;
-};
-
class MainWindow : public QMainWindow
{
Q_OBJECT
@@ -128,13 +113,16 @@ private:
Stream *vfStream_;
Stream *rawStream_;
std::map<const Stream *, QQueue<FrameBuffer *>> freeBuffers_;
- QQueue<CaptureRequest> doneQueue_;
- QMutex mutex_; /* Protects freeBuffers_ and doneQueue_ */
+ QQueue<Request *> doneQueue_;
+ QQueue<Request *> freeQueue_;
+ QMutex mutex_; /* Protects freeBuffers_, doneQueue_, and freeQueue_ */
uint64_t lastBufferTime_;
QElapsedTimer frameRateInterval_;
uint32_t previousFrames_;
uint32_t framesCaptured_;
+
+ std::vector<std::unique_ptr<Request>> requests_;
};
#endif /* __QCAM_MAIN_WINDOW__ */
diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp
index 3565f369..0d59502a 100644
--- a/src/v4l2/v4l2_camera.cpp
+++ b/src/v4l2/v4l2_camera.cpp
@@ -49,6 +49,8 @@ int V4L2Camera::open(StreamConfiguration *streamConfig)
void V4L2Camera::close()
{
+ requestPool_.clear();
+
delete bufferAllocator_;
bufferAllocator_ = nullptr;
@@ -154,16 +156,30 @@ int V4L2Camera::validateConfiguration(const PixelFormat &pixelFormat,
return 0;
}
-int V4L2Camera::allocBuffers([[maybe_unused]] unsigned int count)
+int V4L2Camera::allocBuffers(unsigned int count)
{
Stream *stream = config_->at(0).stream();
- return bufferAllocator_->allocate(stream);
+ int ret = bufferAllocator_->allocate(stream);
+ if (ret < 0)
+ return ret;
+
+ for (unsigned int i = 0; i < count; i++) {
+ std::unique_ptr<Request> request = camera_->createRequest(i);
+ if (!request) {
+ requestPool_.clear();
+ return -ENOMEM;
+ }
+ requestPool_.push_back(std::move(request));
+ }
+
+ return ret;
}
void V4L2Camera::freeBuffers()
{
pendingRequests_.clear();
+ requestPool_.clear();
Stream *stream = config_->at(0).stream();
bufferAllocator_->free(stream);
@@ -192,9 +208,9 @@ int V4L2Camera::streamOn()
isRunning_ = true;
- for (std::unique_ptr<Request> &req : pendingRequests_) {
+ for (Request *req : pendingRequests_) {
/* \todo What should we do if this returns -EINVAL? */
- ret = camera_->queueRequest(req.release());
+ ret = camera_->queueRequest(req);
if (ret < 0)
return ret == -EACCES ? -EBUSY : ret;
}
@@ -226,12 +242,12 @@ int V4L2Camera::streamOff()
int V4L2Camera::qbuf(unsigned int index)
{
- std::unique_ptr<Request> request =
- std::unique_ptr<Request>(camera_->createRequest(index));
- if (!request) {
- LOG(V4L2Compat, Error) << "Can't create request";
- return -ENOMEM;
+ if (index >= requestPool_.size()) {
+ LOG(V4L2Compat, Error) << "Invalid index";
+ return -EINVAL;
}
+ Request *request = requestPool_[index].get();
+ request->reset();
Stream *stream = config_->at(0).stream();
FrameBuffer *buffer = bufferAllocator_->buffers(stream)[index].get();
@@ -242,11 +258,11 @@ int V4L2Camera::qbuf(unsigned int index)
}
if (!isRunning_) {
- pendingRequests_.push_back(std::move(request));
+ pendingRequests_.push_back(request);
return 0;
}
- ret = camera_->queueRequest(request.release());
+ ret = camera_->queueRequest(request);
if (ret < 0) {
LOG(V4L2Compat, Error) << "Can't queue request";
return ret == -EACCES ? -EBUSY : ret;
diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h
index 1fc5ebef..a6c35a2e 100644
--- a/src/v4l2/v4l2_camera.h
+++ b/src/v4l2/v4l2_camera.h
@@ -76,7 +76,9 @@ private:
std::mutex bufferLock_;
FrameBufferAllocator *bufferAllocator_;
- std::deque<std::unique_ptr<Request>> pendingRequests_;
+ std::vector<std::unique_ptr<Request>> requestPool_;
+
+ std::deque<Request *> pendingRequests_;
std::deque<std::unique_ptr<Buffer>> completedBuffers_;
int efd_;
diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp
index 64e96264..9cfdb388 100644
--- a/test/camera/buffer_import.cpp
+++ b/test/camera/buffer_import.cpp
@@ -50,7 +50,7 @@ protected:
if (request->status() != Request::RequestComplete)
return;
- const Request::BufferMap &buffers = request->buffers();
+ const Request::BufferMap buffers = request->buffers();
completeRequestsCount_++;
@@ -58,7 +58,7 @@ protected:
const Stream *stream = buffers.begin()->first;
FrameBuffer *buffer = buffers.begin()->second;
- request = camera_->createRequest();
+ request->reset();
request->addBuffer(stream, buffer);
camera_->queueRequest(request);
}
@@ -98,9 +98,8 @@ protected:
if (ret != TestPass)
return ret;
- std::vector<Request *> requests;
for (const std::unique_ptr<FrameBuffer> &buffer : source.buffers()) {
- Request *request = camera_->createRequest();
+ std::unique_ptr<Request> request = camera_->createRequest();
if (!request) {
std::cout << "Failed to create request" << std::endl;
return TestFail;
@@ -111,7 +110,7 @@ protected:
return TestFail;
}
- requests.push_back(request);
+ requests_.push_back(std::move(request));
}
completeRequestsCount_ = 0;
@@ -125,8 +124,8 @@ protected:
return TestFail;
}
- for (Request *request : requests) {
- if (camera_->queueRequest(request)) {
+ for (std::unique_ptr<Request> &request : requests_) {
+ if (camera_->queueRequest(request.get())) {
std::cout << "Failed to queue request" << std::endl;
return TestFail;
}
@@ -160,6 +159,8 @@ protected:
}
private:
+ std::vector<std::unique_ptr<Request>> requests_;
+
unsigned int completeBuffersCount_;
unsigned int completeRequestsCount_;
std::unique_ptr<CameraConfiguration> config_;
diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp
index 51bbd258..5c86c490 100644
--- a/test/camera/capture.cpp
+++ b/test/camera/capture.cpp
@@ -44,7 +44,7 @@ protected:
if (request->status() != Request::RequestComplete)
return;
- const Request::BufferMap &buffers = request->buffers();
+ const Request::BufferMap buffers = request->buffers();
completeRequestsCount_++;
@@ -52,7 +52,7 @@ protected:
const Stream *stream = buffers.begin()->first;
FrameBuffer *buffer = buffers.begin()->second;
- request = camera_->createRequest();
+ request->reset();
request->addBuffer(stream, buffer);
camera_->queueRequest(request);
}
@@ -98,9 +98,8 @@ protected:
if (ret < 0)
return TestFail;
- std::vector<Request *> requests;
for (const std::unique_ptr<FrameBuffer> &buffer : allocator_->buffers(stream)) {
- Request *request = camera_->createRequest();
+ std::unique_ptr<Request> request = camera_->createRequest();
if (!request) {
cout << "Failed to create request" << endl;
return TestFail;
@@ -111,7 +110,7 @@ protected:
return TestFail;
}
- requests.push_back(request);
+ requests_.push_back(std::move(request));
}
completeRequestsCount_ = 0;
@@ -125,8 +124,8 @@ protected:
return TestFail;
}
- for (Request *request : requests) {
- if (camera_->queueRequest(request)) {
+ for (std::unique_ptr<Request> &request : requests_) {
+ if (camera_->queueRequest(request.get())) {
cout << "Failed to queue request" << endl;
return TestFail;
}
@@ -161,6 +160,8 @@ protected:
return TestPass;
}
+ std::vector<std::unique_ptr<Request>> requests_;
+
std::unique_ptr<CameraConfiguration> config_;
FrameBufferAllocator *allocator_;
};
diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp
index 28faeb91..e63ab298 100644
--- a/test/camera/statemachine.cpp
+++ b/test/camera/statemachine.cpp
@@ -101,13 +101,10 @@ protected:
return TestFail;
/* Test operations which should pass. */
- Request *request2 = camera_->createRequest();
+ std::unique_ptr<Request> request2 = camera_->createRequest();
if (!request2)
return TestFail;
- /* Never handed to hardware so need to manually delete it. */
- delete request2;
-
/* Test valid state transitions, end in Running state. */
if (camera_->release())
return TestFail;
@@ -146,7 +143,7 @@ protected:
return TestFail;
/* Test operations which should pass. */
- Request *request = camera_->createRequest();
+ std::unique_ptr<Request> request = camera_->createRequest();
if (!request)
return TestFail;
@@ -154,7 +151,7 @@ protected:
if (request->addBuffer(stream, allocator_->buffers(stream)[0].get()))
return TestFail;
- if (camera_->queueRequest(request))
+ if (camera_->queueRequest(request.get()))
return TestFail;
/* Test valid state transitions, end in Available state. */
--
2.27.0
More information about the libcamera-devel
mailing list