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