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