Move virtual camera service to frameworks/av/services
Bug: 311647154
Bug: 301023410
Test: atest virtual_camera_tests
Test: build & flash & adb shell cmd virtual_camera help
Change-Id: I6d43a2b70f454c9c01ec2abcae9f138cd78c6a85
diff --git a/services/camera/virtualcamera/VirtualCameraRenderThread.h b/services/camera/virtualcamera/VirtualCameraRenderThread.h
new file mode 100644
index 0000000..30de7c2
--- /dev/null
+++ b/services/camera/virtualcamera/VirtualCameraRenderThread.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H
+#define ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H
+
+#include <deque>
+#include <future>
+#include <memory>
+#include <thread>
+
+#include "VirtualCameraSessionContext.h"
+#include "aidl/android/hardware/camera/device/ICameraDeviceCallback.h"
+#include "util/EglDisplayContext.h"
+#include "util/EglProgram.h"
+#include "util/EglSurfaceTexture.h"
+
+namespace android {
+namespace companion {
+namespace virtualcamera {
+
+// Represents single output buffer of capture request.
+class CaptureRequestBuffer {
+ public:
+ CaptureRequestBuffer(int streamId, int bufferId, sp<Fence> fence = nullptr);
+
+ int getStreamId() const;
+ int getBufferId() const;
+ sp<Fence> getFence() const;
+
+ private:
+ const int mStreamId;
+ const int mBufferId;
+ const sp<Fence> mFence;
+};
+
+// Represents single capture request to fill set of buffers.
+class ProcessCaptureRequestTask {
+ public:
+ ProcessCaptureRequestTask(
+ int frameNumber, const std::vector<CaptureRequestBuffer>& requestBuffers);
+
+ // Returns frame number corresponding to the request.
+ int getFrameNumber() const;
+
+ // Get reference to vector describing output buffers corresponding
+ // to this request.
+ //
+ // Note that the vector is owned by the ProcessCaptureRequestTask instance,
+ // so it cannot be access outside of its lifetime.
+ const std::vector<CaptureRequestBuffer>& getBuffers() const;
+
+ private:
+ const int mFrameNumber;
+ const std::vector<CaptureRequestBuffer> mBuffers;
+};
+
+// Wraps dedicated rendering thread and rendering business with corresponding
+// input surface.
+class VirtualCameraRenderThread {
+ public:
+ // Create VirtualCameraRenderThread instance:
+ // * sessionContext - VirtualCameraSessionContext reference for shared access
+ // to mapped buffers.
+ // * inputWidth - requested width of input surface ("virtual camera sensor")
+ // * inputHeight - requested height of input surface ("virtual camera sensor")
+ // * cameraDeviceCallback - callback for corresponding camera instance
+ // * testMode - when set to true, test pattern is rendered to input surface
+ // before each capture request is processed to simulate client input.
+ VirtualCameraRenderThread(
+ VirtualCameraSessionContext& sessionContext, int inputWidth,
+ int inputHeight,
+ std::shared_ptr<
+ ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
+ cameraDeviceCallback,
+ bool testMode = false);
+
+ ~VirtualCameraRenderThread();
+
+ // Start rendering thread.
+ void start();
+ // Stop rendering thread.
+ void stop();
+
+ // Equeue capture task for processing on render thread.
+ void enqueueTask(std::unique_ptr<ProcessCaptureRequestTask> task)
+ EXCLUDES(mLock);
+
+ // Flush all in-flight requests.
+ void flush() EXCLUDES(mLock);
+
+ // Returns input surface corresponding to "virtual camera sensor".
+ sp<Surface> getInputSurface();
+
+ private:
+ std::unique_ptr<ProcessCaptureRequestTask> dequeueTask() EXCLUDES(mLock);
+
+ // Rendering thread entry point.
+ void threadLoop();
+
+ // Process single capture request task (always called on render thread).
+ void processCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
+
+ // Flush single capture request task returning the error status immediately.
+ void flushCaptureRequest(const ProcessCaptureRequestTask& captureRequestTask);
+
+ // TODO(b/301023410) - Refactor the actual rendering logic off this class for
+ // easier testability.
+
+ // Render current image to the BLOB buffer.
+ // If fence is specified, this function will block until the fence is cleared
+ // before writing to the buffer.
+ // Always called on render thread.
+ ndk::ScopedAStatus renderIntoBlobStreamBuffer(const int streamId,
+ const int bufferId,
+ const size_t bufferSize,
+ sp<Fence> fence = nullptr);
+
+ // Render current image to the YCbCr buffer.
+ // If fence is specified, this function will block until the fence is cleared
+ // before writing to the buffer.
+ // Always called on render thread.
+ ndk::ScopedAStatus renderIntoImageStreamBuffer(int streamId, int bufferId,
+ sp<Fence> fence = nullptr);
+
+ // Camera callback
+ const std::shared_ptr<
+ ::aidl::android::hardware::camera::device::ICameraDeviceCallback>
+ mCameraDeviceCallback;
+
+ const int mInputSurfaceWidth;
+ const int mInputSurfaceHeight;
+ const int mTestMode;
+
+ VirtualCameraSessionContext& mSessionContext;
+
+ std::thread mThread;
+
+ // Blocking queue implementation.
+ std::mutex mLock;
+ std::deque<std::unique_ptr<ProcessCaptureRequestTask>> mQueue GUARDED_BY(mLock);
+ std::condition_variable mCondVar;
+ volatile bool mPendingExit GUARDED_BY(mLock);
+
+ // EGL helpers - constructed and accessed only from rendering thread.
+ std::unique_ptr<EglDisplayContext> mEglDisplayContext;
+ std::unique_ptr<EglTextureProgram> mEglTextureProgram;
+ std::unique_ptr<EglSurfaceTexture> mEglSurfaceTexture;
+
+ std::promise<sp<Surface>> mInputSurfacePromise;
+};
+
+} // namespace virtualcamera
+} // namespace companion
+} // namespace android
+
+#endif // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERARENDERTHREAD_H