1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file expected in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ut_common.h"
17 #include "camera.h"
18 #include "video_key_info.h"
19
20 namespace OHOS::Camera {
21 Test::ResultCallback Test::resultCallback_ = 0;
22
GetCurrentLocalTimeStamp()23 uint64_t Test::GetCurrentLocalTimeStamp()
24 {
25 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
26 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
27 auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
28 return static_cast<uint64_t>(tmp.count());
29 }
30
DumpImageFile(int streamId,std::string suffix,const void * buffer,int32_t size)31 int32_t Test::DumpImageFile(int streamId, std::string suffix, const void* buffer, int32_t size)
32 {
33 if (imageDataSaveSwitch == SWITCH_OFF) {
34 return 0;
35 }
36 if (streamId < 0) {
37 CAMERA_LOGE("ivalid stream id: %{public}d", streamId);
38 return -1;
39 }
40 char mkdirCmd[PATH_MAX] = {0};
41 char path[PATH_MAX] = {0};
42 int ret = sprintf_s(mkdirCmd, sizeof(mkdirCmd) / sizeof(mkdirCmd[0]),
43 "mkdir -p /data/stream-%d", streamId);
44 if (ret < 0) {
45 return -1;
46 }
47 system(mkdirCmd);
48 ret = sprintf_s(path, sizeof(path) / sizeof(path[0]), "data/stream-%d/%lld.%s",
49 streamId, GetCurrentLocalTimeStamp(), suffix.c_str());
50 if (ret < 0) {
51 return -1;
52 }
53
54 int imgFd = open(path, O_RDWR | O_CREAT, 00766);
55 if (imgFd == -1) {
56 CAMERA_LOGE("open file failed, errno: %{public}s", strerror(errno));
57 return -1;
58 }
59
60 ret = write(imgFd, buffer, size);
61 if (ret == -1) {
62 CAMERA_LOGE("write file failed, error: %{public}s", strerror(errno));
63 close(imgFd);
64 return -1;
65 }
66 close(imgFd);
67 return 0;
68 }
69
Init()70 void Test::Init()
71 {
72 if (service == nullptr) {
73 service = ICameraHost::Get("camera_service", false);
74 if (service == nullptr) {
75 CAMERA_LOGI("ICameraHost get failed");
76 } else {
77 CAMERA_LOGE("ICameraHost get success");
78 }
79 ASSERT_TRUE(service != nullptr);
80 }
81 hostCallback = new TestCameraHostCallback();
82 service->SetCallback(hostCallback);
83 }
84
GetCameraMetadata()85 void Test::GetCameraMetadata()
86 {
87 rc = service->GetCameraAbility(cameraIds.front(), abilityVec);
88 if (rc != HDI::Camera::V1_0::NO_ERROR) {
89 CAMERA_LOGE("GetCameraAbility failed, rc = %{public}d", rc);
90 }
91 MetadataUtils::ConvertVecToMetadata(abilityVec, ability);
92
93 common_metadata_header_t* data = ability->get();
94 camera_metadata_item_t entry;
95 int ret = FindCameraMetadataItem(data, OHOS_CONTROL_AE_AVAILABLE_MODES, &entry);
96 if (ret == 0) {
97 CAMERA_LOGI("get OHOS_CONTROL_AE_AVAILABLE_MODES success");
98 }
99 }
100
Open()101 void Test::Open()
102 {
103 if (cameraDevice == nullptr) {
104 service->GetCameraIds(cameraIds);
105 if (cameraIds.size() == 0) {
106 CAMERA_LOGE("camera device list empty");
107 return;
108 }
109 GetCameraMetadata();
110 deviceCallback = new OHOS::Camera::Test::DemoCameraDeviceCallback();
111 rc = service->OpenCamera(cameraIds.front(), deviceCallback, cameraDevice);
112 if (rc != HDI::Camera::V1_0::NO_ERROR || cameraDevice == nullptr) {
113 CAMERA_LOGE("openCamera failed, rc = %{public}d", rc);
114 return;
115 }
116 CAMERA_LOGI("OpenCamera success");
117 }
118 }
119
Close()120 void Test::Close()
121 {
122 if (cameraDevice != nullptr) {
123 cameraDevice->Close();
124 cameraDevice = nullptr;
125 }
126 }
127
StartStream(std::vector<StreamIntent> intents)128 void Test::StartStream(std::vector<StreamIntent> intents)
129 {
130 streamOperatorCallback = new TestStreamOperatorCallback();
131 rc = cameraDevice->GetStreamOperator(streamOperatorCallback, streamOperator);
132 if (rc == HDI::Camera::V1_0::NO_ERROR) {
133 CAMERA_LOGI("GetStreamOperator success");
134 } else {
135 CAMERA_LOGE("GetStreamOperator fail, rc = %{public}d", rc);
136 }
137 streamInfoPre = std::make_shared<StreamInfo>();
138 streamInfoVideo = std::make_shared<StreamInfo>();
139 streamInfoCapture = std::make_shared<StreamInfo>();
140 streamInfoAnalyze = std::make_shared<StreamInfo>();
141 for (auto& intent : intents) {
142 if (intent == StreamIntent::PREVIEW) {
143 streamInfoPre->streamId_ = streamIdPreview;
144 streamInfoPre->width_ = previewWidth;
145 streamInfoPre->height_ = previewHeight;
146 streamInfoPre->format_ = previewFormat;
147 streamInfoPre->dataspace_ = UT_DATA_SIZE;
148 streamInfoPre->intent_ = intent;
149 streamInfoPre->tunneledMode_ = UT_TUNNEL_MODE;
150 std::shared_ptr<StreamConsumer> consumer_pre = std::make_shared<StreamConsumer>();
151 streamInfoPre->bufferQueue_ = consumer_pre->CreateProducerSeq([this](void* addr, uint32_t size) {
152 DumpImageFile(streamIdPreview, "yuv", addr, size);
153 });
154 streamInfoPre->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
155 consumerMap_[intent] = consumer_pre;
156 streamInfos.push_back(*streamInfoPre);
157 } else if (intent == StreamIntent::VIDEO) {
158 streamInfoVideo->streamId_ = streamIdVideo;
159 streamInfoVideo->width_ = videoWidth;
160 streamInfoVideo->height_ = videoHeight;
161 streamInfoVideo->format_ = videoFormat;
162 streamInfoVideo->dataspace_ = UT_DATA_SIZE;
163 streamInfoVideo->intent_ = intent;
164 streamInfoVideo->encodeType_ = ENCODE_TYPE_H265;
165 streamInfoVideo->tunneledMode_ = UT_TUNNEL_MODE;
166 std::shared_ptr<StreamConsumer> consumer_video = std::make_shared<StreamConsumer>();
167 streamInfoVideo->bufferQueue_ = consumer_video->CreateProducerSeq([this](void* addr, uint32_t size) {
168 DumpImageFile(streamIdPreview, "yuv", addr, size);
169 });
170 streamInfoVideo->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
171 consumerMap_[intent] = consumer_video;
172 streamInfos.push_back(*streamInfoVideo);
173 } else if (intent == StreamIntent::ANALYZE) {
174 streamInfoAnalyze->streamId_ = streamIdAnalyze;
175 streamInfoAnalyze->width_ = analyzeWidth;
176 streamInfoAnalyze->height_ = analyzeHeight;
177 streamInfoAnalyze->format_ = analyzeFormat;
178 streamInfoAnalyze->dataspace_ = UT_DATA_SIZE;
179 streamInfoAnalyze->intent_ = intent;
180 streamInfoAnalyze->tunneledMode_ = UT_TUNNEL_MODE;
181
182 std::shared_ptr<StreamConsumer> consumer_analyze = std::make_shared<StreamConsumer>();
183 streamInfoAnalyze->bufferQueue_ = consumer_analyze->CreateProducerSeq([this](void* addr, uint32_t size) {
184 common_metadata_header_t *data = static_cast<common_metadata_header_t *>(addr);
185 camera_metadata_item_t entry = {};
186
187 int ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_IDS, &entry);
188 if (ret == 0) {
189 for (size_t i = 0; i < entry.count; i++) {
190 int id = entry.data.i32[i];
191 CAMERA_LOGI("Face ids : %{public}d", id);
192 }
193 }
194
195 ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_RECTANGLES, &entry);
196 if (ret == 0) {
197 for (size_t i = 0; i < entry.count; i++) {
198 int id = entry.data.i32[i];
199 CAMERA_LOGI("Face rectangles : %{public}d", id);
200 }
201 }
202 });
203 streamInfoAnalyze->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
204 consumerMap_[intent] = consumer_analyze;
205 streamInfos.push_back(*streamInfoAnalyze);
206 } else {
207 streamInfoCapture->streamId_ = streamIdAnalyze;
208 streamInfoCapture->width_ = analyzeWidth;
209 streamInfoCapture->height_ = analyzeHeight;
210 streamInfoCapture->format_ = analyzeFormat;
211 streamInfoCapture->dataspace_ = UT_DATA_SIZE;
212 streamInfoCapture->intent_ = intent;
213 streamInfoCapture->tunneledMode_ = UT_TUNNEL_MODE;
214 std::shared_ptr<StreamConsumer> consumer_capture = std::make_shared<StreamConsumer>();
215 streamInfoCapture->bufferQueue_ = consumer_capture->CreateProducerSeq([this](void* addr, uint32_t size) {
216 DumpImageFile(streamIdPreview, "yuv", addr, size);
217 });
218 streamInfoCapture->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
219 consumerMap_[intent] = consumer_capture;
220 streamInfos.push_back(*streamInfoCapture);
221 }
222 }
223
224 rc = streamOperator->CreateStreams(streamInfos);
225 EXPECT_EQ(false, rc != HDI::Camera::V1_0::NO_ERROR);
226 rc = streamOperator->CommitStreams(OperationMode::NORMAL, abilityVec);
227 EXPECT_EQ(false, rc != HDI::Camera::V1_0::NO_ERROR);
228 sleep(1);
229 std::vector<StreamInfo>().swap(streamInfos);
230 }
231
StartCapture(int streamId,int captureId,bool shutterCallback,bool isStreaming)232 void Test::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)
233 {
234 captureInfo = std::make_shared<CaptureInfo>();
235 captureInfo->streamIds_ = {streamId};
236 captureInfo->captureSetting_ = abilityVec;
237 captureInfo->enableShutterCallback_ = shutterCallback;
238 rc = (CamRetCode)streamOperator->Capture(captureId, *captureInfo, isStreaming);
239 EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
240 if (rc == HDI::Camera::V1_0::NO_ERROR) {
241 CAMERA_LOGI("check Capture: Capture success, %{public}d", captureId);
242 } else {
243 std::cout << "rc = " << rc << std::endl;
244 CAMERA_LOGE("check Capture: Capture fail, rc = %{public}d", rc);
245 }
246 sleep(UT_SLEEP_TIME);
247 }
248
StopStream(std::vector<int> & captureIds,std::vector<int> & streamIds)249 void Test::StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)
250 {
251 if (sizeof(captureIds) > 0) {
252 for (auto &captureId : captureIds) {
253 rc = streamOperator->CancelCapture(captureId);
254 EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
255 if (rc == HDI::Camera::V1_0::NO_ERROR) {
256 CAMERA_LOGI("check Capture: CancelCapture success, %{public}d", captureId);
257 } else {
258 CAMERA_LOGE("check Capture: CancelCapture fail, rc = %{public}d, captureId = %{public}d",
259 rc, captureId);
260 }
261 }
262 }
263 if (sizeof(streamIds) > 0) {
264 rc = streamOperator->ReleaseStreams(streamIds);
265 EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
266 if (rc == HDI::Camera::V1_0::NO_ERROR) {
267 CAMERA_LOGI("check Capture: ReleaseStream success");
268 } else {
269 CAMERA_LOGE("check Capture: ReleaseStreams fail, rc = %{public}d", rc);
270 }
271 }
272 }
273
CalculateFps(int64_t timestamp,int32_t streamId)274 void Test::StreamConsumer::CalculateFps(int64_t timestamp, int32_t streamId)
275 {
276 if (isFirstCalculateFps_) {
277 if ((timestamp - intervalTimestamp_) >= interval_) {
278 int64_t timeInterval = timestamp - intervalTimestamp_;
279 if (timeInterval != 0) {
280 float fps = (int64_t)(100000000000 * timestampCount_ / timeInterval) / 100.0;
281 CAMERA_LOGI("Calculate FPS success, streamId: %{public}d, Fps:%{public}f", streamId, fps);
282 interval_ = ONESECOND_OF_MICROSECOND_UNIT;
283 } else {
284 CAMERA_LOGE("Calculate FPS error timeInerval is 0");
285 }
286 }
287 } else {
288 intervalTimestamp_ = timestamp;
289 isFirstCalculateFps_ = true;
290 }
291 if ((timestamp - intervalTimestamp_) >= ONESECOND_OF_MICROSECOND_UNIT * UT_SECOND_TIMES) {
292 intervalTimestamp_ = timestamp;
293 timestampCount_ = 0;
294 interval_ = ONESECOND_OF_MICROSECOND_UNIT;
295 }
296 timestampCount_++;
297 }
298
CreateProducer(std::function<void (void *,uint32_t)> callback)299 OHOS::sptr<OHOS::IBufferProducer> Test::StreamConsumer::CreateProducer(std::function<void(void*, uint32_t)> callback)
300 {
301 consumer_ = OHOS::IConsumerSurface::Create();
302 if (consumer_ == nullptr) {
303 return nullptr;
304 }
305 sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
306 consumer_->RegisterConsumerListener(listener);
307 auto producer = consumer_->GetProducer();
308 if (producer == nullptr) {
309 return nullptr;
310 }
311
312 callback_ = callback;
313 consumerThread_ = new std::thread([this, listener] {
314 int32_t flushFence = 0;
315 int64_t timestamp = 0;
316 OHOS::Rect damage;
317 TestBufferConsumerListener* checker = static_cast<TestBufferConsumerListener*>(listener.GetRefPtr());
318 while (running_ == true) {
319 OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
320 if (checker->checkBufferAvailable()) {
321 consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage);
322 if (buffer != nullptr) {
323 void* addr = buffer->GetVirAddr();
324 uint32_t size = buffer->GetSize();
325
326 int32_t gotSize = 0;
327 int32_t isKey = 0;
328 int32_t streamId = 0;
329 int32_t captureId = 0;
330 buffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, gotSize);
331 buffer->GetExtraData()->ExtraGet(OHOS::Camera::isKeyFrame, isKey);
332 buffer->GetExtraData()->ExtraGet(OHOS::Camera::timeStamp, timestamp);
333 buffer->GetExtraData()->ExtraGet(OHOS::Camera::streamId, streamId);
334 buffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
335 if (gotSize) {
336 CalculateFps(timestamp, streamId);
337 callback_(addr, gotSize);
338 } else {
339 callback_(addr, size);
340 }
341
342 consumer_->ReleaseBuffer(buffer, -1);
343 shotCount_--;
344 if (shotCount_ == 0) {
345 std::unique_lock<std::mutex> l(l_);
346 cv_.notify_one();
347 }
348 }
349 }
350 if (running_ == false) {
351 break;
352 }
353 usleep(1);
354 }
355 });
356
357 return producer;
358 }
359
CreateProducerSeq(std::function<void (void *,uint32_t)> callback)360 OHOS::sptr<BufferProducerSequenceable> Test::StreamConsumer::CreateProducerSeq(
361 std::function<void(void*, uint32_t)> callback)
362 {
363 OHOS::sptr<OHOS::IBufferProducer> producer = CreateProducer(callback);
364 if (producer == nullptr) {
365 return nullptr;
366 }
367
368 return new BufferProducerSequenceable(producer);
369 }
370
OnCaptureStarted(int32_t captureId,const std::vector<int32_t> & streamId)371 int32_t Test::TestStreamOperatorCallback::OnCaptureStarted(int32_t captureId, const std::vector<int32_t> &streamId)
372 {
373 for (auto it : streamId) {
374 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d", captureId, it);
375 }
376 return HDI::Camera::V1_0::NO_ERROR;
377 }
378
OnCaptureEnded(int32_t captureId,const std::vector<CaptureEndedInfo> & infos)379 int32_t Test::TestStreamOperatorCallback::OnCaptureEnded(int32_t captureId, const std::vector<CaptureEndedInfo> &infos)
380 {
381 for (auto it : infos) {
382 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d, count: %{public}d", captureId, it.streamId_,
383 it.frameCount_);
384 }
385 return HDI::Camera::V1_0::NO_ERROR;
386 }
387
OnCaptureError(int32_t captureId,const std::vector<CaptureErrorInfo> & infos)388 int32_t Test::TestStreamOperatorCallback::OnCaptureError(int32_t captureId, const std::vector<CaptureErrorInfo> &infos)
389 {
390 for (auto it : infos) {
391 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d, error: %{public}d", captureId, it.streamId_,
392 it.error_);
393 }
394 return HDI::Camera::V1_0::NO_ERROR;
395 }
396
OnFrameShutter(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)397 int32_t Test::TestStreamOperatorCallback::OnFrameShutter(int32_t captureId,
398 const std::vector<int32_t> &streamIds, uint64_t timestamp)
399 {
400 (void)timestamp;
401 for (auto it : streamIds) {
402 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d", captureId, it);
403 }
404 return HDI::Camera::V1_0::NO_ERROR;
405 }
406
OnError(ErrorType type,int32_t errorMsg)407 int32_t Test::DemoCameraDeviceCallback::OnError(ErrorType type, int32_t errorMsg)
408 {
409 CAMERA_LOGE("type: %{public}d, errorMsg: %{public}d", type, errorMsg);
410 return HDI::Camera::V1_0::NO_ERROR;
411 }
412
OnResult(uint64_t timestamp,const std::vector<uint8_t> & result)413 int32_t Test::DemoCameraDeviceCallback::OnResult(uint64_t timestamp, const std::vector<uint8_t> &result)
414 {
415 if (Test::resultCallback_) {
416 std::shared_ptr<CameraMetadata> resultMeta;
417 MetadataUtils::ConvertVecToMetadata(result, resultMeta);
418 Test::resultCallback_(timestamp, resultMeta);
419 }
420 return HDI::Camera::V1_0::NO_ERROR;
421 }
422
OnCameraStatus(const std::string & cameraId,CameraStatus status)423 int32_t Test::TestCameraHostCallback::OnCameraStatus(const std::string& cameraId, CameraStatus status)
424 {
425 CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), status);
426 return HDI::Camera::V1_0::NO_ERROR;
427 }
428
OnFlashlightStatus(const std::string & cameraId,FlashlightStatus status)429 int32_t Test::TestCameraHostCallback::OnFlashlightStatus(const std::string& cameraId, FlashlightStatus status)
430 {
431 CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), status);
432 return HDI::Camera::V1_0::NO_ERROR;
433 }
434
OnCameraEvent(const std::string & cameraId,CameraEvent event)435 int32_t Test::TestCameraHostCallback::OnCameraEvent(const std::string& cameraId, CameraEvent event)
436 {
437 CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), event);
438 return HDI::Camera::V1_0::NO_ERROR;
439 }
440
441 }