blob: aafed44402e8e6a721db67d75fddacdc326cc3d8 [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 Sebechlebsky18ac32c2024-06-07 09:53:53 +020026#include <variant>
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010027#include <vector>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010028
Vadim Caen550634d2024-07-17 14:01:21 +020029#include "VirtualCameraCaptureRequest.h"
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +010030#include "VirtualCameraDevice.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010031#include "VirtualCameraSessionContext.h"
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010032#include "aidl/android/hardware/camera/device/CameraMetadata.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010033#include "aidl/android/hardware/camera/device/ICameraDeviceCallback.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010034#include "android/binder_auto_utils.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010035#include "util/EglDisplayContext.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010036#include "util/EglFramebuffer.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010037#include "util/EglProgram.h"
38#include "util/EglSurfaceTexture.h"
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010039#include "util/Util.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010040
41namespace android {
42namespace companion {
43namespace virtualcamera {
44
45// Represents single output buffer of capture request.
46class CaptureRequestBuffer {
47 public:
48 CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr);
49
50 int getStreamId() const;
51 int getBufferId() const;
52 sp<Fence> getFence() const;
53
54 private:
55 const int mStreamId;
56 const int mBufferId;
57 const sp<Fence> mFence;
58};
59
60// Represents single capture request to fill set of buffers.
61class ProcessCaptureRequestTask {
62 public:
63 ProcessCaptureRequestTask(
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010064 int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers,
65 const RequestSettings& RequestSettings = {});
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010066
67 // Returns frame number corresponding to the request.
68 int getFrameNumber() const;
69
70 // Get reference to vector describing output buffers corresponding
71 // to this request.
72 //
73 // Note that the vector is owned by the ProcessCaptureRequestTask instance,
74 // so it cannot be access outside of its lifetime.
75 const std::vector<CaptureRequestBuffer>& getBuffers() const;
76
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010077 const RequestSettings& getRequestSettings() const;
78
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010079 private:
80 const int mFrameNumber;
81 const std::vector<CaptureRequestBuffer> mBuffers;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010082 const RequestSettings mRequestSettings;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010083};
84
Jan Sebechlebsky18ac32c2024-06-07 09:53:53 +020085struct UpdateTextureTask {};
86
87struct RenderThreadTask
88 : public std::variant<std::unique_ptr<ProcessCaptureRequestTask>,
89 UpdateTextureTask> {
90 // Allow implicit conversion to bool.
91 //
92 // Returns false, if the RenderThreadTask consist of null
93 // ProcessCaptureRequestTask, which signals that the thread should terminate.
94 operator bool() const {
95 const bool isExitSignal =
96 std::holds_alternative<std::unique_ptr<ProcessCaptureRequestTask>>(
97 *this) &&
98 std::get<std::unique_ptr<ProcessCaptureRequestTask>>(*this) == nullptr;
99 return !isExitSignal;
100 }
101};
102
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100103// Wraps dedicated rendering thread and rendering business with corresponding
104// input surface.
105class VirtualCameraRenderThread {
106 public:
107 // Create VirtualCameraRenderThread instance:
108 // * sessionContext - VirtualCameraSessionContext reference for shared access
109 // to mapped buffers.
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100110 // * inputSurfaceSize - requested size of input surface.
111 // * reportedSensorSize - reported static sensor size of virtual camera.
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100112 // * cameraDeviceCallback - callback for corresponding camera instance
113 // * testMode - when set to true, test pattern is rendered to input surface
114 // before each capture request is processed to simulate client input.
115 VirtualCameraRenderThread(
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100116 VirtualCameraSessionContext& sessionContext, Resolution inputSurfaceSize,
117 Resolution reportedSensorSize,
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100118 std::shared_ptr<
119 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
Jan Sebechlebsky288900f2024-05-24 14:47:54 +0200120 cameraDeviceCallback);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100121
122 ~VirtualCameraRenderThread();
123
124 // Start rendering thread.
125 void start();
126 // Stop rendering thread.
127 void stop();
128
Jan Sebechlebsky18ac32c2024-06-07 09:53:53 +0200129 // Send request to render thread to update the texture.
130 // Currently queued buffers in the input surface will be consumed and the most
131 // recent buffer in the input surface will be attached to the texture), all
132 // other buffers will be returned to the buffer queue.
133 void requestTextureUpdate() EXCLUDES(mLock);
134
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100135 // Equeue capture task for processing on render thread.
136 void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task)
137 EXCLUDES(mLock);
138
139 // Flush all in-flight requests.
140 void flush() EXCLUDES(mLock);
141
142 // Returns input surface corresponding to "virtual camera sensor".
143 sp<Surface> getInputSurface();
144
145 private:
Jan Sebechlebsky18ac32c2024-06-07 09:53:53 +0200146 RenderThreadTask dequeueTask() EXCLUDES(mLock);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100147
148 // Rendering thread entry point.
149 void threadLoop();
150
151 // Process single capture request task (always called on render thread).
Jan Sebechlebsky18ac32c2024-06-07 09:53:53 +0200152 void processTask(const ProcessCaptureRequestTask& captureRequestTask);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100153
154 // Flush single capture request task returning the error status immediately.
155 void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
156
157 // TODO(b/301023410) - Refactor the actual rendering logic off this class for
158 // easier testability.
159
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100160 // Create thumbnail with specified size for current image.
161 // The compressed image size is limited by 32KiB.
162 // Returns vector with compressed thumbnail if successful,
163 // empty vector otherwise.
164 std::vector<uint8_t> createThumbnail(Resolution resolution, int quality);
165
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100166 // Render current image to the BLOB buffer.
167 // If fence is specified, this function will block until the fence is cleared
168 // before writing to the buffer.
169 // Always called on render thread.
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100170 ndk::ScopedAStatus renderIntoBlobStreamBuffer(
171 const int streamId, const int bufferId,
Vadim Caenc0aff132024-03-12 17:20:07 +0100172 const ::aidl::android::hardware::camera::device::CameraMetadata&
173 resultMetadata,
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100174 const RequestSettings& requestSettings, sp<Fence> fence = nullptr);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100175
176 // Render current image to the YCbCr buffer.
177 // If fence is specified, this function will block until the fence is cleared
178 // before writing to the buffer.
179 // Always called on render thread.
180 ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId,
181 sp<Fence> fence = nullptr);
182
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100183 // Render current image into provided EglFramebuffer.
184 // If fence is specified, this function will block until the fence is cleared
185 // before writing to the buffer.
186 // Always called on the render thread.
Jan Sebechlebskyb3771312024-03-15 10:38:02 +0100187 ndk::ScopedAStatus renderIntoEglFramebuffer(
188 EglFrameBuffer& framebuffer, sp<Fence> fence = nullptr,
189 std::optional<Rect> viewport = std::nullopt);
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100190
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100191 // Camera callback
192 const std::shared_ptr<
193 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
194 mCameraDeviceCallback;
195
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100196 const Resolution mInputSurfaceSize;
197 const Resolution mReportedSensorSize;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100198
199 VirtualCameraSessionContext& mSessionContext;
200
201 std::thread mThread;
202
203 // Blocking queue implementation.
204 std::mutex mLock;
205 std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock);
206 std::condition_variable mCondVar;
Jan Sebechlebsky18ac32c2024-06-07 09:53:53 +0200207 volatile bool mTextureUpdateRequested GUARDED_BY(mLock);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100208 volatile bool mPendingExit GUARDED_BY(mLock);
209
Jan Sebechlebsky2f4478e2024-05-08 17:26:42 +0200210 // Acquisition timestamp of last frame.
211 std::atomic<uint64_t> mLastAcquisitionTimestampNanoseconds;
212
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100213 // EGL helpers - constructed and accessed only from rendering thread.
214 std::unique_ptr<EglDisplayContext> mEglDisplayContext;
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100215 std::unique_ptr<EglTextureProgram> mEglTextureYuvProgram;
216 std::unique_ptr<EglTextureProgram> mEglTextureRgbProgram;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100217 std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture;
218
219 std::promise<sp<Surface>> mInputSurfacePromise;
Jan Sebechlebsky9fcd0262024-05-31 15:20:09 +0200220 std::shared_future<sp<Surface>> mInputSurfaceFuture;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100221};
222
223} // namespace virtualcamera
224} // namespace companion
225} // namespace android
226
227#endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H