| /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
| /* |
| * Copyright (C) 2020, Google Inc. |
| * |
| * camera_stream.h - Camera HAL stream |
| */ |
| |
| #pragma once |
| |
| #include <memory> |
| #include <queue> |
| #include <vector> |
| |
| #include <hardware/camera3.h> |
| |
| #include <libcamera/base/mutex.h> |
| #include <libcamera/base/thread.h> |
| |
| #include <libcamera/camera.h> |
| #include <libcamera/framebuffer.h> |
| #include <libcamera/geometry.h> |
| #include <libcamera/pixel_format.h> |
| |
| #include "camera_request.h" |
| #include "post_processor.h" |
| |
| class CameraDevice; |
| class PlatformFrameBufferAllocator; |
| |
| class CameraStream |
| { |
| public: |
| /* |
| * Enumeration of CameraStream types. |
| * |
| * A camera stream associates an Android stream to a libcamera stream. |
| * This enumeration describes how the two streams are associated and how |
| * and where data produced from libcamera are delivered to the |
| * Android framework. |
| * |
| * Direct: |
| * |
| * The Android stream is directly mapped onto a libcamera stream: frames |
| * are delivered by the library directly in the memory location |
| * specified by the Android stream (buffer_handle_t->data) and provided |
| * to the framework as they are. The Android stream characteristics are |
| * directly translated to the libcamera stream configuration. |
| * |
| * +-----+ +-----+ |
| * | A | | L | |
| * +-----+ +-----+ |
| * | | |
| * V V |
| * +-----+ +------+ |
| * | B |<---------------| FB | |
| * +-----+ +------+ |
| * |
| * |
| * Internal: |
| * |
| * Data for the Android stream is produced by processing a libcamera |
| * stream created by the HAL for that purpose. The libcamera stream |
| * needs to be supplied with intermediate buffers where the library |
| * delivers frames to be processed and then provided to the framework. |
| * The libcamera stream configuration is not a direct translation of the |
| * Android stream characteristics, but it describes the format and size |
| * required for the processing procedure to produce frames in the |
| * Android required format. |
| * |
| * +-----+ +-----+ |
| * | A | | L | |
| * +-----+ +-----+ |
| * | | |
| * V V |
| * +-----+ +------+ |
| * | B | | FB | |
| * +-----+ +------+ |
| * ^ | |
| * |-------Processing------| |
| * |
| * |
| * Mapped: |
| * |
| * Data for the Android stream is produced by processing a libcamera |
| * stream associated with another CameraStream. Mapped camera streams do |
| * not need any memory to be reserved for them as they process data |
| * produced by libcamera for a different stream whose format and size |
| * are compatible with the processing procedure requirements to produce |
| * frames in the Android required format. |
| * |
| * +-----+ +-----+ +-----+ |
| * | A | | A' | | L | |
| * +-----+ +-----+ +-----+ |
| * | | | |
| * V V V |
| * +-----+ +-----+ +------+ |
| * | B | | B' |<---------| FB | |
| * +-----+ +-----+ +------+ |
| * ^ | |
| * |--Processing--| |
| * |
| * |
| * -------------------------------------------------------------------- |
| * A = Android stream |
| * L = libcamera stream |
| * B = memory buffer |
| * FB = libcamera FrameBuffer |
| * "Processing" = Frame processing procedure (Encoding, scaling etc) |
| */ |
| enum class Type { |
| Direct, |
| Internal, |
| Mapped, |
| }; |
| CameraStream(CameraDevice *const cameraDevice, |
| libcamera::CameraConfiguration *config, Type type, |
| camera3_stream_t *camera3Stream, |
| CameraStream *const sourceStream, |
| unsigned int index); |
| CameraStream(CameraStream &&other); |
| ~CameraStream(); |
| |
| Type type() const { return type_; } |
| camera3_stream_t *camera3Stream() const { return camera3Stream_; } |
| const libcamera::StreamConfiguration &configuration() const; |
| libcamera::Stream *stream() const; |
| CameraStream *sourceStream() const { return sourceStream_; } |
| bool isJpegStream() const |
| { |
| return camera3Stream_->format == HAL_PIXEL_FORMAT_BLOB; |
| } |
| |
| int configure(); |
| int process(StreamBuffer *streamBuffer); |
| libcamera::FrameBuffer *getBuffer(); |
| void putBuffer(libcamera::FrameBuffer *buffer); |
| void flush(); |
| |
| private: |
| class PostProcessorWorker : public libcamera::Thread |
| { |
| public: |
| enum class State { |
| Stopped, |
| Running, |
| Flushing, |
| }; |
| |
| PostProcessorWorker(PostProcessor *postProcessor); |
| ~PostProcessorWorker(); |
| |
| void start(); |
| void queueRequest(StreamBuffer *request); |
| void flush(); |
| |
| protected: |
| void run() override; |
| |
| private: |
| PostProcessor *postProcessor_; |
| |
| libcamera::Mutex mutex_; |
| libcamera::ConditionVariable cv_; |
| |
| std::queue<StreamBuffer *> requests_ |
| LIBCAMERA_TSA_GUARDED_BY(mutex_); |
| |
| State state_ LIBCAMERA_TSA_GUARDED_BY(mutex_) = State::Stopped; |
| }; |
| |
| int waitFence(int fence); |
| |
| CameraDevice *const cameraDevice_; |
| const libcamera::CameraConfiguration *config_; |
| const Type type_; |
| camera3_stream_t *camera3Stream_; |
| CameraStream *const sourceStream_; |
| const unsigned int index_; |
| |
| std::unique_ptr<PlatformFrameBufferAllocator> allocator_; |
| std::vector<std::unique_ptr<libcamera::FrameBuffer>> allocatedBuffers_; |
| std::vector<libcamera::FrameBuffer *> buffers_ LIBCAMERA_TSA_GUARDED_BY(mutex_); |
| /* |
| * The class has to be MoveConstructible as instances are stored in |
| * an std::vector in CameraDevice. |
| */ |
| std::unique_ptr<libcamera::Mutex> mutex_; |
| std::unique_ptr<PostProcessor> postProcessor_; |
| |
| std::unique_ptr<PostProcessorWorker> worker_; |
| }; |