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 #pragma once 18 19 #include "EvsCameraBase.h" 20 21 #include <aidl/android/hardware/automotive/evs/IEvsCameraStream.h> 22 #include <cutils/native_handle.h> 23 24 #include <cstddef> 25 #include <mutex> 26 #include <utility> 27 #include <vector> 28 29 namespace aidl::android::hardware::automotive::evs::implementation { 30 31 class EvsCamera : public EvsCameraBase { 32 private: 33 using Base = EvsCameraBase; 34 using Self = EvsCamera; 35 36 public: 37 using Base::Base; 38 39 ~EvsCamera() override; 40 41 // Methods from ::android::hardware::automotive::evs::IEvsCamera follow. 42 ndk::ScopedAStatus doneWithFrame(const std::vector<evs::BufferDesc>& buffers) override; 43 44 ndk::ScopedAStatus importExternalBuffers(const std::vector<evs::BufferDesc>& buffers, 45 int32_t* _aidl_return) override; 46 47 ndk::ScopedAStatus setMaxFramesInFlight(int32_t bufferCount) override; 48 49 ndk::ScopedAStatus startVideoStream( 50 const std::shared_ptr<evs::IEvsCameraStream>& receiver) override; 51 52 ndk::ScopedAStatus stopVideoStream() override; 53 54 ndk::ScopedAStatus pauseVideoStream() override; 55 56 ndk::ScopedAStatus resumeVideoStream() override; 57 58 protected: 59 virtual ::android::status_t allocateOneFrame(buffer_handle_t* handle) = 0; 60 61 virtual void freeOneFrame(const buffer_handle_t handle); 62 63 virtual bool preVideoStreamStart_locked(const std::shared_ptr<evs::IEvsCameraStream>& receiver, 64 ndk::ScopedAStatus& status, 65 std::unique_lock<std::mutex>& lck); 66 67 virtual bool startVideoStreamImpl_locked(const std::shared_ptr<evs::IEvsCameraStream>& receiver, 68 ndk::ScopedAStatus& status, 69 std::unique_lock<std::mutex>& lck) = 0; 70 71 virtual bool postVideoStreamStart_locked(const std::shared_ptr<evs::IEvsCameraStream>& receiver, 72 ndk::ScopedAStatus& status, 73 std::unique_lock<std::mutex>& lck); 74 75 virtual bool preVideoStreamStop_locked(ndk::ScopedAStatus& status, 76 std::unique_lock<std::mutex>& lck); 77 78 virtual bool stopVideoStreamImpl_locked(ndk::ScopedAStatus& status, 79 std::unique_lock<std::mutex>& lck) = 0; 80 81 virtual bool postVideoStreamStop_locked(ndk::ScopedAStatus& status, 82 std::unique_lock<std::mutex>& lck); 83 84 void shutdown() override; 85 86 void closeAllBuffers_unsafe(); 87 88 // Returns (ID, handle) if succeeds. (kInvalidBufferID, nullptr) otherwise. 89 [[nodiscard]] std::pair<std::size_t, buffer_handle_t> useBuffer_unsafe(); 90 91 void returnBuffer_unsafe(const std::size_t id); 92 93 bool increaseAvailableFrames_unsafe(const buffer_handle_t handle); 94 95 bool decreaseAvailableFrames_unsafe(); 96 97 bool setAvailableFrames_unsafe(const std::size_t bufferCount); 98 99 void swapBufferFrames_unsafe(const std::size_t pos1, const std::size_t pos2); 100 101 struct BufferRecord { 102 BufferRecord() = default; 103 BufferRecord(const BufferRecord&) = default; 104 BufferRecord(BufferRecord&&) = default; 105 BufferRecord& operator=(const BufferRecord&) = default; 106 BufferRecord& operator=(BufferRecord&&) = default; 107 ~BufferRecord() = default; 108 BufferRecordBufferRecord109 explicit BufferRecord(buffer_handle_t h) : handle(h) {} 110 111 buffer_handle_t handle{nullptr}; 112 bool inUse{false}; 113 }; 114 115 enum class StreamState { 116 STOPPED = 0, 117 RUNNING = 1, 118 STOPPING = 2, 119 DEAD = 3, 120 }; 121 122 StreamState mStreamState{StreamState::STOPPED}; 123 124 std::mutex mMutex; 125 126 // Graphics buffers to transfer images, always in the order of: 127 // In use buffers ... available buffers ... unavailable (unallocated) buffers. 128 std::vector<BufferRecord> mBuffers; 129 130 // Double-mapping between buffer position and ID. 131 std::vector<std::size_t> mBufferPosToId; 132 std::vector<std::size_t> mBufferIdToPos; 133 134 std::size_t mAvailableFrames{0}; 135 std::size_t mFramesInUse{0}; 136 137 // We use all 1's as a reserved invalid buffer ID. 138 static constexpr std::size_t kInvalidBufferID = ~static_cast<std::size_t>(0); 139 140 public: IsBufferIDValid(const std::size_t bufferId)141 static bool IsBufferIDValid(const std::size_t bufferId) { return ~bufferId; } 142 }; 143 144 } // namespace aidl::android::hardware::automotive::evs::implementation 145