1 /*
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 #ifndef ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERASTREAM_H
17 #define ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERASTREAM_H
18 
19 #include <cstdint>
20 #include <functional>
21 #include <memory>
22 #include <mutex>
23 #include <tuple>
24 #include <unordered_map>
25 
26 #include "EGL/egl.h"
27 #include "aidl/android/hardware/camera/device/Stream.h"
28 #include "aidl/android/hardware/camera/device/StreamBuffer.h"
29 #include "android/hardware_buffer.h"
30 #include "util/EglFramebuffer.h"
31 #include "utils/Mutex.h"
32 
33 namespace android {
34 namespace companion {
35 namespace virtualcamera {
36 
37 // Encapsulates buffer management for the set of buffers belonging to the single
38 // camera stream.
39 class VirtualCameraStream {
40  public:
41   VirtualCameraStream(
42       const ::aidl::android::hardware::camera::device::Stream& stream);
43 
44   std::shared_ptr<AHardwareBuffer> importBuffer(
45       const ::aidl::android::hardware::camera::device::StreamBuffer& streamBuffer);
46 
47   // Get AHardwareBuffer instance corresponding to StreamBuffer from camera AIDL.
48   // In case this is the first occurrence of the buffer, this will perform mapping
49   // and stores hardware buffer in cache for further use.
50   //
51   // Returns nullptr in case buffer cannot be mapped or retrieved from the cache.
52   std::shared_ptr<AHardwareBuffer> getHardwareBuffer(int bufferId)
53       EXCLUDES(mLock);
54 
55   std::shared_ptr<EglFrameBuffer> getEglFrameBuffer(const EGLDisplay eglDisplay,
56                                                     int bufferId)
57       EXCLUDES(mLock);
58 
59   // Un-maps the previously mapped buffer and removes it from the stream cache.
60   // Returns true if removal is successful, false otherwise.
61   bool removeBuffer(int bufferId) EXCLUDES(mLock);
62 
63   // Returns AIDL Stream instance containing configuration of this stream.
64   ::aidl::android::hardware::camera::device::Stream getStreamConfig() const;
65 
66  private:
67   std::shared_ptr<AHardwareBuffer> getHardwareBufferLocked(int bufferId)
68       REQUIRES(mLock);
69 
70   const ::aidl::android::hardware::camera::device::Stream mStreamConfig;
71   std::mutex mLock;
72 
73   // Cache for already mapped buffers, mapping bufferId -> AHardwareBuffer instance.
74   std::unordered_map<int, std::shared_ptr<AHardwareBuffer>> mBuffers
75       GUARDED_BY(mLock);
76 
77   using FramebufferMapKey = std::pair<int, EGLDisplay>;
78   struct FramebufferMapKeyHash {
operatorFramebufferMapKeyHash79     std::size_t operator()(const FramebufferMapKey& key) const {
80       return std::hash<int>{}(key.first) ^
81              (std::hash<void*>{}(reinterpret_cast<void*>(key.second)) << 1);
82     }
83   };
84   std::unordered_map<FramebufferMapKey, std::shared_ptr<EglFrameBuffer>,
85                      FramebufferMapKeyHash>
86       mEglFramebuffers GUARDED_BY(mLock);
87 };
88 
89 }  // namespace virtualcamera
90 }  // namespace companion
91 }  // namespace android
92 
93 #endif  // ANDROID_COMPANION_VIRTUALCAMERA_VIRTUALCAMERASTREAM_H
94