| /* SPDX-License-Identifier: LGPL-2.1-or-later */ | |
| /* | |
| * Copyright (C) 2019-2021, Google Inc. | |
| * | |
| * camera_request.cpp - libcamera Android Camera Request Descriptor | |
| */ | |
| #include "camera_request.h" | |
| #include <libcamera/base/log.h> | |
| #include <libcamera/base/span.h> | |
| #include "camera_buffer.h" | |
| #include "camera_stream.h" | |
| using namespace libcamera; | |
| /* | |
| * \class Camera3RequestDescriptor | |
| * | |
| * A utility class that groups information about a capture request to be later | |
| * reused at request complete time to notify the framework. | |
| * | |
| ******************************************************************************* | |
| * Lifetime of a Camera3RequestDescriptor tracking a capture request placed by | |
| * Android Framework | |
| ******************************************************************************* | |
| * | |
| * | |
| * Android Framework | |
| * │ | |
| * │ ┌──────────────────────────────────┐ | |
| * │ │camera3_capture_request_t │ | |
| * │ │ │ | |
| * │ │Requested output streams │ | |
| * │ │ stream1 stream2 stream3 ... │ | |
| * │ └──────────────────────────────────┘ | |
| * ▼ | |
| * ┌─────────────────────────────────────────────────────────────┐ | |
| * │ libcamera HAL │ | |
| * ├─────────────────────────────────────────────────────────────┤ | |
| * │ CameraDevice │ | |
| * │ │ | |
| * │ processCaptureRequest(camera3_capture_request_t request) │ | |
| * │ │ | |
| * │ - Create Camera3RequestDescriptor tracking this request │ | |
| * │ - Buffers requiring post-processing are marked by the │ | |
| * │ CameraStream::Type as Mapped or Internal │ | |
| * │ - Add this Camera3RequestDescriptor to descriptors' queue │ | |
| * │ CameraDevice::pendingRequests_ │ | |
| * │ │ ┌────────────────────────────────┐ | |
| * │ - Queue the capture request to libcamera core ────────────┤►│libcamera core │ | |
| * │ │ ├────────────────────────────────┤ | |
| * │ │ │- Capture from Camera │ | |
| * │ │ │ │ | |
| * │ │ │- Emit │ | |
| * │ │ │ Camera::partialResultCompleted│ | |
| * │ partialResultComplete(Request *request, Result result*) ◄──┼─┼──── │ | |
| * │ │ │ │ | |
| * │ - Check request completion status │ └────────────────────────────────┘ | |
| * │ │ | |
| * │ - if (pendingBuffersToProcess > 0) │ | |
| * │ Queue all entries from pendingBuffersToProcess │ | |
| * │ else │ │ | |
| * │ completeResultDescriptor() │ └──────────────────────┐ | |
| * │ │ │ | |
| * │ ┌──────────────────────────┴───┬──────────────────┐ │ | |
| * │ │ │ │ │ | |
| * │ ┌──────────▼────────────┐ ┌───────────▼─────────┐ ▼ │ | |
| * │ │CameraStream1 │ │CameraStream2 │ .... │ | |
| * │ ├┬───┬───┬──────────────┤ ├┬───┬───┬────────────┤ │ | |
| * │ ││ │ │ │ ││ │ │ │ │ | |
| * │ │▼───▼───▼──────────────┤ │▼───▼───▼────────────┤ │ | |
| * │ │PostProcessorWorker │ │PostProcessorWorker │ │ | |
| * │ │ │ │ │ │ | |
| * │ │ +------------------+ │ │ +------------------+│ │ | |
| * │ │ | PostProcessor | │ │ | PostProcessor |│ │ | |
| * │ │ | process() | │ │ | process() |│ │ | |
| * │ │ | | │ │ | |│ │ | |
| * │ │ | Emit | │ │ | Emit |│ │ | |
| * │ │ | processComplete | │ │ | processComplete |│ │ | |
| * │ │ | | │ │ | |│ │ | |
| * │ │ +--------------│---+ │ │ +--------------│---+│ │ | |
| * │ │ │ │ │ │ │ │ | |
| * │ │ │ │ │ │ │ │ | |
| * │ └────────────────┼──────┘ └────────────────┼────┘ │ | |
| * │ │ │ │ | |
| * │ │ │ │ | |
| * │ │ │ │ | |
| * │ ▼ ▼ │ | |
| * │ +---------------------------------------+ +--------------+ │ | |
| * │ | CameraDevice | | | │ | |
| * │ | | | | │ | |
| * │ | streamProcessingComplete() | | | │ | |
| * │ | | | | │ | |
| * │ | - Check and set buffer status | | .... | │ | |
| * │ | - Remove post+processing entry | | | │ | |
| * │ | from pendingBuffersToProcess | | | │ | |
| * │ | | | | │ | |
| * │ | - if (pendingBuffersToProcess.empty())| | | │ | |
| * │ | completeResultDescriptor | | | │ | |
| * │ | | | | │ | |
| * │ +---------------------------------------+ +--------------+ │ | |
| * │ │ | |
| * └────────────────────────────────────────────────────────────────────────────────────┘ | |
| * | |
| * +-------------+ | |
| * | | - PostProcessorWorker's thread | |
| * | | | |
| * +-------------+ | |
| */ | |
| Camera3RequestDescriptor::Camera3RequestDescriptor( | |
| Camera *camera, | |
| #ifdef HAVE_ANDROID_OS | |
| std::shared_ptr<android::BufferAdapter> bufferAdaptor, | |
| #endif | |
| const camera3_capture_request_t *camera3Request) | |
| : status_(Status::Pending), nextPartialResultIndex_(1), completed_(false) | |
| { | |
| frameNumber_ = camera3Request->frame_number; | |
| /* Copy the camera3 request stream information for later access. */ | |
| const Span<const camera3_stream_buffer_t> buffers{ | |
| camera3Request->output_buffers, | |
| camera3Request->num_output_buffers | |
| }; | |
| buffers_.reserve(buffers.size()); | |
| for (const camera3_stream_buffer_t &buffer : buffers) { | |
| CameraStream *stream = | |
| static_cast<CameraStream *>(buffer.stream->priv); | |
| #ifdef HAVE_ANDROID_OS | |
| camera3_stream_buffer_t outputBuffer = bufferAdaptor->prepareStreamBufferPtr(&buffer); | |
| buffers_.emplace_back(stream, outputBuffer, this); | |
| #else | |
| buffers_.emplace_back(stream, buffer, this); | |
| #endif | |
| } | |
| /* Clone the controls associated with the camera3 request. */ | |
| settings_ = CameraMetadata(camera3Request->settings); | |
| /* | |
| * Create the CaptureRequest, stored as a unique_ptr<> to tie its | |
| * lifetime to the descriptor. | |
| */ | |
| request_ = camera->createRequest(reinterpret_cast<uint64_t>(this)); | |
| } | |
| Camera3RequestDescriptor::~Camera3RequestDescriptor() | |
| { | |
| /* | |
| * Recycle the allocated internal buffer back to its source stream. | |
| */ | |
| for (auto &[sourceStream, frameBuffer] : internalBuffers_) | |
| sourceStream->putBuffer(frameBuffer); | |
| } | |
| /* | |
| * \class Camera3ResultDescriptor | |
| * | |
| * A utility class that groups information about a capture result to be later | |
| * sent to framework. | |
| */ | |
| Camera3ResultDescriptor::Camera3ResultDescriptor(Camera3RequestDescriptor *request) | |
| : request_(request), metadataPackIndex_(1), completed_(false) | |
| { | |
| } | |
| Camera3ResultDescriptor::~Camera3ResultDescriptor() = default; | |
| /** | |
| * \class StreamBuffer | |
| * \brief Group information for per-stream buffer of Camera3RequestDescriptor | |
| * | |
| * A capture request placed to the libcamera HAL can contain multiple streams. | |
| * Each stream will have an associated buffer to be filled. StreamBuffer | |
| * tracks this buffer with contextual information which aids in the stream's | |
| * generation. The generation of the stream will depend on its type (refer to | |
| * the CameraStream::Type documentation). | |
| * | |
| * \var StreamBuffer::stream | |
| * \brief Pointer to the corresponding CameraStream | |
| * | |
| * \var StreamBuffer::camera3Buffer | |
| * \brief Native handle to the buffer | |
| * | |
| * \var StreamBuffer::frameBuffer | |
| * \brief Encapsulate the dmabuf handle inside a libcamera::FrameBuffer for | |
| * direct streams | |
| * | |
| * \var StreamBuffer::fence | |
| * \brief Acquire fence of the buffer | |
| * | |
| * \var StreamBuffer::status | |
| * \brief Track the status of the buffer | |
| * | |
| * \var StreamBuffer::srcBuffer | |
| * \brief Pointer to the source frame buffer used for post-processing | |
| * | |
| * \var StreamBuffer::dstBuffer | |
| * \brief Pointer to the destination frame buffer used for post-processing | |
| * | |
| * \var StreamBuffer::request | |
| * \brief Back pointer to the Camera3RequestDescriptor to which the StreamBuffer belongs | |
| * | |
| * \var StreamBuffer::result | |
| * \brief Back pointer to the Camera3ResultDescriptor to which the StreamBuffer belongs | |
| */ | |
| StreamBuffer::StreamBuffer( | |
| CameraStream *cameraStream, const camera3_stream_buffer_t &buffer, | |
| Camera3RequestDescriptor *requestDescriptor) | |
| : stream(cameraStream), camera3Buffer(buffer.buffer), | |
| fence(buffer.acquire_fence), request(requestDescriptor) | |
| { | |
| } | |
| StreamBuffer::~StreamBuffer() = default; | |
| StreamBuffer::StreamBuffer(StreamBuffer &&) = default; | |
| StreamBuffer &StreamBuffer::operator=(StreamBuffer &&) = default; |