blob: 284ad05b23efe74ad92deb99eb3af061dbfd0f8c [file] [log] [blame]
Jan Sebechlebsky5cb39962023-11-22 17:33:07 +01001/*
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
26namespace android {
27namespace companion {
28namespace virtualcamera {
29
30using ::aidl::android::hardware::camera::device::BufferCache;
31using ::aidl::android::hardware::camera::device::Stream;
32using ::aidl::android::hardware::camera::device::StreamBuffer;
33using ::aidl::android::hardware::camera::device::StreamConfiguration;
34
35bool 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
47void VirtualCameraSessionContext::closeAllStreams() {
48 std::lock_guard<std::mutex> lock(mLock);
49 mStreams.clear();
50}
51
52bool 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
80void 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
101void 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
123std::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 return {it->second->getStreamConfig()};
133}
134
135std::shared_ptr<AHardwareBuffer> VirtualCameraSessionContext::fetchHardwareBuffer(
136 const int streamId, const int bufferId) const {
137 std::lock_guard<std::mutex> lock(mLock);
138 auto it = mStreams.find(streamId);
139 if (it == mStreams.end()) {
140 ALOGE("%s: StreamBuffer references buffer of unknown streamId %d", __func__,
141 streamId);
142 return nullptr;
143 }
144 return it->second->getHardwareBuffer(bufferId);
145}
146
147std::shared_ptr<EglFrameBuffer>
148VirtualCameraSessionContext::fetchOrCreateEglFramebuffer(
149 const EGLDisplay eglDisplay, const int streamId, const int bufferId) {
150 std::lock_guard<std::mutex> lock(mLock);
151 auto it = mStreams.find(streamId);
152 if (it == mStreams.end()) {
153 ALOGE("%s: StreamBuffer references buffer of unknown streamId %d", __func__,
154 streamId);
155 return nullptr;
156 }
157 return it->second->getEglFrameBuffer(eglDisplay, bufferId);
158}
159
160std::set<int> VirtualCameraSessionContext::getStreamIds() const {
161 std::set<int> result;
162 std::lock_guard<std::mutex> lock(mLock);
163 for (const auto& [streamId, _] : mStreams) {
164 result.insert(streamId);
165 }
166 return result;
167}
168
169} // namespace virtualcamera
170} // namespace companion
171} // namespace android