blob: dfb6f7bfde33a3993cc6cc01282256c1d3afd7ec [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H
18#define ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H
19
Jan Sebechlebsky2f4478e2024-05-08 17:26:42 +020020#include <atomic>
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010021#include <cstdint>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010022#include <deque>
23#include <future>
24#include <memory>
25#include <thread>
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010026#include <vector>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010027
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +010028#include "VirtualCameraDevice.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010029#include "VirtualCameraSessionContext.h"
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010030#include "aidl/android/hardware/camera/device/CameraMetadata.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010031#include "aidl/android/hardware/camera/device/ICameraDeviceCallback.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010032#include "android/binder_auto_utils.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010033#include "util/EglDisplayContext.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010034#include "util/EglFramebuffer.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010035#include "util/EglProgram.h"
36#include "util/EglSurfaceTexture.h"
Vadim Caen11dfd932024-03-05 09:57:20 +010037#include "util/MetadataUtil.h"
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010038#include "util/Util.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010039
40namespace android {
41namespace companion {
42namespace virtualcamera {
43
44// Represents single output buffer of capture request.
45class CaptureRequestBuffer {
46 public:
47 CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr);
48
49 int getStreamId() const;
50 int getBufferId() const;
51 sp<Fence> getFence() const;
52
53 private:
54 const int mStreamId;
55 const int mBufferId;
56 const sp<Fence> mFence;
57};
58
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010059struct RequestSettings {
60 int jpegQuality = VirtualCameraDevice::kDefaultJpegQuality;
Vadim Caenc0aff132024-03-12 17:20:07 +010061 int jpegOrientation = VirtualCameraDevice::kDefaultJpegOrientation;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010062 Resolution thumbnailResolution = Resolution(0, 0);
63 int thumbnailJpegQuality = VirtualCameraDevice::kDefaultJpegQuality;
Vadim Caenc0aff132024-03-12 17:20:07 +010064 std::optional<FpsRange> fpsRange;
Vadim Caen11dfd932024-03-05 09:57:20 +010065 camera_metadata_enum_android_control_capture_intent_t captureIntent =
66 VirtualCameraDevice::kDefaultCaptureIntent;
Vadim Caenc0aff132024-03-12 17:20:07 +010067 std::optional<GpsCoordinates> gpsCoordinates;
Vadim Caen6a43beb2024-04-12 15:06:42 +020068 std::optional<camera_metadata_enum_android_control_ae_precapture_trigger>
69 aePrecaptureTrigger;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010070};
71
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010072// Represents single capture request to fill set of buffers.
73class ProcessCaptureRequestTask {
74 public:
75 ProcessCaptureRequestTask(
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010076 int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers,
77 const RequestSettings& RequestSettings = {});
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010078
79 // Returns frame number corresponding to the request.
80 int getFrameNumber() const;
81
82 // Get reference to vector describing output buffers corresponding
83 // to this request.
84 //
85 // Note that the vector is owned by the ProcessCaptureRequestTask instance,
86 // so it cannot be access outside of its lifetime.
87 const std::vector<CaptureRequestBuffer>& getBuffers() const;
88
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010089 const RequestSettings& getRequestSettings() const;
90
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010091 private:
92 const int mFrameNumber;
93 const std::vector<CaptureRequestBuffer> mBuffers;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010094 const RequestSettings mRequestSettings;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010095};
96
97// Wraps dedicated rendering thread and rendering business with corresponding
98// input surface.
99class VirtualCameraRenderThread {
100 public:
101 // Create VirtualCameraRenderThread instance:
102 // * sessionContext - VirtualCameraSessionContext reference for shared access
103 // to mapped buffers.
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100104 // * inputSurfaceSize - requested size of input surface.
105 // * reportedSensorSize - reported static sensor size of virtual camera.
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100106 // * cameraDeviceCallback - callback for corresponding camera instance
107 // * testMode - when set to true, test pattern is rendered to input surface
108 // before each capture request is processed to simulate client input.
109 VirtualCameraRenderThread(
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100110 VirtualCameraSessionContext& sessionContext, Resolution inputSurfaceSize,
111 Resolution reportedSensorSize,
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100112 std::shared_ptr<
113 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
114 cameraDeviceCallback,
115 bool testMode = false);
116
117 ~VirtualCameraRenderThread();
118
119 // Start rendering thread.
120 void start();
121 // Stop rendering thread.
122 void stop();
123
124 // Equeue capture task for processing on render thread.
125 void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task)
126 EXCLUDES(mLock);
127
128 // Flush all in-flight requests.
129 void flush() EXCLUDES(mLock);
130
131 // Returns input surface corresponding to "virtual camera sensor".
132 sp<Surface> getInputSurface();
133
134 private:
135 std::unique_ptr<ProcessCaptureRequestTask> dequeueTask() EXCLUDES(mLock);
136
137 // Rendering thread entry point.
138 void threadLoop();
139
140 // Process single capture request task (always called on render thread).
141 void processCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
142
143 // Flush single capture request task returning the error status immediately.
144 void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
145
146 // TODO(b/301023410) - Refactor the actual rendering logic off this class for
147 // easier testability.
148
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100149 // Create thumbnail with specified size for current image.
150 // The compressed image size is limited by 32KiB.
151 // Returns vector with compressed thumbnail if successful,
152 // empty vector otherwise.
153 std::vector<uint8_t> createThumbnail(Resolution resolution, int quality);
154
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100155 // Render current image to the BLOB buffer.
156 // If fence is specified, this function will block until the fence is cleared
157 // before writing to the buffer.
158 // Always called on render thread.
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100159 ndk::ScopedAStatus renderIntoBlobStreamBuffer(
160 const int streamId, const int bufferId,
Vadim Caenc0aff132024-03-12 17:20:07 +0100161 const ::aidl::android::hardware::camera::device::CameraMetadata&
162 resultMetadata,
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100163 const RequestSettings& requestSettings, sp<Fence> fence = nullptr);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100164
165 // Render current image to the YCbCr buffer.
166 // If fence is specified, this function will block until the fence is cleared
167 // before writing to the buffer.
168 // Always called on render thread.
169 ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId,
170 sp<Fence> fence = nullptr);
171
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100172 // Render current image into provided EglFramebuffer.
173 // If fence is specified, this function will block until the fence is cleared
174 // before writing to the buffer.
175 // Always called on the render thread.
Jan Sebechlebskyb3771312024-03-15 10:38:02 +0100176 ndk::ScopedAStatus renderIntoEglFramebuffer(
177 EglFrameBuffer& framebuffer, sp<Fence> fence = nullptr,
178 std::optional<Rect> viewport = std::nullopt);
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100179
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100180 // Camera callback
181 const std::shared_ptr<
182 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
183 mCameraDeviceCallback;
184
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100185 const Resolution mInputSurfaceSize;
186 const Resolution mReportedSensorSize;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100187 const int mTestMode;
188
189 VirtualCameraSessionContext& mSessionContext;
190
191 std::thread mThread;
192
193 // Blocking queue implementation.
194 std::mutex mLock;
195 std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock);
196 std::condition_variable mCondVar;
197 volatile bool mPendingExit GUARDED_BY(mLock);
198
Jan Sebechlebsky2f4478e2024-05-08 17:26:42 +0200199 // Acquisition timestamp of last frame.
200 std::atomic<uint64_t> mLastAcquisitionTimestampNanoseconds;
201
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100202 // EGL helpers - constructed and accessed only from rendering thread.
203 std::unique_ptr<EglDisplayContext> mEglDisplayContext;
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100204 std::unique_ptr<EglTextureProgram> mEglTextureYuvProgram;
205 std::unique_ptr<EglTextureProgram> mEglTextureRgbProgram;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100206 std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture;
207
208 std::promise<sp<Surface>> mInputSurfacePromise;
209};
210
211} // namespace virtualcamera
212} // namespace companion
213} // namespace android
214
215#endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H