blob: f0e9fed9a11ae8761cae4172036c4b0f17f9e618 [file] [log] [blame]
Haoxiang Lib21a13e2019-06-18 13:16:28 -07001/*
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 Jo5162a6c2020-03-02 14:25:36 -080020#include <condition_variable>
Haoxiang Lib21a13e2019-06-18 13:16:28 -070021#include <queue>
Haoxiang Li3993d002019-09-17 14:42:02 -070022#include <thread>
Changyeon Jod4e24762020-02-28 11:15:29 -080023#include <shared_mutex>
Haoxiang Li3993d002019-09-17 14:42:02 -070024#include <ui/GraphicBuffer.h>
Haoxiang Lib21a13e2019-06-18 13:16:28 -070025#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 Li5cb69052019-08-30 16:24:25 -070029#include "BaseRenderCallback.h"
Haoxiang Li3993d002019-09-17 14:42:02 -070030#include "BaseAnalyzeCallback.h"
Haoxiang Li5cb69052019-08-30 16:24:25 -070031
Haoxiang Lid2454a52019-06-18 13:23:12 -070032namespace android {
33namespace automotive {
34namespace evs {
35namespace support {
36
Haoxiang Lib21a13e2019-06-18 13:16:28 -070037using namespace ::android::hardware::automotive::evs::V1_0;
38using ::android::hardware::Return;
39using ::android::hardware::Void;
40using ::android::hardware::hidl_vec;
41using ::android::hardware::hidl_handle;
42using ::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 */
52class StreamHandler : public IEvsCameraStream {
53public:
Haoxiang Lic8888592019-09-19 16:39:53 -070054 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 Lib21a13e2019-06-18 13:16:28 -070062
63 StreamHandler(android::sp <IEvsCamera> pCamera);
64 void shutdown();
65
66 bool startStream();
Haoxiang Lib21a13e2019-06-18 13:16:28 -070067
Haoxiang Li5cb69052019-08-30 16:24:25 -070068 bool newDisplayFrameAvailable();
69 const BufferDesc& getNewDisplayFrame();
Haoxiang Lib21a13e2019-06-18 13:16:28 -070070 void doneWithFrame(const BufferDesc& buffer);
71
Haoxiang Li5cb69052019-08-30 16:24:25 -070072 /*
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 Li3993d002019-09-17 14:42:02 -070098 /*
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 Lib21a13e2019-06-18 13:16:28 -0700130private:
131 // Implementation for ::android::hardware::automotive::evs::V1_0::ICarCameraStream
132 Return<void> deliverFrame(const BufferDesc& buffer) override;
133
Haoxiang Li5cb69052019-08-30 16:24:25 -0700134 bool processFrame(const BufferDesc&, BufferDesc&);
Haoxiang Li3993d002019-09-17 14:42:02 -0700135 bool copyAndAnalyzeFrame(const BufferDesc&);
Haoxiang Li5cb69052019-08-30 16:24:25 -0700136
Haoxiang Lib21a13e2019-06-18 13:16:28 -0700137 // 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 Li5cb69052019-08-30 16:24:25 -0700148 BufferDesc mOriginalBuffers[2];
Haoxiang Lib21a13e2019-06-18 13:16:28 -0700149 int mHeldBuffer = -1; // Index of the one currently held by the client
150 int mReadyBuffer = -1; // Index of the newest available buffer
Haoxiang Li5cb69052019-08-30 16:24:25 -0700151
Haoxiang Li3993d002019-09-17 14:42:02 -0700152 BufferDesc mProcessedBuffers[2];
Changyeon Jod4e24762020-02-28 11:15:29 -0800153 BufferDesc mAnalyzeBuffer GUARDED_BY(mAnalyzerLock);
Haoxiang Li3993d002019-09-17 14:42:02 -0700154
Haoxiang Li5cb69052019-08-30 16:24:25 -0700155 BaseRenderCallback* mRenderCallback = nullptr;
Haoxiang Li3993d002019-09-17 14:42:02 -0700156
Changyeon Jod4e24762020-02-28 11:15:29 -0800157 BaseAnalyzeCallback* mAnalyzeCallback GUARDED_BY(mAnalyzerLock);
Changyeon Jo5162a6c2020-03-02 14:25:36 -0800158 std::atomic<bool> mAnalyzerRunning;
Changyeon Jod4e24762020-02-28 11:15:29 -0800159 std::shared_mutex mAnalyzerLock;
Changyeon Jo5162a6c2020-03-02 14:25:36 -0800160 std::condition_variable_any mAnalyzerSignal;
Haoxiang Lib21a13e2019-06-18 13:16:28 -0700161};
162
Haoxiang Lid2454a52019-06-18 13:23:12 -0700163} // namespace support
164} // namespace evs
165} // namespace automotive
166} // namespace android
Haoxiang Lib21a13e2019-06-18 13:16:28 -0700167
168#endif //EVS_VTS_STREAMHANDLER_H
Haoxiang Li3993d002019-09-17 14:42:02 -0700169