summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/camera_device.cpp77
-rw-r--r--src/android/camera_device.h3
-rw-r--r--src/android/camera_ops.cpp8
3 files changed, 71 insertions, 17 deletions
diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp
index b29c1edc..52317037 100644
--- a/src/android/camera_device.cpp
+++ b/src/android/camera_device.cpp
@@ -798,6 +798,23 @@ void CameraDevice::close()
camera_->release();
}
+void CameraDevice::flush()
+{
+ {
+ MutexLocker stateLock(stateMutex_);
+ if (state_ != State::Running)
+ return;
+
+ state_ = State::Flushing;
+ }
+
+ worker_.stop();
+ camera_->stop();
+
+ MutexLocker stateLock(stateMutex_);
+ state_ = State::Stopped;
+}
+
void CameraDevice::stop()
{
MutexLocker stateLock(stateMutex_);
@@ -1896,27 +1913,31 @@ int CameraDevice::processControls(Camera3RequestDescriptor *descriptor)
return 0;
}
-int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
+void CameraDevice::abortRequest(camera3_capture_request_t *request)
{
- if (!isValidRequest(camera3Request))
- return -EINVAL;
+ notifyError(request->frame_number, nullptr, CAMERA3_MSG_ERROR_REQUEST);
- {
- MutexLocker stateLock(stateMutex_);
+ camera3_capture_result_t result = {};
+ result.num_output_buffers = request->num_output_buffers;
+ result.frame_number = request->frame_number;
+ result.partial_result = 0;
- /* Start the camera if that's the first request we handle. */
- if (state_ == State::Stopped) {
- worker_.start();
+ std::vector<camera3_stream_buffer_t> resultBuffers(result.num_output_buffers);
+ for (auto [i, buffer] : utils::enumerate(resultBuffers)) {
+ buffer = request->output_buffers[i];
+ buffer.release_fence = request->output_buffers[i].acquire_fence;
+ buffer.acquire_fence = -1;
+ buffer.status = CAMERA3_BUFFER_STATUS_ERROR;
+ }
+ result.output_buffers = resultBuffers.data();
- int ret = camera_->start();
- if (ret) {
- LOG(HAL, Error) << "Failed to start camera";
- return ret;
- }
+ callbacks_->process_capture_result(callbacks_, &result);
+}
- state_ = State::Running;
- }
- }
+int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)
+{
+ if (!isValidRequest(camera3Request))
+ return -EINVAL;
/*
* Save the request descriptors for use at completion time.
@@ -2006,6 +2027,30 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques
if (ret)
return ret;
+ /*
+ * If flush is in progress abort the request. If the camera has been
+ * stopped we have to re-start it to be able to process the request.
+ */
+ MutexLocker stateLock(stateMutex_);
+
+ if (state_ == State::Flushing) {
+ abortRequest(camera3Request);
+ return 0;
+ }
+
+ if (state_ == State::Stopped) {
+ worker_.start();
+
+ ret = camera_->start();
+ if (ret) {
+ LOG(HAL, Error) << "Failed to start camera";
+ worker_.stop();
+ return ret;
+ }
+
+ state_ = State::Running;
+ }
+
worker_.queueRequest(descriptor.request_.get());
{
diff --git a/src/android/camera_device.h b/src/android/camera_device.h
index c949fa50..4aadb27c 100644
--- a/src/android/camera_device.h
+++ b/src/android/camera_device.h
@@ -43,6 +43,7 @@ public:
int open(const hw_module_t *hardwareModule);
void close();
+ void flush();
unsigned int id() const { return id_; }
camera3_device_t *camera3Device() { return &camera3Device_; }
@@ -92,6 +93,7 @@ private:
enum class State {
Stopped,
+ Flushing,
Running,
};
@@ -106,6 +108,7 @@ private:
getRawResolutions(const libcamera::PixelFormat &pixelFormat);
libcamera::FrameBuffer *createFrameBuffer(const buffer_handle_t camera3buffer);
+ void abortRequest(camera3_capture_request_t *request);
void notifyShutter(uint32_t frameNumber, uint64_t timestamp);
void notifyError(uint32_t frameNumber, camera3_stream_t *stream,
camera3_error_msg_code code);
diff --git a/src/android/camera_ops.cpp b/src/android/camera_ops.cpp
index 696e8043..8a3cfa17 100644
--- a/src/android/camera_ops.cpp
+++ b/src/android/camera_ops.cpp
@@ -66,8 +66,14 @@ static void hal_dev_dump([[maybe_unused]] const struct camera3_device *dev,
{
}
-static int hal_dev_flush([[maybe_unused]] const struct camera3_device *dev)
+static int hal_dev_flush(const struct camera3_device *dev)
{
+ if (!dev)
+ return -EINVAL;
+
+ CameraDevice *camera = reinterpret_cast<CameraDevice *>(dev->priv);
+ camera->flush();
+
return 0;
}