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