blob: e222d5b90b45dcb936dc78bbefd3581b4bfa64a2 [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 Sebechlebsky4ce32082024-02-14 16:02:11 +010020#include <cstdint>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010021#include <deque>
22#include <future>
23#include <memory>
24#include <thread>
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010025#include <vector>
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010026
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +010027#include "VirtualCameraDevice.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010028#include "VirtualCameraSessionContext.h"
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010029#include "aidl/android/hardware/camera/device/CameraMetadata.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010030#include "aidl/android/hardware/camera/device/ICameraDeviceCallback.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010031#include "android/binder_auto_utils.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010032#include "util/EglDisplayContext.h"
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +010033#include "util/EglFramebuffer.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010034#include "util/EglProgram.h"
35#include "util/EglSurfaceTexture.h"
Vadim Caen11dfd932024-03-05 09:57:20 +010036#include "util/MetadataUtil.h"
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010037#include "util/Util.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010038
39namespace android {
40namespace companion {
41namespace virtualcamera {
42
43// Represents single output buffer of capture request.
44class CaptureRequestBuffer {
45 public:
46 CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr);
47
48 int getStreamId() const;
49 int getBufferId() const;
50 sp<Fence> getFence() const;
51
52 private:
53 const int mStreamId;
54 const int mBufferId;
55 const sp<Fence> mFence;
56};
57
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010058struct RequestSettings {
59 int jpegQuality = VirtualCameraDevice::kDefaultJpegQuality;
Vadim Caenc0aff132024-03-12 17:20:07 +010060 int jpegOrientation = VirtualCameraDevice::kDefaultJpegOrientation;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010061 Resolution thumbnailResolution = Resolution(0, 0);
62 int thumbnailJpegQuality = VirtualCameraDevice::kDefaultJpegQuality;
Vadim Caenc0aff132024-03-12 17:20:07 +010063 std::optional<FpsRange> fpsRange;
Vadim Caen11dfd932024-03-05 09:57:20 +010064 camera_metadata_enum_android_control_capture_intent_t captureIntent =
65 VirtualCameraDevice::kDefaultCaptureIntent;
Vadim Caenc0aff132024-03-12 17:20:07 +010066 std::optional<GpsCoordinates> gpsCoordinates;
Vadim Caen6a43beb2024-04-12 15:06:42 +020067 std::optional<camera_metadata_enum_android_control_ae_precapture_trigger>
68 aePrecaptureTrigger;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010069};
70
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010071// Represents single capture request to fill set of buffers.
72class ProcessCaptureRequestTask {
73 public:
74 ProcessCaptureRequestTask(
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010075 int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers,
76 const RequestSettings& RequestSettings = {});
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010077
78 // Returns frame number corresponding to the request.
79 int getFrameNumber() const;
80
81 // Get reference to vector describing output buffers corresponding
82 // to this request.
83 //
84 // Note that the vector is owned by the ProcessCaptureRequestTask instance,
85 // so it cannot be access outside of its lifetime.
86 const std::vector<CaptureRequestBuffer>& getBuffers() const;
87
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010088 const RequestSettings& getRequestSettings() const;
89
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010090 private:
91 const int mFrameNumber;
92 const std::vector<CaptureRequestBuffer> mBuffers;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010093 const RequestSettings mRequestSettings;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010094};
95
96// Wraps dedicated rendering thread and rendering business with corresponding
97// input surface.
98class VirtualCameraRenderThread {
99 public:
100 // Create VirtualCameraRenderThread instance:
101 // * sessionContext - VirtualCameraSessionContext reference for shared access
102 // to mapped buffers.
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100103 // * inputSurfaceSize - requested size of input surface.
104 // * reportedSensorSize - reported static sensor size of virtual camera.
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100105 // * cameraDeviceCallback - callback for corresponding camera instance
106 // * testMode - when set to true, test pattern is rendered to input surface
107 // before each capture request is processed to simulate client input.
108 VirtualCameraRenderThread(
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100109 VirtualCameraSessionContext& sessionContext, Resolution inputSurfaceSize,
110 Resolution reportedSensorSize,
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100111 std::shared_ptr<
112 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
113 cameraDeviceCallback,
114 bool testMode = false);
115
116 ~VirtualCameraRenderThread();
117
118 // Start rendering thread.
119 void start();
120 // Stop rendering thread.
121 void stop();
122
123 // Equeue capture task for processing on render thread.
124 void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task)
125 EXCLUDES(mLock);
126
127 // Flush all in-flight requests.
128 void flush() EXCLUDES(mLock);
129
130 // Returns input surface corresponding to "virtual camera sensor".
131 sp<Surface> getInputSurface();
132
133 private:
134 std::unique_ptr<ProcessCaptureRequestTask> dequeueTask() EXCLUDES(mLock);
135
136 // Rendering thread entry point.
137 void threadLoop();
138
139 // Process single capture request task (always called on render thread).
140 void processCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
141
142 // Flush single capture request task returning the error status immediately.
143 void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
144
145 // TODO(b/301023410) - Refactor the actual rendering logic off this class for
146 // easier testability.
147
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100148 // Create thumbnail with specified size for current image.
149 // The compressed image size is limited by 32KiB.
150 // Returns vector with compressed thumbnail if successful,
151 // empty vector otherwise.
152 std::vector<uint8_t> createThumbnail(Resolution resolution, int quality);
153
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100154 // Render current image to the BLOB buffer.
155 // If fence is specified, this function will block until the fence is cleared
156 // before writing to the buffer.
157 // Always called on render thread.
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100158 ndk::ScopedAStatus renderIntoBlobStreamBuffer(
159 const int streamId, const int bufferId,
Vadim Caenc0aff132024-03-12 17:20:07 +0100160 const ::aidl::android::hardware::camera::device::CameraMetadata&
161 resultMetadata,
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100162 const RequestSettings& requestSettings, sp<Fence> fence = nullptr);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100163
164 // Render current image to the YCbCr buffer.
165 // If fence is specified, this function will block until the fence is cleared
166 // before writing to the buffer.
167 // Always called on render thread.
168 ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId,
169 sp<Fence> fence = nullptr);
170
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100171 // Render current image into provided EglFramebuffer.
172 // If fence is specified, this function will block until the fence is cleared
173 // before writing to the buffer.
174 // Always called on the render thread.
Jan Sebechlebskyb3771312024-03-15 10:38:02 +0100175 ndk::ScopedAStatus renderIntoEglFramebuffer(
176 EglFrameBuffer& framebuffer, sp<Fence> fence = nullptr,
177 std::optional<Rect> viewport = std::nullopt);
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100178
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100179 // Camera callback
180 const std::shared_ptr<
181 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
182 mCameraDeviceCallback;
183
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100184 const Resolution mInputSurfaceSize;
185 const Resolution mReportedSensorSize;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100186 const int mTestMode;
187
188 VirtualCameraSessionContext& mSessionContext;
189
190 std::thread mThread;
191
192 // Blocking queue implementation.
193 std::mutex mLock;
194 std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock);
195 std::condition_variable mCondVar;
196 volatile bool mPendingExit GUARDED_BY(mLock);
197
198 // EGL helpers - constructed and accessed only from rendering thread.
199 std::unique_ptr<EglDisplayContext> mEglDisplayContext;
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100200 std::unique_ptr<EglTextureProgram> mEglTextureYuvProgram;
201 std::unique_ptr<EglTextureProgram> mEglTextureRgbProgram;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100202 std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture;
203
204 std::promise<sp<Surface>> mInputSurfacePromise;
205};
206
207} // namespace virtualcamera
208} // namespace companion
209} // namespace android
210
211#endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H