• Home
  • 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 #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