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
17 #include "VirtualCameraSessionContext.h"
18
19 #include <memory>
20 #include <mutex>
21 #include <unordered_set>
22
23 #include "VirtualCameraStream.h"
24 #include "aidl/android/hardware/camera/device/StreamConfiguration.h"
25
26 namespace android {
27 namespace companion {
28 namespace virtualcamera {
29
30 using ::aidl::android::hardware::camera::device::BufferCache;
31 using ::aidl::android::hardware::camera::device::Stream;
32 using ::aidl::android::hardware::camera::device::StreamBuffer;
33 using ::aidl::android::hardware::camera::device::StreamConfiguration;
34
initializeStream(const::aidl::android::hardware::camera::device::Stream & stream)35 bool VirtualCameraSessionContext::initializeStream(
36 const ::aidl::android::hardware::camera::device::Stream& stream) {
37 std::lock_guard<std::mutex> lock(mLock);
38
39 auto s = std::make_unique<VirtualCameraStream>(stream);
40
41 const auto& [_, newlyInserted] = mStreams.emplace(
42 std::piecewise_construct, std::forward_as_tuple(stream.id),
43 std::forward_as_tuple(std::move(s)));
44 return newlyInserted;
45 }
46
closeAllStreams()47 void VirtualCameraSessionContext::closeAllStreams() {
48 std::lock_guard<std::mutex> lock(mLock);
49 mStreams.clear();
50 }
51
importBuffersFromCaptureRequest(const::aidl::android::hardware::camera::device::CaptureRequest & captureRequest)52 bool VirtualCameraSessionContext::importBuffersFromCaptureRequest(
53 const ::aidl::android::hardware::camera::device::CaptureRequest&
54 captureRequest) {
55 std::lock_guard<std::mutex> lock(mLock);
56
57 for (const StreamBuffer& buffer : captureRequest.outputBuffers) {
58 auto it = mStreams.find(buffer.streamId);
59 if (it == mStreams.end()) {
60 ALOGE("%s: Cannot import buffer for unknown stream with id %d", __func__,
61 buffer.streamId);
62 return false;
63 }
64 VirtualCameraStream& stream = *it->second;
65 if (stream.getHardwareBuffer(buffer.bufferId) != nullptr) {
66 // This buffer is already imported.
67 continue;
68 }
69
70 if (stream.importBuffer(buffer) == nullptr) {
71 ALOGE("%s: Failed to import buffer %" PRId64 " for streamId %d", __func__,
72 buffer.bufferId, buffer.streamId);
73 return false;
74 }
75 }
76
77 return true;
78 }
79
removeBufferCaches(const std::vector<BufferCache> & cachesToRemove)80 void VirtualCameraSessionContext::removeBufferCaches(
81 const std::vector<BufferCache>& cachesToRemove) {
82 std::lock_guard<std::mutex> lock(mLock);
83 for (const auto& bufferCache : cachesToRemove) {
84 auto it = mStreams.find(bufferCache.streamId);
85 if (it == mStreams.end()) {
86 ALOGE("%s: Ask to remove buffer %" PRId64 " from unknown stream %d",
87 __func__, bufferCache.bufferId, bufferCache.streamId);
88 continue;
89 }
90 if (it->second->removeBuffer(bufferCache.bufferId)) {
91 ALOGD("%s: Successfully removed buffer %" PRId64
92 " from cache of stream %d",
93 __func__, bufferCache.bufferId, bufferCache.streamId);
94 } else {
95 ALOGE("%s: Failed to remove buffer %" PRId64 " from cache of stream %d",
96 __func__, bufferCache.bufferId, bufferCache.streamId);
97 }
98 }
99 }
100
removeStreamsNotInStreamConfiguration(const StreamConfiguration & streamConfiguration)101 void VirtualCameraSessionContext::removeStreamsNotInStreamConfiguration(
102 const StreamConfiguration& streamConfiguration) {
103 std::unordered_set<int> newConfigurationStreamIds;
104 for (const Stream& stream : streamConfiguration.streams) {
105 newConfigurationStreamIds.insert(stream.id);
106 }
107
108 std::lock_guard<std::mutex> lock(mLock);
109 for (auto it = mStreams.begin(); it != mStreams.end();) {
110 if (newConfigurationStreamIds.find(it->first) ==
111 newConfigurationStreamIds.end()) {
112 ALOGV(
113 "Disposing of stream %d, since it is not referenced by new "
114 "configuration.",
115 it->first);
116 it = mStreams.erase(it);
117 } else {
118 ++it;
119 }
120 }
121 }
122
getStreamConfig(int streamId) const123 std::optional<Stream> VirtualCameraSessionContext::getStreamConfig(
124 int streamId) const {
125 std::lock_guard<std::mutex> lock(mLock);
126 auto it = mStreams.find(streamId);
127 if (it == mStreams.end()) {
128 ALOGE("%s: StreamBuffer references buffer of unknown streamId %d", __func__,
129 streamId);
130 return std::optional<Stream>();
131 }
132 VirtualCameraStream& stream = *it->second;
133 return {stream.getStreamConfig()};
134 }
135
fetchHardwareBuffer(const int streamId,const int bufferId) const136 std::shared_ptr<AHardwareBuffer> VirtualCameraSessionContext::fetchHardwareBuffer(
137 const int streamId, const int bufferId) const {
138 std::lock_guard<std::mutex> lock(mLock);
139 auto it = mStreams.find(streamId);
140 if (it == mStreams.end()) {
141 ALOGE("%s: StreamBuffer references buffer of unknown streamId %d", __func__,
142 streamId);
143 return nullptr;
144 }
145 VirtualCameraStream& stream = *it->second;
146 return stream.getHardwareBuffer(bufferId);
147 }
148
149 std::shared_ptr<EglFrameBuffer>
fetchOrCreateEglFramebuffer(const EGLDisplay eglDisplay,const int streamId,const int bufferId)150 VirtualCameraSessionContext::fetchOrCreateEglFramebuffer(
151 const EGLDisplay eglDisplay, const int streamId, const int bufferId) {
152 std::lock_guard<std::mutex> lock(mLock);
153 auto it = mStreams.find(streamId);
154 if (it == mStreams.end()) {
155 ALOGE("%s: StreamBuffer references buffer of unknown streamId %d", __func__,
156 streamId);
157 return nullptr;
158 }
159 VirtualCameraStream& stream = *it->second;
160 return stream.getEglFrameBuffer(eglDisplay, bufferId);
161 }
162
getStreamIds() const163 std::set<int> VirtualCameraSessionContext::getStreamIds() const {
164 std::set<int> result;
165 std::lock_guard<std::mutex> lock(mLock);
166 for (const auto& [streamId, _] : mStreams) {
167 result.insert(streamId);
168 }
169 return result;
170 }
171
172 } // namespace virtualcamera
173 } // namespace companion
174 } // namespace android
175