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