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