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