1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*ec779b8eSAndroid Build Coastguard Worker * 4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*ec779b8eSAndroid Build Coastguard Worker * 8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*ec779b8eSAndroid Build Coastguard Worker * 10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License. 15*ec779b8eSAndroid Build Coastguard Worker */ 16*ec779b8eSAndroid Build Coastguard Worker 17*ec779b8eSAndroid Build Coastguard Worker #ifndef ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H 18*ec779b8eSAndroid Build Coastguard Worker #define ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H 19*ec779b8eSAndroid Build Coastguard Worker 20*ec779b8eSAndroid Build Coastguard Worker #include <atomic> 21*ec779b8eSAndroid Build Coastguard Worker #include <chrono> 22*ec779b8eSAndroid Build Coastguard Worker #include <cstddef> 23*ec779b8eSAndroid Build Coastguard Worker #include <cstdint> 24*ec779b8eSAndroid Build Coastguard Worker #include <deque> 25*ec779b8eSAndroid Build Coastguard Worker #include <future> 26*ec779b8eSAndroid Build Coastguard Worker #include <memory> 27*ec779b8eSAndroid Build Coastguard Worker #include <thread> 28*ec779b8eSAndroid Build Coastguard Worker #include <variant> 29*ec779b8eSAndroid Build Coastguard Worker #include <vector> 30*ec779b8eSAndroid Build Coastguard Worker 31*ec779b8eSAndroid Build Coastguard Worker #include "VirtualCameraCaptureRequest.h" 32*ec779b8eSAndroid Build Coastguard Worker #include "VirtualCameraDevice.h" 33*ec779b8eSAndroid Build Coastguard Worker #include "VirtualCameraSessionContext.h" 34*ec779b8eSAndroid Build Coastguard Worker #include "aidl/android/hardware/camera/device/CameraMetadata.h" 35*ec779b8eSAndroid Build Coastguard Worker #include "aidl/android/hardware/camera/device/ICameraDeviceCallback.h" 36*ec779b8eSAndroid Build Coastguard Worker #include "android/binder_auto_utils.h" 37*ec779b8eSAndroid Build Coastguard Worker #include "util/EglDisplayContext.h" 38*ec779b8eSAndroid Build Coastguard Worker #include "util/EglFramebuffer.h" 39*ec779b8eSAndroid Build Coastguard Worker #include "util/EglProgram.h" 40*ec779b8eSAndroid Build Coastguard Worker #include "util/EglSurfaceTexture.h" 41*ec779b8eSAndroid Build Coastguard Worker #include "util/Util.h" 42*ec779b8eSAndroid Build Coastguard Worker 43*ec779b8eSAndroid Build Coastguard Worker namespace android { 44*ec779b8eSAndroid Build Coastguard Worker namespace companion { 45*ec779b8eSAndroid Build Coastguard Worker namespace virtualcamera { 46*ec779b8eSAndroid Build Coastguard Worker 47*ec779b8eSAndroid Build Coastguard Worker // Represents single output buffer of capture request. 48*ec779b8eSAndroid Build Coastguard Worker class CaptureRequestBuffer { 49*ec779b8eSAndroid Build Coastguard Worker public: 50*ec779b8eSAndroid Build Coastguard Worker CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr); 51*ec779b8eSAndroid Build Coastguard Worker 52*ec779b8eSAndroid Build Coastguard Worker int getStreamId() const; 53*ec779b8eSAndroid Build Coastguard Worker int getBufferId() const; 54*ec779b8eSAndroid Build Coastguard Worker sp<Fence> getFence() const; 55*ec779b8eSAndroid Build Coastguard Worker 56*ec779b8eSAndroid Build Coastguard Worker private: 57*ec779b8eSAndroid Build Coastguard Worker const int mStreamId; 58*ec779b8eSAndroid Build Coastguard Worker const int mBufferId; 59*ec779b8eSAndroid Build Coastguard Worker const sp<Fence> mFence; 60*ec779b8eSAndroid Build Coastguard Worker }; 61*ec779b8eSAndroid Build Coastguard Worker 62*ec779b8eSAndroid Build Coastguard Worker // Represents single capture request to fill set of buffers. 63*ec779b8eSAndroid Build Coastguard Worker class ProcessCaptureRequestTask { 64*ec779b8eSAndroid Build Coastguard Worker public: 65*ec779b8eSAndroid Build Coastguard Worker ProcessCaptureRequestTask( 66*ec779b8eSAndroid Build Coastguard Worker int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers, 67*ec779b8eSAndroid Build Coastguard Worker const RequestSettings& RequestSettings = {}); 68*ec779b8eSAndroid Build Coastguard Worker 69*ec779b8eSAndroid Build Coastguard Worker // Returns frame number corresponding to the request. 70*ec779b8eSAndroid Build Coastguard Worker int getFrameNumber() const; 71*ec779b8eSAndroid Build Coastguard Worker 72*ec779b8eSAndroid Build Coastguard Worker // Get reference to vector describing output buffers corresponding 73*ec779b8eSAndroid Build Coastguard Worker // to this request. 74*ec779b8eSAndroid Build Coastguard Worker // 75*ec779b8eSAndroid Build Coastguard Worker // Note that the vector is owned by the ProcessCaptureRequestTask instance, 76*ec779b8eSAndroid Build Coastguard Worker // so it cannot be access outside of its lifetime. 77*ec779b8eSAndroid Build Coastguard Worker const std::vector<CaptureRequestBuffer>& getBuffers() const; 78*ec779b8eSAndroid Build Coastguard Worker 79*ec779b8eSAndroid Build Coastguard Worker const RequestSettings& getRequestSettings() const; 80*ec779b8eSAndroid Build Coastguard Worker 81*ec779b8eSAndroid Build Coastguard Worker private: 82*ec779b8eSAndroid Build Coastguard Worker const int mFrameNumber; 83*ec779b8eSAndroid Build Coastguard Worker const std::vector<CaptureRequestBuffer> mBuffers; 84*ec779b8eSAndroid Build Coastguard Worker const RequestSettings mRequestSettings; 85*ec779b8eSAndroid Build Coastguard Worker }; 86*ec779b8eSAndroid Build Coastguard Worker 87*ec779b8eSAndroid Build Coastguard Worker struct UpdateTextureTask {}; 88*ec779b8eSAndroid Build Coastguard Worker 89*ec779b8eSAndroid Build Coastguard Worker struct RenderThreadTask 90*ec779b8eSAndroid Build Coastguard Worker : public std::variant<std::unique_ptr<ProcessCaptureRequestTask>, 91*ec779b8eSAndroid Build Coastguard Worker UpdateTextureTask> { 92*ec779b8eSAndroid Build Coastguard Worker // Allow implicit conversion to bool. 93*ec779b8eSAndroid Build Coastguard Worker // 94*ec779b8eSAndroid Build Coastguard Worker // Returns false, if the RenderThreadTask consist of null 95*ec779b8eSAndroid Build Coastguard Worker // ProcessCaptureRequestTask, which signals that the thread should terminate. 96*ec779b8eSAndroid Build Coastguard Worker operator bool() const { 97*ec779b8eSAndroid Build Coastguard Worker const bool isExitSignal = 98*ec779b8eSAndroid Build Coastguard Worker std::holds_alternative<std::unique_ptr<ProcessCaptureRequestTask>>( 99*ec779b8eSAndroid Build Coastguard Worker *this) && 100*ec779b8eSAndroid Build Coastguard Worker std::get<std::unique_ptr<ProcessCaptureRequestTask>>(*this) == nullptr; 101*ec779b8eSAndroid Build Coastguard Worker return !isExitSignal; 102*ec779b8eSAndroid Build Coastguard Worker } 103*ec779b8eSAndroid Build Coastguard Worker }; 104*ec779b8eSAndroid Build Coastguard Worker 105*ec779b8eSAndroid Build Coastguard Worker // Wraps dedicated rendering thread and rendering business with corresponding 106*ec779b8eSAndroid Build Coastguard Worker // input surface. 107*ec779b8eSAndroid Build Coastguard Worker class VirtualCameraRenderThread { 108*ec779b8eSAndroid Build Coastguard Worker public: 109*ec779b8eSAndroid Build Coastguard Worker // Create VirtualCameraRenderThread instance: 110*ec779b8eSAndroid Build Coastguard Worker // * sessionContext - VirtualCameraSessionContext reference for shared access 111*ec779b8eSAndroid Build Coastguard Worker // to mapped buffers. 112*ec779b8eSAndroid Build Coastguard Worker // * inputSurfaceSize - requested size of input surface. 113*ec779b8eSAndroid Build Coastguard Worker // * reportedSensorSize - reported static sensor size of virtual camera. 114*ec779b8eSAndroid Build Coastguard Worker // * cameraDeviceCallback - callback for corresponding camera instance 115*ec779b8eSAndroid Build Coastguard Worker // * testMode - when set to true, test pattern is rendered to input surface 116*ec779b8eSAndroid Build Coastguard Worker // before each capture request is processed to simulate client input. 117*ec779b8eSAndroid Build Coastguard Worker VirtualCameraRenderThread( 118*ec779b8eSAndroid Build Coastguard Worker VirtualCameraSessionContext& sessionContext, Resolution inputSurfaceSize, 119*ec779b8eSAndroid Build Coastguard Worker Resolution reportedSensorSize, 120*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr< 121*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::camera::device::ICameraDeviceCallback> 122*ec779b8eSAndroid Build Coastguard Worker cameraDeviceCallback); 123*ec779b8eSAndroid Build Coastguard Worker 124*ec779b8eSAndroid Build Coastguard Worker ~VirtualCameraRenderThread(); 125*ec779b8eSAndroid Build Coastguard Worker 126*ec779b8eSAndroid Build Coastguard Worker // Start rendering thread. 127*ec779b8eSAndroid Build Coastguard Worker void start(); 128*ec779b8eSAndroid Build Coastguard Worker // Stop rendering thread. 129*ec779b8eSAndroid Build Coastguard Worker void stop(); 130*ec779b8eSAndroid Build Coastguard Worker 131*ec779b8eSAndroid Build Coastguard Worker // Send request to render thread to update the texture. 132*ec779b8eSAndroid Build Coastguard Worker // Currently queued buffers in the input surface will be consumed and the most 133*ec779b8eSAndroid Build Coastguard Worker // recent buffer in the input surface will be attached to the texture), all 134*ec779b8eSAndroid Build Coastguard Worker // other buffers will be returned to the buffer queue. 135*ec779b8eSAndroid Build Coastguard Worker void requestTextureUpdate() EXCLUDES(mLock); 136*ec779b8eSAndroid Build Coastguard Worker 137*ec779b8eSAndroid Build Coastguard Worker // Equeue capture task for processing on render thread. 138*ec779b8eSAndroid Build Coastguard Worker void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task) 139*ec779b8eSAndroid Build Coastguard Worker EXCLUDES(mLock); 140*ec779b8eSAndroid Build Coastguard Worker 141*ec779b8eSAndroid Build Coastguard Worker // Flush all in-flight requests. 142*ec779b8eSAndroid Build Coastguard Worker void flush() EXCLUDES(mLock); 143*ec779b8eSAndroid Build Coastguard Worker 144*ec779b8eSAndroid Build Coastguard Worker // Returns input surface corresponding to "virtual camera sensor". 145*ec779b8eSAndroid Build Coastguard Worker sp<Surface> getInputSurface(); 146*ec779b8eSAndroid Build Coastguard Worker 147*ec779b8eSAndroid Build Coastguard Worker private: 148*ec779b8eSAndroid Build Coastguard Worker RenderThreadTask dequeueTask() EXCLUDES(mLock); 149*ec779b8eSAndroid Build Coastguard Worker 150*ec779b8eSAndroid Build Coastguard Worker // Rendering thread entry point. 151*ec779b8eSAndroid Build Coastguard Worker void threadLoop(); 152*ec779b8eSAndroid Build Coastguard Worker 153*ec779b8eSAndroid Build Coastguard Worker // Process single capture request task (always called on render thread). 154*ec779b8eSAndroid Build Coastguard Worker void processTask(const ProcessCaptureRequestTask& captureRequestTask); 155*ec779b8eSAndroid Build Coastguard Worker 156*ec779b8eSAndroid Build Coastguard Worker // Flush single capture request task returning the error status immediately. 157*ec779b8eSAndroid Build Coastguard Worker void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask); 158*ec779b8eSAndroid Build Coastguard Worker 159*ec779b8eSAndroid Build Coastguard Worker // TODO(b/301023410) - Refactor the actual rendering logic off this class for 160*ec779b8eSAndroid Build Coastguard Worker // easier testability. 161*ec779b8eSAndroid Build Coastguard Worker 162*ec779b8eSAndroid Build Coastguard Worker // Create thumbnail with specified size for current image. 163*ec779b8eSAndroid Build Coastguard Worker // The compressed image size is limited by 32KiB. 164*ec779b8eSAndroid Build Coastguard Worker // Returns vector with compressed thumbnail if successful, 165*ec779b8eSAndroid Build Coastguard Worker // empty vector otherwise. 166*ec779b8eSAndroid Build Coastguard Worker std::vector<uint8_t> createThumbnail(Resolution resolution, int quality); 167*ec779b8eSAndroid Build Coastguard Worker 168*ec779b8eSAndroid Build Coastguard Worker // Render current image to the BLOB buffer. 169*ec779b8eSAndroid Build Coastguard Worker // If fence is specified, this function will block until the fence is cleared 170*ec779b8eSAndroid Build Coastguard Worker // before writing to the buffer. 171*ec779b8eSAndroid Build Coastguard Worker // Always called on render thread. 172*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus renderIntoBlobStreamBuffer( 173*ec779b8eSAndroid Build Coastguard Worker const int streamId, const int bufferId, 174*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::camera::device::CameraMetadata& 175*ec779b8eSAndroid Build Coastguard Worker resultMetadata, 176*ec779b8eSAndroid Build Coastguard Worker const RequestSettings& requestSettings, sp<Fence> fence = nullptr); 177*ec779b8eSAndroid Build Coastguard Worker 178*ec779b8eSAndroid Build Coastguard Worker // Render current image to the YCbCr buffer. 179*ec779b8eSAndroid Build Coastguard Worker // If fence is specified, this function will block until the fence is cleared 180*ec779b8eSAndroid Build Coastguard Worker // before writing to the buffer. 181*ec779b8eSAndroid Build Coastguard Worker // Always called on render thread. 182*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId, 183*ec779b8eSAndroid Build Coastguard Worker sp<Fence> fence = nullptr); 184*ec779b8eSAndroid Build Coastguard Worker 185*ec779b8eSAndroid Build Coastguard Worker // Render current image into provided EglFramebuffer. 186*ec779b8eSAndroid Build Coastguard Worker // If fence is specified, this function will block until the fence is cleared 187*ec779b8eSAndroid Build Coastguard Worker // before writing to the buffer. 188*ec779b8eSAndroid Build Coastguard Worker // Always called on the render thread. 189*ec779b8eSAndroid Build Coastguard Worker ndk::ScopedAStatus renderIntoEglFramebuffer( 190*ec779b8eSAndroid Build Coastguard Worker EglFrameBuffer& framebuffer, sp<Fence> fence = nullptr, 191*ec779b8eSAndroid Build Coastguard Worker std::optional<Rect> viewport = std::nullopt); 192*ec779b8eSAndroid Build Coastguard Worker 193*ec779b8eSAndroid Build Coastguard Worker // Throttle the current thread to ensure that we are not rendering faster than 194*ec779b8eSAndroid Build Coastguard Worker // the provided maxFps. 195*ec779b8eSAndroid Build Coastguard Worker // maxFps: The maximum fps in the capture request 196*ec779b8eSAndroid Build Coastguard Worker // lastAcquisitionTimestamp: timestamp of the previous frame 197*ec779b8eSAndroid Build Coastguard Worker // timestamp: the current capture time 198*ec779b8eSAndroid Build Coastguard Worker // Returns the time at which the capture has happened after throttling. 199*ec779b8eSAndroid Build Coastguard Worker std::chrono::nanoseconds throttleRendering( 200*ec779b8eSAndroid Build Coastguard Worker int maxFps, std::chrono::nanoseconds lastAcquisitionTimestamp, 201*ec779b8eSAndroid Build Coastguard Worker std::chrono::nanoseconds timestamp); 202*ec779b8eSAndroid Build Coastguard Worker 203*ec779b8eSAndroid Build Coastguard Worker // Fetch the timestamp of the latest buffer from the EGL Surface 204*ec779b8eSAndroid Build Coastguard Worker // timeSinceLastFrame: The elapsed time since the last captured frame. 205*ec779b8eSAndroid Build Coastguard Worker // Return 0 if no timestamp has been associated to this surface by the producer. 206*ec779b8eSAndroid Build Coastguard Worker std::chrono::nanoseconds getSurfaceTimestamp( 207*ec779b8eSAndroid Build Coastguard Worker std::chrono::nanoseconds timeSinceLastFrame); 208*ec779b8eSAndroid Build Coastguard Worker 209*ec779b8eSAndroid Build Coastguard Worker // Build a default capture result object populating the metadata from the request. 210*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<::aidl::android::hardware::camera::device::CaptureResult> 211*ec779b8eSAndroid Build Coastguard Worker createCaptureResult( 212*ec779b8eSAndroid Build Coastguard Worker int frameNumber, 213*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<aidl::android::hardware::camera::device::CameraMetadata> 214*ec779b8eSAndroid Build Coastguard Worker metadata); 215*ec779b8eSAndroid Build Coastguard Worker 216*ec779b8eSAndroid Build Coastguard Worker // Renders the images from the input surface into the request's buffers. 217*ec779b8eSAndroid Build Coastguard Worker void renderOutputBuffers( 218*ec779b8eSAndroid Build Coastguard Worker const ProcessCaptureRequestTask& request, 219*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::camera::device::CaptureResult& captureResult); 220*ec779b8eSAndroid Build Coastguard Worker 221*ec779b8eSAndroid Build Coastguard Worker // Notify a shutter event for all the buffers in this request. 222*ec779b8eSAndroid Build Coastguard Worker ::ndk::ScopedAStatus notifyShutter( 223*ec779b8eSAndroid Build Coastguard Worker const ProcessCaptureRequestTask& request, 224*ec779b8eSAndroid Build Coastguard Worker const ::aidl::android::hardware::camera::device::CaptureResult& captureResult, 225*ec779b8eSAndroid Build Coastguard Worker std::chrono::nanoseconds captureTimestamp); 226*ec779b8eSAndroid Build Coastguard Worker 227*ec779b8eSAndroid Build Coastguard Worker // Notify a timeout error for this request. The capture result still needs to 228*ec779b8eSAndroid Build Coastguard Worker // be submitted after this call. 229*ec779b8eSAndroid Build Coastguard Worker ::ndk::ScopedAStatus notifyTimeout( 230*ec779b8eSAndroid Build Coastguard Worker const ProcessCaptureRequestTask& request, 231*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::camera::device::CaptureResult& captureResult); 232*ec779b8eSAndroid Build Coastguard Worker 233*ec779b8eSAndroid Build Coastguard Worker // Submit the capture result to the camera callback. 234*ec779b8eSAndroid Build Coastguard Worker ::ndk::ScopedAStatus submitCaptureResult( 235*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<::aidl::android::hardware::camera::device::CaptureResult> 236*ec779b8eSAndroid Build Coastguard Worker captureResult); 237*ec779b8eSAndroid Build Coastguard Worker 238*ec779b8eSAndroid Build Coastguard Worker // Camera callback 239*ec779b8eSAndroid Build Coastguard Worker const std::shared_ptr< 240*ec779b8eSAndroid Build Coastguard Worker ::aidl::android::hardware::camera::device::ICameraDeviceCallback> 241*ec779b8eSAndroid Build Coastguard Worker mCameraDeviceCallback; 242*ec779b8eSAndroid Build Coastguard Worker 243*ec779b8eSAndroid Build Coastguard Worker const Resolution mInputSurfaceSize; 244*ec779b8eSAndroid Build Coastguard Worker const Resolution mReportedSensorSize; 245*ec779b8eSAndroid Build Coastguard Worker 246*ec779b8eSAndroid Build Coastguard Worker VirtualCameraSessionContext& mSessionContext; 247*ec779b8eSAndroid Build Coastguard Worker 248*ec779b8eSAndroid Build Coastguard Worker std::thread mThread; 249*ec779b8eSAndroid Build Coastguard Worker 250*ec779b8eSAndroid Build Coastguard Worker // Blocking queue implementation. 251*ec779b8eSAndroid Build Coastguard Worker std::mutex mLock; 252*ec779b8eSAndroid Build Coastguard Worker std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock); 253*ec779b8eSAndroid Build Coastguard Worker std::condition_variable mCondVar; 254*ec779b8eSAndroid Build Coastguard Worker volatile bool GUARDED_BY(mLock) mTextureUpdateRequested = false; 255*ec779b8eSAndroid Build Coastguard Worker volatile bool GUARDED_BY(mLock) mPendingExit = false; 256*ec779b8eSAndroid Build Coastguard Worker 257*ec779b8eSAndroid Build Coastguard Worker // Acquisition timestamp of last frame. 258*ec779b8eSAndroid Build Coastguard Worker std::atomic<uint64_t> mLastAcquisitionTimestampNanoseconds; 259*ec779b8eSAndroid Build Coastguard Worker std::atomic<uint64_t> mLastSurfaceTimestampNanoseconds; 260*ec779b8eSAndroid Build Coastguard Worker 261*ec779b8eSAndroid Build Coastguard Worker // EGL helpers - constructed and accessed only from rendering thread. 262*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<EglDisplayContext> mEglDisplayContext; 263*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<EglTextureProgram> mEglTextureYuvProgram; 264*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<EglTextureProgram> mEglTextureRgbProgram; 265*ec779b8eSAndroid Build Coastguard Worker std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture; 266*ec779b8eSAndroid Build Coastguard Worker 267*ec779b8eSAndroid Build Coastguard Worker std::promise<sp<Surface>> mInputSurfacePromise; 268*ec779b8eSAndroid Build Coastguard Worker std::shared_future<sp<Surface>> mInputSurfaceFuture; 269*ec779b8eSAndroid Build Coastguard Worker }; 270*ec779b8eSAndroid Build Coastguard Worker 271*ec779b8eSAndroid Build Coastguard Worker } // namespace virtualcamera 272*ec779b8eSAndroid Build Coastguard Worker } // namespace companion 273*ec779b8eSAndroid Build Coastguard Worker } // namespace android 274*ec779b8eSAndroid Build Coastguard Worker 275*ec779b8eSAndroid Build Coastguard Worker #endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H 276