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 camera_metadata_item_t connectEntry;
100 ret = FindCameraMetadataItem(data, OHOS_ABILITY_CAMERA_CONNECTION_TYPE, &connectEntry);
101 if (ret == HDI::Camera::V1_0::NO_ERROR && connectEntry.data.u8 != nullptr && connectEntry.count > 0) {
102 uint8_t cameraConnectionType = *(connectEntry.data.u8);
103 if (static_cast<int>(cameraConnectionType) == OHOS_CAMERA_CONNECTION_TYPE_USB_PLUGIN) {
104 CAMERA_LOGI("get OHOS_ABILITY_CAMERA_CONNECTION_TYPE success, this camera is usb camera.");
105 previewWidth = usbCamera_previewWidth;
106 previewHeight = usbCamera_previewHeight;
107 videoWidth = usbCamera_videoWidth;
108 videoHeight = usbCamera_videoHeight;
109 captureWidth = usbCamera_captureWidth;
110 captureHeight = usbCamera_captureHeight;
111 analyzeWidth = usbCamera_analyzeWidth;
112 analyzeHeight = usbCamera_analyzeHeight;
113 previewFormat = usbCamera_previewFormat;
114 videoFormat = usbCamera_videoFormat;
115 snapshotFormat = usbCamera_snapshotFormat;
116 analyzeFormat = usbCamera_analyzeFormat;
117 videoEncodeType = usbCamera_videoEncodeType;
118 }
119 }
120 }
121
Open()122 void Test::Open()
123 {
124 if (cameraDevice == nullptr) {
125 service->GetCameraIds(cameraIds);
126 if (cameraIds.size() == 0) {
127 CAMERA_LOGE("camera device list empty");
128 return;
129 }
130 GetCameraMetadata();
131 deviceCallback = new OHOS::Camera::Test::DemoCameraDeviceCallback();
132 rc = service->OpenCamera(cameraIds.front(), deviceCallback, cameraDevice);
133 if (rc != HDI::Camera::V1_0::NO_ERROR || cameraDevice == nullptr) {
134 CAMERA_LOGE("openCamera failed, rc = %{public}d", rc);
135 return;
136 }
137 CAMERA_LOGI("OpenCamera success");
138 }
139 }
140
Close()141 void Test::Close()
142 {
143 if (cameraDevice != nullptr) {
144 cameraDevice->Close();
145 cameraDevice = nullptr;
146 }
147 }
148
DefaultPreview(std::shared_ptr<StreamInfo> & infos)149 void Test::DefaultPreview(std::shared_ptr<StreamInfo> &infos)
150 {
151 infos->streamId_ = streamIdPreview;
152 infos->width_ = previewWidth;
153 infos->height_ = previewHeight;
154 infos->format_ = previewFormat;
155 infos->dataspace_ = UT_DATA_SIZE;
156 infos->intent_ = StreamIntent::PREVIEW;
157 infos->tunneledMode_ = UT_TUNNEL_MODE;
158 }
159
DefaultCapture(std::shared_ptr<StreamInfo> & infos)160 void Test::DefaultCapture(std::shared_ptr<StreamInfo> &infos)
161 {
162 infos->streamId_ = streamIdCapture;
163 infos->width_ = captureWidth;
164 infos->height_ = captureHeight;
165 infos->format_ = snapshotFormat;
166 infos->dataspace_ = UT_DATA_SIZE;
167 infos->intent_ = StreamIntent::STILL_CAPTURE;
168 infos->tunneledMode_ = UT_TUNNEL_MODE;
169 }
170
DefaultInfosPreview(std::shared_ptr<StreamInfo> & infos)171 void Test::DefaultInfosPreview(std::shared_ptr<StreamInfo> &infos)
172 {
173 DefaultPreview(infos);
174 std::shared_ptr<OHOS::Camera::Test::StreamConsumer> consumer_pre =
175 std::make_shared<OHOS::Camera::Test::StreamConsumer>();
176 infos->bufferQueue_ = consumer_pre->CreateProducerSeq([this](void* addr, uint32_t size) {
177 DumpImageFile(streamIdPreview, "yuv", addr, size);
178 });
179 infos->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
180 consumerMap_[StreamIntent::PREVIEW] = consumer_pre;
181 }
182
DefaultInfosCapture(std::shared_ptr<StreamInfo> & infos)183 void Test::DefaultInfosCapture(std::shared_ptr<StreamInfo> &infos)
184 {
185 DefaultCapture(infos);
186 std::shared_ptr<OHOS::Camera::Test::StreamConsumer> consumer_capture =
187 std::make_shared<OHOS::Camera::Test::StreamConsumer>();
188 infos->bufferQueue_ = consumer_capture->CreateProducerSeq([this](void* addr, uint32_t size) {
189 DumpImageFile(streamIdPreview, "yuv", addr, size);
190 });
191 infos->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
192 consumerMap_[StreamIntent::PREVIEW] = consumer_capture;
193 }
194
DefaultInfosVideo(std::shared_ptr<StreamInfo> & infos)195 void Test::DefaultInfosVideo(std::shared_ptr<StreamInfo> &infos)
196 {
197 infos->streamId_ = streamIdVideo;
198 infos->width_ = videoWidth;
199 infos->height_ = videoHeight;
200 infos->format_ = videoFormat;
201 infos->dataspace_ = UT_DATA_SIZE;
202 infos->intent_ = StreamIntent::VIDEO;
203 infos->encodeType_ = static_cast<OHOS::HDI::Camera::V1_0::EncodeType>(videoEncodeType);
204 infos->tunneledMode_ = UT_TUNNEL_MODE;
205 std::shared_ptr<OHOS::Camera::Test::StreamConsumer> consumer_video =
206 std::make_shared<OHOS::Camera::Test::StreamConsumer>();
207 infos->bufferQueue_ = consumer_video->CreateProducerSeq([this](void* addr, uint32_t size) {
208 DumpImageFile(streamIdVideo, "yuv", addr, size);
209 });
210 infos->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
211 consumerMap_[StreamIntent::VIDEO] = consumer_video;
212 }
213
DefaultInfosAnalyze(std::shared_ptr<StreamInfo> & infos)214 void Test::DefaultInfosAnalyze(std::shared_ptr<StreamInfo> &infos)
215 {
216 infos->streamId_ = streamIdAnalyze;
217 infos->width_ = analyzeWidth;
218 infos->height_ = analyzeHeight;
219 infos->format_ = analyzeFormat;
220 infos->dataspace_ = UT_DATA_SIZE;
221 infos->intent_ = StreamIntent::ANALYZE;
222 infos->tunneledMode_ = UT_TUNNEL_MODE;
223
224 std::shared_ptr<OHOS::Camera::Test::StreamConsumer> consumer_analyze =
225 std::make_shared<OHOS::Camera::Test::StreamConsumer>();
226 infos->bufferQueue_ = consumer_analyze->CreateProducerSeq([this](void* addr, uint32_t size) {
227 common_metadata_header_t *data = static_cast<common_metadata_header_t *>(addr);
228 camera_metadata_item_t entry = {};
229
230 int ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_IDS, &entry);
231 if (ret == 0) {
232 for (size_t i = 0; i < entry.count; i++) {
233 int id = entry.data.i32[i];
234 CAMERA_LOGI("Face ids : %{public}d", id);
235 }
236 }
237
238 ret = FindCameraMetadataItem(data, OHOS_STATISTICS_FACE_RECTANGLES, &entry);
239 if (ret == 0) {
240 for (size_t i = 0; i < entry.count; i++) {
241 int id = entry.data.i32[i];
242 CAMERA_LOGI("Face rectangles : %{public}d", id);
243 }
244 }
245 });
246 infos->bufferQueue_->producer_->SetQueueSize(UT_DATA_SIZE);
247 consumerMap_[StreamIntent::ANALYZE] = consumer_analyze;
248 }
249
StartStream(std::vector<StreamIntent> intents)250 void Test::StartStream(std::vector<StreamIntent> intents)
251 {
252 streamOperatorCallback = new TestStreamOperatorCallback();
253 rc = cameraDevice->GetStreamOperator(streamOperatorCallback, streamOperator);
254 if (rc == HDI::Camera::V1_0::NO_ERROR) {
255 CAMERA_LOGI("GetStreamOperator success");
256 } else {
257 CAMERA_LOGE("GetStreamOperator fail, rc = %{public}d", rc);
258 }
259 streamInfoPre = std::make_shared<StreamInfo>();
260 streamInfoVideo = std::make_shared<StreamInfo>();
261 streamInfoCapture = std::make_shared<StreamInfo>();
262 streamInfoAnalyze = std::make_shared<StreamInfo>();
263 for (auto& intent : intents) {
264 if (intent == StreamIntent::PREVIEW) {
265 DefaultInfosPreview(streamInfoPre);
266 streamInfos.push_back(*streamInfoPre);
267 } else if (intent == StreamIntent::VIDEO) {
268 DefaultInfosVideo(streamInfoVideo);
269 streamInfos.push_back(*streamInfoVideo);
270 } else if (intent == StreamIntent::ANALYZE) {
271 DefaultInfosAnalyze(streamInfoAnalyze);
272 streamInfos.push_back(*streamInfoAnalyze);
273 } else {
274 DefaultInfosCapture(streamInfoCapture);
275 streamInfos.push_back(*streamInfoCapture);
276 }
277 }
278
279 rc = streamOperator->CreateStreams(streamInfos);
280 EXPECT_EQ(false, rc != HDI::Camera::V1_0::NO_ERROR);
281 rc = streamOperator->CommitStreams(OperationMode::NORMAL, abilityVec);
282 EXPECT_EQ(false, rc != HDI::Camera::V1_0::NO_ERROR);
283 sleep(1);
284 std::vector<StreamInfo>().swap(streamInfos);
285 }
286
StartCapture(int streamId,int captureId,bool shutterCallback,bool isStreaming)287 void Test::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)
288 {
289 captureInfo = std::make_shared<CaptureInfo>();
290 captureInfo->streamIds_ = {streamId};
291 captureInfo->captureSetting_ = abilityVec;
292 captureInfo->enableShutterCallback_ = shutterCallback;
293 rc = (CamRetCode)streamOperator->Capture(captureId, *captureInfo, isStreaming);
294 EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
295 if (rc == HDI::Camera::V1_0::NO_ERROR) {
296 CAMERA_LOGI("check Capture: Capture success, %{public}d", captureId);
297 } else {
298 std::cout << "rc = " << rc << std::endl;
299 CAMERA_LOGE("check Capture: Capture fail, rc = %{public}d", rc);
300 }
301 sleep(UT_SLEEP_TIME);
302 }
303
StopStream(std::vector<int> & captureIds,std::vector<int> & streamIds)304 void Test::StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)
305 {
306 if (captureIds.size() > 0) {
307 for (auto &captureId : captureIds) {
308 rc = streamOperator->CancelCapture(captureId);
309 EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
310 if (rc == HDI::Camera::V1_0::NO_ERROR) {
311 CAMERA_LOGI("check Capture: CancelCapture success, %{public}d", captureId);
312 } else {
313 CAMERA_LOGE("check Capture: CancelCapture fail, rc = %{public}d, captureId = %{public}d",
314 rc, captureId);
315 }
316 }
317 }
318 if (streamIds.size() > 0) {
319 rc = streamOperator->ReleaseStreams(streamIds);
320 EXPECT_EQ(true, rc == HDI::Camera::V1_0::NO_ERROR);
321 if (rc == HDI::Camera::V1_0::NO_ERROR) {
322 CAMERA_LOGI("check Capture: ReleaseStream success");
323 } else {
324 CAMERA_LOGE("check Capture: ReleaseStreams fail, rc = %{public}d", rc);
325 }
326 }
327 }
328
CalculateFps(int64_t timestamp,int32_t streamId)329 void Test::StreamConsumer::CalculateFps(int64_t timestamp, int32_t streamId)
330 {
331 if (isFirstCalculateFps_) {
332 if ((timestamp - intervalTimestamp_) >= interval_) {
333 int64_t timeInterval = timestamp - intervalTimestamp_;
334 if (timeInterval != 0) {
335 float fps = (int64_t)(100000000000 * timestampCount_ / timeInterval) / 100.0;
336 CAMERA_LOGI("Calculate FPS success, streamId: %{public}d, Fps:%{public}f", streamId, fps);
337 interval_ = ONESECOND_OF_MICROSECOND_UNIT;
338 } else {
339 CAMERA_LOGE("Calculate FPS error timeInerval is 0");
340 }
341 }
342 } else {
343 intervalTimestamp_ = timestamp;
344 isFirstCalculateFps_ = true;
345 }
346 if ((timestamp - intervalTimestamp_) >= ONESECOND_OF_MICROSECOND_UNIT * UT_SECOND_TIMES) {
347 intervalTimestamp_ = timestamp;
348 timestampCount_ = 0;
349 interval_ = ONESECOND_OF_MICROSECOND_UNIT;
350 }
351 timestampCount_++;
352 }
353
CreateProducer(std::function<void (void *,uint32_t)> callback)354 OHOS::sptr<OHOS::IBufferProducer> Test::StreamConsumer::CreateProducer(std::function<void(void*, uint32_t)> callback)
355 {
356 consumer_ = OHOS::IConsumerSurface::Create();
357 if (consumer_ == nullptr) {
358 return nullptr;
359 }
360 sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
361 consumer_->RegisterConsumerListener(listener);
362 auto producer = consumer_->GetProducer();
363 if (producer == nullptr) {
364 return nullptr;
365 }
366
367 callback_ = callback;
368 consumerThread_ = new std::thread([this, listener] {
369 int32_t flushFence = 0;
370 int64_t timestamp = 0;
371 OHOS::Rect damage;
372 TestBufferConsumerListener* checker = static_cast<TestBufferConsumerListener*>(listener.GetRefPtr());
373 while (running_ == true) {
374 OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
375 if (checker->checkBufferAvailable()) {
376 consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage);
377 if (buffer != nullptr) {
378 void* addr = buffer->GetVirAddr();
379 uint32_t size = buffer->GetSize();
380
381 int32_t gotSize = 0;
382 int32_t isKey = 0;
383 int32_t streamId = 0;
384 int32_t captureId = 0;
385 buffer->GetExtraData()->ExtraGet(OHOS::Camera::dataSize, gotSize);
386 buffer->GetExtraData()->ExtraGet(OHOS::Camera::isKeyFrame, isKey);
387 buffer->GetExtraData()->ExtraGet(OHOS::Camera::timeStamp, timestamp);
388 buffer->GetExtraData()->ExtraGet(OHOS::Camera::streamId, streamId);
389 buffer->GetExtraData()->ExtraGet(OHOS::Camera::captureId, captureId);
390 if (gotSize) {
391 CalculateFps(timestamp, streamId);
392 callback_(addr, gotSize);
393 } else {
394 callback_(addr, size);
395 }
396
397 consumer_->ReleaseBuffer(buffer, -1);
398 shotCount_--;
399 if (shotCount_ == 0) {
400 std::unique_lock<std::mutex> l(l_);
401 cv_.notify_one();
402 }
403 }
404 }
405 if (running_ == false) {
406 break;
407 }
408 usleep(1);
409 }
410 });
411
412 return producer;
413 }
414
CreateProducerSeq(std::function<void (void *,uint32_t)> callback)415 OHOS::sptr<BufferProducerSequenceable> Test::StreamConsumer::CreateProducerSeq(
416 std::function<void(void*, uint32_t)> callback)
417 {
418 OHOS::sptr<OHOS::IBufferProducer> producer = CreateProducer(callback);
419 if (producer == nullptr) {
420 return nullptr;
421 }
422
423 return new BufferProducerSequenceable(producer);
424 }
425
OnCaptureStarted(int32_t captureId,const std::vector<int32_t> & streamId)426 int32_t Test::TestStreamOperatorCallback::OnCaptureStarted(int32_t captureId, const std::vector<int32_t> &streamId)
427 {
428 for (auto it : streamId) {
429 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d", captureId, it);
430 }
431 return HDI::Camera::V1_0::NO_ERROR;
432 }
433
OnCaptureEnded(int32_t captureId,const std::vector<CaptureEndedInfo> & infos)434 int32_t Test::TestStreamOperatorCallback::OnCaptureEnded(int32_t captureId, const std::vector<CaptureEndedInfo> &infos)
435 {
436 for (auto it : infos) {
437 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d, count: %{public}d", captureId, it.streamId_,
438 it.frameCount_);
439 }
440 return HDI::Camera::V1_0::NO_ERROR;
441 }
442
OnCaptureError(int32_t captureId,const std::vector<CaptureErrorInfo> & infos)443 int32_t Test::TestStreamOperatorCallback::OnCaptureError(int32_t captureId, const std::vector<CaptureErrorInfo> &infos)
444 {
445 for (auto it : infos) {
446 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d, error: %{public}d", captureId, it.streamId_,
447 it.error_);
448 }
449 return HDI::Camera::V1_0::NO_ERROR;
450 }
451
OnFrameShutter(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)452 int32_t Test::TestStreamOperatorCallback::OnFrameShutter(int32_t captureId,
453 const std::vector<int32_t> &streamIds, uint64_t timestamp)
454 {
455 (void)timestamp;
456 for (auto it : streamIds) {
457 CAMERA_LOGE("captureId: %{public}d, streamId: %{public}d", captureId, it);
458 }
459 return HDI::Camera::V1_0::NO_ERROR;
460 }
461
OnError(ErrorType type,int32_t errorMsg)462 int32_t Test::DemoCameraDeviceCallback::OnError(ErrorType type, int32_t errorMsg)
463 {
464 CAMERA_LOGE("type: %{public}d, errorMsg: %{public}d", type, errorMsg);
465 return HDI::Camera::V1_0::NO_ERROR;
466 }
467
OnResult(uint64_t timestamp,const std::vector<uint8_t> & result)468 int32_t Test::DemoCameraDeviceCallback::OnResult(uint64_t timestamp, const std::vector<uint8_t> &result)
469 {
470 if (Test::resultCallback_) {
471 std::shared_ptr<CameraMetadata> resultMeta;
472 MetadataUtils::ConvertVecToMetadata(result, resultMeta);
473 Test::resultCallback_(timestamp, resultMeta);
474 }
475 return HDI::Camera::V1_0::NO_ERROR;
476 }
477
OnCameraStatus(const std::string & cameraId,CameraStatus status)478 int32_t Test::TestCameraHostCallback::OnCameraStatus(const std::string& cameraId, CameraStatus status)
479 {
480 CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), status);
481 return HDI::Camera::V1_0::NO_ERROR;
482 }
483
OnFlashlightStatus(const std::string & cameraId,FlashlightStatus status)484 int32_t Test::TestCameraHostCallback::OnFlashlightStatus(const std::string& cameraId, FlashlightStatus status)
485 {
486 CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), status);
487 return HDI::Camera::V1_0::NO_ERROR;
488 }
489
OnCameraEvent(const std::string & cameraId,CameraEvent event)490 int32_t Test::TestCameraHostCallback::OnCameraEvent(const std::string& cameraId, CameraEvent event)
491 {
492 CAMERA_LOGE("cameraId: %{public}s, status: %{public}d", cameraId.c_str(), event);
493 return HDI::Camera::V1_0::NO_ERROR;
494 }
495
496 }
497