blob: 86dad0b5ffead4c3f240486719fb96bdfebd36b4 [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"
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010036#include "util/Util.h"
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010037
38namespace android {
39namespace companion {
40namespace virtualcamera {
41
42// Represents single output buffer of capture request.
43class CaptureRequestBuffer {
44 public:
45 CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr);
46
47 int getStreamId() const;
48 int getBufferId() const;
49 sp<Fence> getFence() const;
50
51 private:
52 const int mStreamId;
53 const int mBufferId;
54 const sp<Fence> mFence;
55};
56
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010057struct RequestSettings {
58 int jpegQuality = VirtualCameraDevice::kDefaultJpegQuality;
59 Resolution thumbnailResolution = Resolution(0, 0);
60 int thumbnailJpegQuality = VirtualCameraDevice::kDefaultJpegQuality;
61};
62
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010063// Represents single capture request to fill set of buffers.
64class ProcessCaptureRequestTask {
65 public:
66 ProcessCaptureRequestTask(
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010067 int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers,
68 const RequestSettings& RequestSettings = {});
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010069
70 // Returns frame number corresponding to the request.
71 int getFrameNumber() const;
72
73 // Get reference to vector describing output buffers corresponding
74 // to this request.
75 //
76 // Note that the vector is owned by the ProcessCaptureRequestTask instance,
77 // so it cannot be access outside of its lifetime.
78 const std::vector<CaptureRequestBuffer>& getBuffers() const;
79
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010080 const RequestSettings& getRequestSettings() const;
81
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010082 private:
83 const int mFrameNumber;
84 const std::vector<CaptureRequestBuffer> mBuffers;
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +010085 const RequestSettings mRequestSettings;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010086};
87
88// Wraps dedicated rendering thread and rendering business with corresponding
89// input surface.
90class VirtualCameraRenderThread {
91 public:
92 // Create VirtualCameraRenderThread instance:
93 // * sessionContext - VirtualCameraSessionContext reference for shared access
94 // to mapped buffers.
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +010095 // * inputSurfaceSize - requested size of input surface.
96 // * reportedSensorSize - reported static sensor size of virtual camera.
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +010097 // * cameraDeviceCallback - callback for corresponding camera instance
98 // * testMode - when set to true, test pattern is rendered to input surface
99 // before each capture request is processed to simulate client input.
100 VirtualCameraRenderThread(
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100101 VirtualCameraSessionContext& sessionContext, Resolution inputSurfaceSize,
102 Resolution reportedSensorSize,
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100103 std::shared_ptr<
104 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
105 cameraDeviceCallback,
106 bool testMode = false);
107
108 ~VirtualCameraRenderThread();
109
110 // Start rendering thread.
111 void start();
112 // Stop rendering thread.
113 void stop();
114
115 // Equeue capture task for processing on render thread.
116 void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task)
117 EXCLUDES(mLock);
118
119 // Flush all in-flight requests.
120 void flush() EXCLUDES(mLock);
121
122 // Returns input surface corresponding to "virtual camera sensor".
123 sp<Surface> getInputSurface();
124
125 private:
126 std::unique_ptr<ProcessCaptureRequestTask> dequeueTask() EXCLUDES(mLock);
127
128 // Rendering thread entry point.
129 void threadLoop();
130
131 // Process single capture request task (always called on render thread).
132 void processCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
133
134 // Flush single capture request task returning the error status immediately.
135 void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
136
137 // TODO(b/301023410) - Refactor the actual rendering logic off this class for
138 // easier testability.
139
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100140 // Create thumbnail with specified size for current image.
141 // The compressed image size is limited by 32KiB.
142 // Returns vector with compressed thumbnail if successful,
143 // empty vector otherwise.
144 std::vector<uint8_t> createThumbnail(Resolution resolution, int quality);
145
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100146 // Render current image to the BLOB buffer.
147 // If fence is specified, this function will block until the fence is cleared
148 // before writing to the buffer.
149 // Always called on render thread.
Jan Sebechlebsky4ce32082024-02-14 16:02:11 +0100150 ndk::ScopedAStatus renderIntoBlobStreamBuffer(
151 const int streamId, const int bufferId,
152 const RequestSettings& requestSettings, sp<Fence> fence = nullptr);
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100153
154 // Render current image to the YCbCr 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.
158 ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId,
159 sp<Fence> fence = nullptr);
160
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100161 // Render current image into provided EglFramebuffer.
162 // If fence is specified, this function will block until the fence is cleared
163 // before writing to the buffer.
164 // Always called on the render thread.
165 ndk::ScopedAStatus renderIntoEglFramebuffer(EglFrameBuffer& framebuffer,
166 sp<Fence> fence = nullptr);
167
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100168 // Camera callback
169 const std::shared_ptr<
170 ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
171 mCameraDeviceCallback;
172
Jan Sebechlebskybb01c1d2024-02-12 11:41:37 +0100173 const Resolution mInputSurfaceSize;
174 const Resolution mReportedSensorSize;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100175 const int mTestMode;
176
177 VirtualCameraSessionContext& mSessionContext;
178
179 std::thread mThread;
180
181 // Blocking queue implementation.
182 std::mutex mLock;
183 std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock);
184 std::condition_variable mCondVar;
185 volatile bool mPendingExit GUARDED_BY(mLock);
186
187 // EGL helpers - constructed and accessed only from rendering thread.
188 std::unique_ptr<EglDisplayContext> mEglDisplayContext;
Jan Sebechlebsky042d1fb2023-12-12 16:37:00 +0100189 std::unique_ptr<EglTextureProgram> mEglTextureYuvProgram;
190 std::unique_ptr<EglTextureProgram> mEglTextureRgbProgram;
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +0100191 std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture;
192
193 std::promise<sp<Surface>> mInputSurfacePromise;
194};
195
196} // namespace virtualcamera
197} // namespace companion
198} // namespace android
199
200#endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H