blob: dcd74059124686cca98ee947e4c9a338815c10a6 [file] [log] [blame]
Haoxiang Li0601e852020-06-19 16:41:33 -07001/*
2 * Copyright 2020 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#include "MockEvsCamera.h"
18
Haoxiang Lib53ae8d2020-06-28 23:04:10 -070019#include <stdlib.h>
20
Haoxiang Li0601e852020-06-19 16:41:33 -070021namespace android {
22namespace hardware {
23namespace automotive {
24namespace sv {
25namespace V1_0 {
26namespace implementation {
27
Haoxiang Lib53ae8d2020-06-28 23:04:10 -070028// TODO(b/159733690): the number should come from xml
29const int kFramesCount = 4;
30const int kFrameGenerationDelayMillis = 30;
31const char kConfigFilePath[] =
32 "/vendor/etc/automotive/evs/evs_sample_configuration.xml";
33
34MockEvsCamera::MockEvsCamera(const string& cameraId, const Stream& streamCfg) {
35 mConfigManager = ConfigManager::Create(kConfigFilePath);
36
37 mStreamCfg.height = streamCfg.height;
38 mStreamCfg.width = streamCfg.width;
39
40 mCameraDesc.v1.cameraId = cameraId;
41 unique_ptr<ConfigManager::CameraGroupInfo>& cameraGroupInfo =
42 mConfigManager->getCameraGroupInfo(mCameraDesc.v1.cameraId);
43 if (cameraGroupInfo != nullptr) {
44 mCameraDesc.metadata.setToExternal(
45 (uint8_t*)cameraGroupInfo->characteristics,
46 get_camera_metadata_size(cameraGroupInfo->characteristics));
47 }
Haoxiang Li0601e852020-06-19 16:41:33 -070048}
49
50Return<void> MockEvsCamera::getCameraInfo(getCameraInfo_cb _hidl_cb) {
51 // Not implemented.
52
53 (void)_hidl_cb;
54 return {};
55}
56
57Return<EvsResult> MockEvsCamera::setMaxFramesInFlight(uint32_t bufferCount) {
58 // Not implemented.
59
60 (void)bufferCount;
61 return EvsResult::OK;
62}
63
64Return<EvsResult> MockEvsCamera::startVideoStream(
65 const ::android::sp<IEvsCameraStream_1_0>& stream) {
66 LOG(INFO) << __FUNCTION__;
Haoxiang Lib53ae8d2020-06-28 23:04:10 -070067 scoped_lock<mutex> lock(mAccessLock);
Haoxiang Li0601e852020-06-19 16:41:33 -070068
Haoxiang Lib53ae8d2020-06-28 23:04:10 -070069 mStream = IEvsCameraStream_1_1::castFrom(stream).withDefault(nullptr);
70
71 if (mStreamState != STOPPED) {
72 LOG(ERROR) << "Ignoring startVideoStream call when a stream is "
73 << "already running.";
74 return EvsResult::STREAM_ALREADY_RUNNING;
75 }
76
77 // Start the frame generation thread
78 mStreamState = RUNNING;
79 mCaptureThread = thread([this]() { generateFrames(); });
80
Haoxiang Li0601e852020-06-19 16:41:33 -070081 return EvsResult::OK;
82}
83
84Return<void> MockEvsCamera::doneWithFrame(const BufferDesc_1_0& buffer) {
85 // Not implemented.
86
87 (void)buffer;
88 return {};
89}
90
91Return<void> MockEvsCamera::stopVideoStream() {
92 LOG(INFO) << __FUNCTION__;
Haoxiang Lib53ae8d2020-06-28 23:04:10 -070093
94 unique_lock<mutex> lock(mAccessLock);
95 if (mStreamState == RUNNING) {
96 // Tell the GenerateFrames loop we want it to stop
97 mStreamState = STOPPING;
98 // Block outside the mutex until the "stop" flag has been acknowledged
99 // We won't send any more frames, but the client might still get some
100 // already in flight
101 LOG(DEBUG) << __FUNCTION__ << ": Waiting for stream thread to end...";
102 lock.unlock();
103 mCaptureThread.join();
104 lock.lock();
105 mStreamState = STOPPED;
106 mStream = nullptr;
107 LOG(DEBUG) << "Stream marked STOPPED.";
108 }
Haoxiang Li0601e852020-06-19 16:41:33 -0700109 return {};
110}
111
112Return<int32_t> MockEvsCamera::getExtendedInfo(uint32_t opaqueIdentifier) {
113 // Not implemented.
114
115 (void)opaqueIdentifier;
116 return 0;
117}
118
119Return<EvsResult> MockEvsCamera::setExtendedInfo(uint32_t opaqueIdentifier,
120 int32_t opaqueValue) {
121 // Not implemented.
122
123 (void)opaqueIdentifier;
124 (void)opaqueValue;
125 return EvsResult::OK;
126}
127
128Return<void> MockEvsCamera::getCameraInfo_1_1(getCameraInfo_1_1_cb _hidl_cb) {
Haoxiang Lib53ae8d2020-06-28 23:04:10 -0700129 _hidl_cb(mCameraDesc);
Haoxiang Li0601e852020-06-19 16:41:33 -0700130 return {};
131}
132
133Return<void> MockEvsCamera::getPhysicalCameraInfo(
134 const hidl_string& deviceId, getPhysicalCameraInfo_cb _hidl_cb) {
135 CameraDesc_1_1 desc = {};
136 desc.v1.cameraId = deviceId;
137
138 unique_ptr<ConfigManager::CameraInfo>& cameraInfo =
139 mConfigManager->getCameraInfo(deviceId);
140 if (cameraInfo != nullptr) {
141 desc.metadata.setToExternal(
142 (uint8_t*)cameraInfo->characteristics,
143 get_camera_metadata_size(cameraInfo->characteristics));
144 }
145
146 _hidl_cb(desc);
147
148 return {};
149}
150
151Return<EvsResult> MockEvsCamera::doneWithFrame_1_1(
152 const hardware::hidl_vec<BufferDesc_1_1>& buffer) {
153 // Not implemented.
154
155 (void)buffer;
156 return EvsResult::OK;
157}
158
159Return<EvsResult> MockEvsCamera::setMaster() {
160 // Not implemented.
161
162 return EvsResult::OK;
163}
164
165Return<EvsResult> MockEvsCamera::forceMaster(
166 const sp<IEvsDisplay_1_0>& display) {
167 // Not implemented.
168
169 (void)display;
170 return EvsResult::OK;
171}
172
173Return<EvsResult> MockEvsCamera::unsetMaster() {
174 // Not implemented.
175
176 return EvsResult::OK;
177}
178
179Return<void> MockEvsCamera::getParameterList(getParameterList_cb _hidl_cb) {
180 // Not implemented.
181
182 (void)_hidl_cb;
183 return {};
184}
185
186Return<void> MockEvsCamera::getIntParameterRange(
187 CameraParam id, getIntParameterRange_cb _hidl_cb) {
188 // Not implemented.
189
190 (void)id;
191 (void)_hidl_cb;
192 return {};
193}
194
195Return<void> MockEvsCamera::setIntParameter(CameraParam id, int32_t value,
196 setIntParameter_cb _hidl_cb) {
197 // Not implemented.
198
199 (void)id;
200 (void)value;
201 (void)_hidl_cb;
202 return {};
203}
204
205Return<void> MockEvsCamera::getIntParameter(
206 CameraParam id, getIntParameter_cb _hidl_cb) {
207 // Not implemented.
208
209 (void)id;
210 (void)_hidl_cb;
211 return {};
212}
213
214Return<EvsResult> MockEvsCamera::setExtendedInfo_1_1(
215 uint32_t opaqueIdentifier, const hidl_vec<uint8_t>& opaqueValue) {
216 // Not implemented.
217
218 (void)opaqueIdentifier;
219 (void)opaqueValue;
220 return EvsResult::OK;
221}
222
223Return<void> MockEvsCamera::getExtendedInfo_1_1(
224 uint32_t opaqueIdentifier, getExtendedInfo_1_1_cb _hidl_cb) {
225 // Not implemented.
226
227 (void)opaqueIdentifier;
228 (void)_hidl_cb;
229 return {};
230}
231
232Return<void> MockEvsCamera::importExternalBuffers(
233 const hidl_vec<BufferDesc_1_1>& buffers,
234 importExternalBuffers_cb _hidl_cb) {
235 // Not implemented.
236
237 (void)buffers;
238 (void)_hidl_cb;
239 return {};
240}
241
Haoxiang Lib53ae8d2020-06-28 23:04:10 -0700242void MockEvsCamera::initializeFrames(int framesCount) {
243 LOG(INFO) << "StreamCfg width: " << mStreamCfg.width
244 << " height: " << mStreamCfg.height;
245
246 string label = "EmptyBuffer_";
247 mGraphicBuffers.resize(framesCount);
248 mBufferDescs.resize(framesCount);
249 for (int i = 0; i < framesCount; i++) {
250 mGraphicBuffers[i] = new GraphicBuffer(mStreamCfg.width,
251 mStreamCfg.height,
252 HAL_PIXEL_FORMAT_RGBA_8888,
253 1,
254 GRALLOC_USAGE_HW_TEXTURE,
255 label + (char)(i + 48));
256 mBufferDescs[i].buffer.nativeHandle =
257 mGraphicBuffers[i]->getNativeBuffer()->handle;
258 AHardwareBuffer_Desc* pDesc =
259 reinterpret_cast<AHardwareBuffer_Desc*>(
260 &mBufferDescs[i].buffer.description);
261 pDesc->width = mStreamCfg.width;
262 pDesc->height = mStreamCfg.height;
263 pDesc->layers = 1;
264 pDesc->usage = GRALLOC_USAGE_HW_TEXTURE;
265 pDesc->stride = mGraphicBuffers[i]->getStride();
266 pDesc->format = HAL_PIXEL_FORMAT_RGBA_8888;
267 }
268}
269
270void MockEvsCamera::generateFrames() {
271 initializeFrames(kFramesCount);
272
273 while (true) {
274 {
275 scoped_lock<mutex> lock(mAccessLock);
276 if (mStreamState != RUNNING) {
277 // Break out of our main thread loop
278 LOG(INFO) << "StreamState does not equal to RUNNING. "
279 << "Exiting the loop";
280 break;
281 }
282 }
283
284 mStream->deliverFrame_1_1(mBufferDescs);
285 std::this_thread::sleep_for(
286 std::chrono::milliseconds(kFrameGenerationDelayMillis));
287 }
288
289 {
290 scoped_lock<mutex> lock(mAccessLock);
291
292 if (mStream != nullptr) {
293 LOG(DEBUG) << "Notify EvsEventType::STREAM_STOPPED";
294
295 EvsEventDesc evsEventDesc;
296 evsEventDesc.aType = EvsEventType::STREAM_STOPPED;
297 mStream->notify(evsEventDesc);
298 } else {
299 LOG(WARNING) << "EVS stream is not valid any more. "
300 << "The notify call is ignored.";
301 }
302 }
303}
304
Haoxiang Li0601e852020-06-19 16:41:33 -0700305} // namespace implementation
306} // namespace V1_0
307} // namespace sv
308} // namespace automotive
309} // namespace hardware
310} // namespace android