Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2017 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 | #ifndef EVS_VTS_STREAMHANDLER_H |
| 18 | #define EVS_VTS_STREAMHANDLER_H |
| 19 | |
Changyeon Jo | 5162a6c | 2020-03-02 14:25:36 -0800 | [diff] [blame] | 20 | #include <condition_variable> |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 21 | #include <queue> |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 22 | #include <thread> |
Changyeon Jo | d4e2476 | 2020-02-28 11:15:29 -0800 | [diff] [blame] | 23 | #include <shared_mutex> |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 24 | #include <ui/GraphicBuffer.h> |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 25 | #include <android/hardware/automotive/evs/1.0/IEvsCameraStream.h> |
| 26 | #include <android/hardware/automotive/evs/1.0/IEvsCamera.h> |
| 27 | #include <android/hardware/automotive/evs/1.0/IEvsDisplay.h> |
| 28 | |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 29 | #include "BaseRenderCallback.h" |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 30 | #include "BaseAnalyzeCallback.h" |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 31 | |
Haoxiang Li | d2454a5 | 2019-06-18 13:23:12 -0700 | [diff] [blame] | 32 | namespace android { |
| 33 | namespace automotive { |
| 34 | namespace evs { |
| 35 | namespace support { |
| 36 | |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 37 | using namespace ::android::hardware::automotive::evs::V1_0; |
| 38 | using ::android::hardware::Return; |
| 39 | using ::android::hardware::Void; |
| 40 | using ::android::hardware::hidl_vec; |
| 41 | using ::android::hardware::hidl_handle; |
| 42 | using ::android::sp; |
| 43 | |
| 44 | |
| 45 | /* |
| 46 | * StreamHandler: |
| 47 | * This class can be used to receive camera imagery from an IEvsCamera implementation. It will |
| 48 | * hold onto the most recent image buffer, returning older ones. |
| 49 | * Note that the video frames are delivered on a background thread, while the control interface |
| 50 | * is actuated from the applications foreground thread. |
| 51 | */ |
| 52 | class StreamHandler : public IEvsCameraStream { |
| 53 | public: |
Haoxiang Li | c888859 | 2019-09-19 16:39:53 -0700 | [diff] [blame] | 54 | virtual ~StreamHandler() { |
| 55 | // The shutdown logic is supposed to be handled by ResourceManager |
| 56 | // class. But if something goes wrong, we want to make sure that the |
| 57 | // related resources are still released properly. |
| 58 | if (mCamera != nullptr) { |
| 59 | shutdown(); |
| 60 | } |
| 61 | }; |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 62 | |
| 63 | StreamHandler(android::sp <IEvsCamera> pCamera); |
| 64 | void shutdown(); |
| 65 | |
| 66 | bool startStream(); |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 67 | |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 68 | bool newDisplayFrameAvailable(); |
| 69 | const BufferDesc& getNewDisplayFrame(); |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 70 | void doneWithFrame(const BufferDesc& buffer); |
| 71 | |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 72 | /* |
| 73 | * Attaches a render callback to the StreamHandler. |
| 74 | * |
| 75 | * Every frame will be processed by the attached render callback before it |
| 76 | * is delivered to the client by method getNewDisplayFrame(). |
| 77 | * |
| 78 | * Since there is only one DisplayUseCase allowed at the same time, at most |
| 79 | * only one render callback can be attached. The current render callback |
| 80 | * needs to be detached first (by method detachRenderCallback()), before a |
| 81 | * new callback can be attached. In other words, the call will be ignored |
| 82 | * if the current render callback is not null. |
| 83 | * |
| 84 | * @see detachRenderCallback() |
| 85 | * @see getNewDisplayFrame() |
| 86 | */ |
| 87 | void attachRenderCallback(BaseRenderCallback*); |
| 88 | |
| 89 | /* |
| 90 | * Detaches the current render callback. |
| 91 | * |
| 92 | * If no render callback is attached, this call will be ignored. |
| 93 | * |
| 94 | * @see attachRenderCallback(BaseRenderCallback*) |
| 95 | */ |
| 96 | void detachRenderCallback(); |
| 97 | |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 98 | /* |
| 99 | * Attaches an analyze callback to the StreamHandler. |
| 100 | * |
| 101 | * When there is a valid analyze callback attached, a thread dedicated for |
| 102 | * the analyze callback will be allocated. When the thread is not busy, the |
| 103 | * next available evs frame will be copied (now happens in binder thread). |
| 104 | * And the copy will be passed into the analyze thread, and be processed by |
| 105 | * the analyze callback. |
| 106 | * |
| 107 | * Since there is only one AnalyzeUseCase allowed at the same time, at most |
| 108 | * only one analyze callback can be attached. The current analyze callback |
| 109 | * needs to be detached first (by method detachAnalyzeCallback()), before a |
| 110 | * new callback can be attached. In other words, the call will be ignored |
| 111 | * if the current analyze callback is not null. |
| 112 | * |
| 113 | * @see detachAnalyzeCallback() |
| 114 | */ |
| 115 | // TODO(b/130246434): now only one analyze use case is supported, so one |
| 116 | // analyze thread id good enough. But we should be able to support several |
| 117 | // analyze use cases running at the same time, so we should probably use a |
| 118 | // thread pool to handle the cases. |
| 119 | void attachAnalyzeCallback(BaseAnalyzeCallback*); |
| 120 | |
| 121 | /* |
| 122 | * Detaches the current analyze callback. |
| 123 | * |
| 124 | * If no analyze callback is attached, this call will be ignored. |
| 125 | * |
| 126 | * @see attachAnalyzeCallback(BaseAnalyzeCallback*) |
| 127 | */ |
| 128 | void detachAnalyzeCallback(); |
| 129 | |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 130 | private: |
| 131 | // Implementation for ::android::hardware::automotive::evs::V1_0::ICarCameraStream |
| 132 | Return<void> deliverFrame(const BufferDesc& buffer) override; |
| 133 | |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 134 | bool processFrame(const BufferDesc&, BufferDesc&); |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 135 | bool copyAndAnalyzeFrame(const BufferDesc&); |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 136 | |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 137 | // Values initialized as startup |
| 138 | android::sp <IEvsCamera> mCamera; |
| 139 | |
| 140 | // Since we get frames delivered to us asnchronously via the ICarCameraStream interface, |
| 141 | // we need to protect all member variables that may be modified while we're streaming |
| 142 | // (ie: those below) |
| 143 | std::mutex mLock; |
| 144 | std::condition_variable mSignal; |
| 145 | |
| 146 | bool mRunning = false; |
| 147 | |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 148 | BufferDesc mOriginalBuffers[2]; |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 149 | int mHeldBuffer = -1; // Index of the one currently held by the client |
| 150 | int mReadyBuffer = -1; // Index of the newest available buffer |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 151 | |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 152 | BufferDesc mProcessedBuffers[2]; |
Changyeon Jo | d4e2476 | 2020-02-28 11:15:29 -0800 | [diff] [blame] | 153 | BufferDesc mAnalyzeBuffer GUARDED_BY(mAnalyzerLock); |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 154 | |
Haoxiang Li | 5cb6905 | 2019-08-30 16:24:25 -0700 | [diff] [blame] | 155 | BaseRenderCallback* mRenderCallback = nullptr; |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 156 | |
Changyeon Jo | d4e2476 | 2020-02-28 11:15:29 -0800 | [diff] [blame] | 157 | BaseAnalyzeCallback* mAnalyzeCallback GUARDED_BY(mAnalyzerLock); |
Changyeon Jo | 5162a6c | 2020-03-02 14:25:36 -0800 | [diff] [blame] | 158 | std::atomic<bool> mAnalyzerRunning; |
Changyeon Jo | d4e2476 | 2020-02-28 11:15:29 -0800 | [diff] [blame] | 159 | std::shared_mutex mAnalyzerLock; |
Changyeon Jo | 5162a6c | 2020-03-02 14:25:36 -0800 | [diff] [blame] | 160 | std::condition_variable_any mAnalyzerSignal; |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 161 | }; |
| 162 | |
Haoxiang Li | d2454a5 | 2019-06-18 13:23:12 -0700 | [diff] [blame] | 163 | } // namespace support |
| 164 | } // namespace evs |
| 165 | } // namespace automotive |
| 166 | } // namespace android |
Haoxiang Li | b21a13e | 2019-06-18 13:16:28 -0700 | [diff] [blame] | 167 | |
| 168 | #endif //EVS_VTS_STREAMHANDLER_H |
Haoxiang Li | 3993d00 | 2019-09-17 14:42:02 -0700 | [diff] [blame] | 169 | |