| /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
| /* |
| * Copyright (C) 2019-2021, Google Inc. |
| * |
| * libcamera Android Camera Request Descriptor |
| */ |
| |
| #include "camera_request.h" |
| |
| #include <libcamera/base/span.h> |
| |
| #include "camera_buffer.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 │ |
| * │ - Streams requiring post-processing are stored in the │ |
| * │ pendingStreamsToProcess map │ |
| * │ - Add this Camera3RequestDescriptor to descriptors' queue │ |
| * │ CameraDevice::descriptors_ │ |
| * │ │ ┌─────────────────────────┐ |
| * │ - Queue the capture request to libcamera core ────────────┤►│libcamera core │ |
| * │ │ ├─────────────────────────┤ |
| * │ │ │- Capture from Camera │ |
| * │ │ │ │ |
| * │ │ │- Emit │ |
| * │ │ │ Camera::requestComplete│ |
| * │ requestCompleted(Request *request) ◄───────────────────────┼─┼──── │ |
| * │ │ │ │ |
| * │ - Check request completion status │ └─────────────────────────┘ |
| * │ │ |
| * │ - if (pendingStreamsToProcess > 0) │ |
| * │ Queue all entries from pendingStreamsToProcess │ |
| * │ else │ │ |
| * │ completeDescriptor() │ └──────────────────────┐ |
| * │ │ │ |
| * │ ┌──────────────────────────┴───┬──────────────────┐ │ |
| * │ │ │ │ │ |
| * │ ┌──────────▼────────────┐ ┌───────────▼─────────┐ ▼ │ |
| * │ │CameraStream1 │ │CameraStream2 │ .... │ |
| * │ ├┬───┬───┬──────────────┤ ├┬───┬───┬────────────┤ │ |
| * │ ││ │ │ │ ││ │ │ │ │ |
| * │ │▼───▼───▼──────────────┤ │▼───▼───▼────────────┤ │ |
| * │ │PostProcessorWorker │ │PostProcessorWorker │ │ |
| * │ │ │ │ │ │ |
| * │ │ +------------------+ │ │ +------------------+│ │ |
| * │ │ | PostProcessor | │ │ | PostProcessor |│ │ |
| * │ │ | process() | │ │ | process() |│ │ |
| * │ │ | | │ │ | |│ │ |
| * │ │ | Emit | │ │ | Emit |│ │ |
| * │ │ | processComplete | │ │ | processComplete |│ │ |
| * │ │ | | │ │ | |│ │ |
| * │ │ +--------------│---+ │ │ +--------------│---+│ │ |
| * │ │ │ │ │ │ │ │ |
| * │ │ │ │ │ │ │ │ |
| * │ └────────────────┼──────┘ └────────────────┼────┘ │ |
| * │ │ │ │ |
| * │ │ │ │ |
| * │ │ │ │ |
| * │ ▼ ▼ │ |
| * │ +---------------------------------------+ +--------------+ │ |
| * │ | CameraDevice | | | │ |
| * │ | | | | │ |
| * │ | streamProcessingComplete() | | | │ |
| * │ | | | | │ |
| * │ | - Check and set buffer status | | .... | │ |
| * │ | - Remove post+processing entry | | | │ |
| * │ | from pendingStreamsToProcess | | | │ |
| * │ | | | | │ |
| * │ | - if (pendingStreamsToProcess.empty())| | | │ |
| * │ | completeDescriptor | | | │ |
| * │ | | | | │ |
| * │ +---------------------------------------+ +--------------+ │ |
| * │ │ |
| * └────────────────────────────────────────────────────────────────────────────────────┘ |
| * |
| * +-------------+ |
| * | | - PostProcessorWorker's thread |
| * | | |
| * +-------------+ |
| */ |
| |
| Camera3RequestDescriptor::Camera3RequestDescriptor( |
| Camera *camera, const camera3_capture_request_t *camera3Request) |
| { |
| 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); |
| |
| buffers_.emplace_back(stream, buffer, this); |
| } |
| |
| /* 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() = default; |
| |
| /** |
| * \struct Camera3RequestDescriptor::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 Camera3RequestDescriptor::StreamBuffer::stream |
| * \brief Pointer to the corresponding CameraStream |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::camera3Buffer |
| * \brief Native handle to the buffer |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::frameBuffer |
| * \brief Encapsulate the dmabuf handle inside a libcamera::FrameBuffer for |
| * direct streams |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::fence |
| * \brief Acquire fence of the buffer |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::status |
| * \brief Track the status of the buffer |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::internalBuffer |
| * \brief Pointer to a buffer internally handled by CameraStream (if any) |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::srcBuffer |
| * \brief Pointer to the source frame buffer used for post-processing |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::dstBuffer |
| * \brief Pointer to the destination frame buffer used for post-processing |
| * |
| * \var Camera3RequestDescriptor::StreamBuffer::request |
| * \brief Back pointer to the Camera3RequestDescriptor to which the StreamBuffer belongs |
| */ |
| Camera3RequestDescriptor::StreamBuffer::StreamBuffer( |
| CameraStream *cameraStream, const camera3_stream_buffer_t &buffer, |
| Camera3RequestDescriptor *requestDescriptor) |
| : stream(cameraStream), camera3Buffer(buffer.buffer), |
| fence(buffer.acquire_fence), request(requestDescriptor) |
| { |
| } |
| |
| Camera3RequestDescriptor::StreamBuffer::~StreamBuffer() = default; |
| |
| Camera3RequestDescriptor::StreamBuffer::StreamBuffer(StreamBuffer &&) = default; |
| |
| Camera3RequestDescriptor::StreamBuffer & |
| Camera3RequestDescriptor::StreamBuffer::operator=(Camera3RequestDescriptor::StreamBuffer &&) = default; |