• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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