1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except 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
19 namespace OHOS::Camera {
GetCurrentLocalTimeStamp()20 uint64_t Test::GetCurrentLocalTimeStamp()
21 {
22 std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
23 std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
24 auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
25 return static_cast<uint64_t>(tmp.count());
26 }
27
CreateStreamOperatorCallback()28 void Test::CreateStreamOperatorCallback()
29 {
30 #ifdef CAMERA_BUILT_ON_OHOS_LITE
31 streamOperatorCallback = std::make_shared<OHOS::Camera::HdiOperatorCallback>(this);
32 #else
33 streamOperatorCallback = new HdiOperatorCallback(this);
34 #endif
35 }
36
CreateDeviceCallback()37 void Test::CreateDeviceCallback()
38 {
39 #ifdef CAMERA_BUILT_ON_OHOS_LITE
40 deviceCallback = std::make_shared<CameraDeviceCallback>();
41 #else
42 deviceCallback = new CameraDeviceCallback();
43 #endif
44 }
45
CreateOfflineStreamOperatorCallback()46 void Test::CreateOfflineStreamOperatorCallback()
47 {
48 #ifdef CAMERA_BUILT_ON_OHOS_LITE
49 offlineStreamOperatorCallback = std::make_shared<OHOS::Camera::StreamOperatorCallback>();
50 #else
51 offlineStreamOperatorCallback = streamOperatorCallback;
52 #endif
53 }
54
StreamInfoFormat()55 void Test::StreamInfoFormat()
56 {
57 #ifdef CAMERA_BUILT_ON_OHOS_LITE
58 streamInfo->format_ = IMAGE_PIXEL_FORMAT_NV21;
59 #else
60 streamInfo->format_ = PIXEL_FMT_YCRCB_420_SP;
61 #endif
62 }
63
SaveYUV(const char * type,const void * buffer,int32_t size)64 int32_t Test::SaveYUV(const char* type, const void* buffer, int32_t size)
65 {
66 if (strncmp(type, "preview", strlen(type)) == 0) {
67 previewBufCnt += 1;
68 if (previewBufCnt % 8 != 0) { // 8:Save one frame every eight frames
69 std::cout << "receive preview buffer not save" << std::endl;
70 return 0;
71 }
72 }
73 char path[PATH_MAX] = {0};
74 #ifdef CAMERA_BUILT_ON_OHOS_LITE
75 if (strncmp(type, "preview", strlen(type)) == 0) {
76 system("mkdir -p /userdata/camera");
77 char prefix[] = "/userdata/camera/";
78
79 if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "%s%s_%lld.yuv",
80 prefix, type, GetCurrentLocalTimeStamp()) < 0) {
81 CAMERA_LOGE("%s: sprintf path failed", __func__);
82 return 0;
83 }
84 } else {
85 system("mkdir -p /userdata/camera");
86 char prefix[] = "/userdata/camera/";
87
88 if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "%s%s_%lld.jpg",
89 prefix, type, GetCurrentLocalTimeStamp()) < 0) {
90 CAMERA_LOGE("%s: sprintf path failed", __func__);
91 return 0;
92 }
93 }
94 #else
95 if (strncmp(type, "preview", strlen(type)) == 0) {
96 system("mkdir -p /data/camera/preview");
97 char prefix[] = "/data/camera/preview/";
98
99 if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "%s%s_%lld.yuv",
100 prefix, type, GetCurrentLocalTimeStamp()) < 0) {
101 CAMERA_LOGE("%s: sprintf path failed", __func__);
102 return 0;
103 }
104 } else {
105 system("mkdir -p /data/camera/capture");
106 char prefix[] = "/data/camera/capture/";
107
108 if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "%s%s_%lld.jpg",
109 prefix, type, GetCurrentLocalTimeStamp()) < 0) {
110 CAMERA_LOGE("%s: sprintf path failed", __func__);
111 return 0;
112 }
113 }
114 #endif
115 std::cout << "save yuv to file:" << path << std::endl;
116 int imgFd = open(path, O_RDWR | O_CREAT | O_APPEND, 00766); // 00766:file jurisdiction
117 if (imgFd == -1) {
118 std::cout << "open file failed, errno = " << strerror(errno) << std::endl;
119 return -1;
120 }
121
122 int32_t ret = write(imgFd, buffer, size);
123 if (ret == -1) {
124 std::cout << "write file failed, error = " << strerror(errno) << std::endl;
125 close(imgFd);
126 return -1;
127 }
128 close(imgFd);
129 return 0;
130 }
131
SaveVideoFile(const char * type,const void * buffer,int32_t size,int32_t operationMode)132 int32_t Test::SaveVideoFile(const char* type, const void* buffer, int32_t size, int32_t operationMode)
133 {
134 std::cout << "SaveVideoFile: operationMode = " << operationMode << " videoFd = "<< videoFd << std::endl;
135 if (operationMode == 0) {
136 char path[PATH_MAX] = {0};
137 #ifdef CAMERA_BUILT_ON_OHOS_LITE
138 system("mkdir -p /userdata/camera");
139 char prefix[] = "/userdata/camera/";
140
141 if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "%s%s_%lld.h265",
142 prefix, type, GetCurrentLocalTimeStamp()) < 0) {
143 CAMERA_LOGE("%s: sprintf path failed", __func__);
144 return 0;
145 }
146 #else
147 system("mkdir -p /data/camera/video");
148 char prefix[] = "/data/camera/video/";
149
150 if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "%s%s_%lld.h265",
151 prefix, type, GetCurrentLocalTimeStamp()) < 0) {
152 CAMERA_LOGE("%s: sprintf path failed", __func__);
153 return 0;
154 }
155 #endif
156 CAMERA_LOGI("%{public}s, save yuv to file %{public}s", __FUNCTION__, path);
157 videoFd = open(path, O_RDWR | O_CREAT, 00766); // 00766:file jurisdiction
158 if (videoFd == -1) {
159 std::cout << "open file failed, errno = " << strerror(errno) << std::endl;
160 return -1;
161 }
162 } else if (operationMode == 1 && videoFd != -1) {
163 int32_t ret = write(videoFd, buffer, size);
164 if (ret == -1) {
165 std::cout << "write file failed, error = " << strerror(errno) << std::endl;
166 close(videoFd);
167 videoFd = -1;
168 return -1;
169 }
170 } else {
171 if (videoFd != -1) {
172 close(videoFd);
173 videoFd = -1;
174 }
175 }
176 return 0;
177 }
178
Init()179 void Test::Init()
180 {
181 #ifdef CAMERA_BUILT_ON_OHOS_LITE
182 if (service == nullptr) {
183 service = CameraHost::CreateCameraHost();
184 if (service == nullptr) {
185 std::cout << "==========[test log]ICameraHost get failed."<< std::endl;
186 } else {
187 std::cout << "==========[test log]ICameraHost get success."<< std::endl;
188 }
189 }
190 hostCallback = std::make_shared<HdiHostCallback>(this);
191 #else
192 if (service == nullptr) {
193 service = ICameraHost::Get("camera_service");
194 if (service == nullptr) {
195 std::cout << "==========[test log]ICameraHost get failed."<< std::endl;
196 } else {
197 std::cout << "==========[test log]ICameraHost get success."<< std::endl;
198 }
199 ASSERT_TRUE(service != nullptr);
200 }
201 hostCallback = new HdiHostCallback(this);
202 #endif
203 service->SetCallback(hostCallback);
204 }
205
GetCameraAbility()206 void Test::GetCameraAbility()
207 {
208 if (cameraDevice == nullptr) {
209 rc = service->GetCameraIds(cameraIds);
210 if (rc != Camera::NO_ERROR) {
211 std::cout << "==========[test log]GetCameraIds failed." << std::endl;
212 return;
213 } else {
214 std::cout << "==========[test log]GetCameraIds success." << std::endl;
215 }
216 GetCameraMetadata();
217 }
218 }
219
GetCameraMetadata()220 void Test::GetCameraMetadata()
221 {
222 rc = service->GetCameraAbility(cameraIds.front(), ability);
223 if (rc != Camera::NO_ERROR) {
224 std::cout << "==========[test log]GetCameraAbility failed, rc = " << rc << std::endl;
225 }
226 common_metadata_header_t* data = ability->get();
227 camera_metadata_item_t entry;
228 int ret = FindCameraMetadataItem(data, OHOS_CONTROL_AE_AVAILABLE_MODES, &entry);
229 if (ret == 0) {
230 std::cout << "==========[test log] get OHOS_CONTROL_AE_AVAILABLE_MODES success" << std::endl;
231 }
232 }
233
Open()234 void Test::Open()
235 {
236 if (cameraDevice == nullptr) {
237 service->GetCameraIds(cameraIds);
238 #ifdef CAMERA_BUILT_ON_OHOS_LITE
239 deviceCallback = std::make_shared<HdiDeviceCallback>(this);
240 #else
241 deviceCallback = new HdiDeviceCallback(this);
242 #endif
243 rc = service->OpenCamera(cameraIds.front(), deviceCallback, cameraDevice);
244 if (rc != Camera::NO_ERROR || cameraDevice == nullptr) {
245 std::cout << "==========[test log]OpenCamera failed, rc = " << rc << std::endl;
246 return;
247 }
248 std::cout << "==========[test log]OpenCamera success." << std::endl;
249 GetCameraMetadata();
250 }
251 }
252
Close()253 void Test::Close()
254 {
255 if (cameraDevice != nullptr) {
256 cameraDevice->Close();
257 std::cout << "cameraDevice->Close" << std::endl;
258 cameraDevice = nullptr;
259 }
260 }
261
StartStream(std::vector<Camera::StreamIntent> intents)262 void Test::StartStream(std::vector<Camera::StreamIntent> intents)
263 {
264 EXPECT_EQ(true, cameraDevice != nullptr);
265 CreateStreamOperatorCallback();
266 rc = cameraDevice->GetStreamOperator(streamOperatorCallback, streamOperator);
267 EXPECT_EQ(true, rc == Camera::NO_ERROR);
268 if (rc == Camera::NO_ERROR) {
269 std::cout << "==========[test log]GetStreamOperator success." << std::endl;
270 } else {
271 std::cout << "==========[test log]GetStreamOperator fail, rc = " << rc << std::endl;
272 }
273 streamInfo = std::make_shared<Camera::StreamInfo>();
274 streamInfo_video = std::make_shared<Camera::StreamInfo>();
275 streamInfo_capture = std::make_shared<Camera::StreamInfo>();
276 for (const auto& intent : intents) {
277 if (intent == 0) {
278 streamInfo->streamId_ = streamId_preview;
279 streamInfo->width_ = 640; // 640:width of stream
280 streamInfo->height_ = 480; // 480: height of stream
281 streamInfo->dataspace_ = 8; // 8:dataspace of stream
282 streamInfo->intent_ = intent;
283 streamInfo->tunneledMode_ = 5; // 5:tunneledMode of stream
284 StreamInfoFormat();
285 std::shared_ptr<StreamConsumer> consumer_pre = std::make_shared<StreamConsumer>();
286 std::cout << "==========[test log]received a preview buffer ... 0" << std::endl;
287 #ifdef CAMERA_BUILT_ON_OHOS_LITE
288 streamInfo->bufferQueue_ = consumer_pre->CreateProducer([this](OHOS::SurfaceBuffer* buffer) {
289 SaveYUV("preview", buffer->GetVirAddr(), buffer->GetSize());
290 });
291 #else
292 streamInfo->bufferQueue_ = consumer_pre->CreateProducer([this](void* addr, uint32_t size) {
293 SaveYUV("preview", addr, size);
294 });
295 #endif
296 streamInfo->bufferQueue_->SetQueueSize(8); // 8:bufferqueue size
297 consumerMap_[intent] = consumer_pre;
298 streamInfos.push_back(streamInfo);
299 } else if (intent == 1) {
300 streamInfo_video->streamId_ = streamId_video;
301 streamInfo_video->width_ = 1280; // 1280:width of stream
302 streamInfo_video->height_ = 960; // 960: height of stream
303 streamInfo_video->dataspace_ = 8; // 8:dataspace of stream
304 streamInfo_video->intent_ = intent;
305 streamInfo_video->encodeType_ = ENCODE_TYPE_H265;
306 streamInfo_video->tunneledMode_ = 5; // 5:tunneledMode of stream
307 #ifdef CAMERA_BUILT_ON_OHOS_LITE
308 streamInfo_video->format_ = IMAGE_PIXEL_FORMAT_NV21;
309 #else
310 streamInfo_video->format_ = PIXEL_FMT_YCRCB_420_SP;
311 #endif
312 std::shared_ptr<StreamConsumer> consumer_video = std::make_shared<StreamConsumer>();
313 std::cout << "==========[test log]received a video buffer ... 1" << std::endl;
314 SaveVideoFile("video", nullptr, 0, 0);
315 #ifdef CAMERA_BUILT_ON_OHOS_LITE
316 streamInfo_video->bufferQueue_ = consumer_video->CreateProducer([this](OHOS::SurfaceBuffer* buffer) {
317 int32_t size = 0;
318 buffer->GetInt32(OHOS::Camera::VIDEO_KEY_INFO_DATA_SIZE, size);
319 SaveVideoFile("video", buffer->GetVirAddr(), size, 1);
320 });
321 #else
322 streamInfo_video->bufferQueue_ = consumer_video->CreateProducer([this](void* addr, uint32_t size) {
323 SaveVideoFile("video", addr, size, 1);
324 });
325 #endif
326 streamInfo_video->bufferQueue_->SetQueueSize(8); // 8:bufferqueue size
327 consumerMap_[intent] = consumer_video;
328 streamInfos.push_back(streamInfo_video);
329 } else {
330 streamInfo_capture->streamId_ = streamId_capture;
331 streamInfo_capture->width_ = 1280; // 1280:width of stream
332 streamInfo_capture->height_ = 960; // 960: height of stream
333 streamInfo_capture->dataspace_ = 8; // 8:dataspace of stream
334 streamInfo_capture->intent_ = intent;
335 streamInfo_capture->encodeType_ = ENCODE_TYPE_JPEG;
336 streamInfo_capture->tunneledMode_ = 5; // 5:tunneledMode of stream
337 #ifdef CAMERA_BUILT_ON_OHOS_LITE
338 streamInfo_capture->format_ = IMAGE_PIXEL_FORMAT_NV21;
339 #else
340 streamInfo_capture->format_ = PIXEL_FMT_YCRCB_420_SP;
341 #endif
342 std::shared_ptr<StreamConsumer> consumer_capture = std::make_shared<StreamConsumer>();
343 std::cout << "==========[test log]received a capture buffer ... 2" << std::endl;
344 #ifdef CAMERA_BUILT_ON_OHOS_LITE
345 streamInfo_capture->bufferQueue_ = consumer_capture->CreateProducer([this](OHOS::SurfaceBuffer* buffer) {
346 SaveYUV("capture", buffer->GetVirAddr(), buffer->GetSize());
347 });
348 #else
349 streamInfo_capture->bufferQueue_ = consumer_capture->CreateProducer([this](void* addr, uint32_t size) {
350 SaveYUV("capture", addr, size);
351 });
352 #endif
353 streamInfo_capture->bufferQueue_->SetQueueSize(8); // 8:bufferqueue size
354 consumerMap_[intent] = consumer_capture;
355 streamInfos.push_back(streamInfo_capture);
356 }
357 }
358 rc = streamOperator->CreateStreams(streamInfos);
359 EXPECT_EQ(false, rc != Camera::NO_ERROR);
360 if (rc == Camera::NO_ERROR) {
361 std::cout << "==========[test log]CreateStreams success." << std::endl;
362 } else {
363 std::cout << "==========[test log]CreateStreams fail, rc = " << rc << std::endl;
364 }
365
366 rc = streamOperator->CommitStreams(Camera::NORMAL, ability);
367 EXPECT_EQ(false, rc != Camera::NO_ERROR);
368 if (rc == Camera::NO_ERROR) {
369 std::cout << "==========[test log]CommitStreams success." << std::endl;
370 } else {
371 std::cout << "==========[test log]CommitStreams fail, rc = " << rc << std::endl;
372 }
373 sleep(2); // 2:The program waits two seconds
374 std::vector<std::shared_ptr<Camera::StreamInfo>>().swap(streamInfos);
375 }
376
StartCapture(int streamId,int captureId,bool shutterCallback,bool isStreaming)377 void Test::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)
378 {
379 captureInfo = std::make_shared<Camera::CaptureInfo>();
380 captureInfo->streamIds_.push_back(streamId);
381 captureInfo->captureSetting_ = ability;
382 captureInfo->enableShutterCallback_ = shutterCallback;
383 rc = streamOperator->Capture(captureId, captureInfo, isStreaming);
384 EXPECT_EQ(true, rc == Camera::NO_ERROR);
385 if (rc == Camera::NO_ERROR) {
386 std::cout << "==========[test log]check Capture: Capture success, " << captureId << std::endl;
387 } else {
388 std::cout << "==========[test log]check Capture: Capture fail, rc = " << rc << std::endl;
389 }
390 sleep(1); // 1:Wait 1 seconds for the program to run
391 }
392
StopStream(std::vector<int> & captureIds,std::vector<int> & streamIds)393 void Test::StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)
394 {
395 if (captureIds.size() > 0) {
396 std::cout << "captureIds.size() = " << captureIds.size() << std::endl;
397 for (auto &captureId : captureIds) {
398 std::cout << "captureId = " << captureId << std::endl;
399 rc = streamOperator->CancelCapture(captureId);
400 EXPECT_EQ(true, rc == Camera::NO_ERROR);
401 if (rc == Camera::NO_ERROR) {
402 std::cout << "==========[test log]check Capture: CancelCapture success," << captureId << std::endl;
403 } else {
404 std::cout << "==========[test log]check Capture: CancelCapture fail, rc = " << rc << std::endl;
405 std::cout << "captureId = " << captureId << std::endl;
406 }
407 if (captureId == captureId_preview) {
408 captureId_preview++;
409 } else if (captureId == captureId_capture) {
410 captureId_capture++;
411 } else if (captureId == captureId_video) {
412 captureId_video++;
413 }
414 }
415 }
416 SaveVideoFile("video", nullptr, 0, 2); // 2:Operation Mode
417 if (streamIds.size() > 0) {
418 rc = streamOperator->ReleaseStreams(streamIds);
419 EXPECT_EQ(true, rc == Camera::NO_ERROR);
420 if (rc == Camera::NO_ERROR) {
421 std::cout << "==========[test log]check Capture: ReleaseStreams success." << std::endl;
422 } else {
423 std::cout << "==========[test log]check Capture: ReleaseStreams fail, rc = " << rc << std::endl;
424 }
425 }
426 streamIds.clear();
427 }
428
StopConsumer(std::vector<Camera::StreamIntent> intents)429 void Test::StopConsumer(std::vector<Camera::StreamIntent> intents)
430 {
431 for (const auto& intent : intents) {
432 consumerMap_[intent]->StopConsumer();
433 }
434 }
435
StopOfflineStream(int captureId)436 void Test::StopOfflineStream(int captureId)
437 {
438 captureId--;
439 rc = offlineStreamOperator->CancelCapture(captureId);
440 EXPECT_EQ(rc, Camera::NO_ERROR);
441 if (rc == Camera::NO_ERROR) {
442 std::cout << "==========[test log]check offline: CancelCapture success," << captureId << std::endl;
443 } else {
444 std::cout << "==========[test log]check offline: CancelCapture fail, rc = " << rc;
445 std::cout << "captureId = " << captureId << std::endl;
446 }
447 rc = offlineStreamOperator->Release();
448 EXPECT_EQ(rc, Camera::NO_ERROR);
449 if (rc == Camera::NO_ERROR) {
450 std::cout << "==========[test log]Check offline stream: offline Release success." << std::endl;
451 } else {
452 std::cout << "==========[test log]Check offline stream: offline Release fail, rc = " << rc << std::endl;
453 }
454 }
455
456 #ifdef CAMERA_BUILT_ON_OHOS_LITE
CreateProducer(std::function<void (OHOS::SurfaceBuffer *)> callback)457 std::shared_ptr<OHOS::Surface> Test::StreamConsumer::CreateProducer(std::function<void(OHOS::SurfaceBuffer*)> callback)
458 {
459 Surface* surface = OHOS::Surface::CreateSurface();
460 consumer_ = std::shared_ptr<OHOS::Surface>(surface);
461 if (consumer_ == nullptr) {
462 return nullptr;
463 }
464 callback_ = callback;
465
466 consumerThread_ = new std::thread([this] {
467 while (running_ == true) {
468 OHOS::SurfaceBuffer* buffer = consumer_->AcquireBuffer();
469 if (buffer != nullptr) {
470 if (callback_ != nullptr) {
471 callback_(buffer);
472 }
473 consumer_->ReleaseBuffer(buffer);
474 }
475 }
476 });
477 return consumer_;
478 }
479 #else
CreateProducer(std::function<void (void *,uint32_t)> callback)480 OHOS::sptr<OHOS::IBufferProducer> Test::StreamConsumer::CreateProducer(std::function<void(void*, uint32_t)> callback)
481 {
482 consumer_ = OHOS::Surface::CreateSurfaceAsConsumer();
483 if (consumer_ == nullptr) {
484 return nullptr;
485 }
486 sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
487 CHECK_IF_PTR_NULL_RETURN_VALUE(listener, nullptr);
488 consumer_->RegisterConsumerListener(listener);
489 auto producer = consumer_->GetProducer();
490 std::cout << "create a buffer queue producer:" << producer.GetRefPtr() << std::endl;
491 if (producer == nullptr) {
492 return nullptr;
493 }
494 callback_ = callback;
495 running_ = true;
496 consumerThread_ = new std::thread([this] {
497 int32_t flushFence = 0;
498 int64_t timestamp = 0;
499 OHOS::Rect damage;
500 OHOS::BufferRequestConfig config;
501 while (running_ == true) {
502 OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
503 consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage);
504 if (buffer != nullptr) {
505 void* addr = buffer->GetVirAddr();
506 uint32_t size = buffer->GetSize();
507 uint64_t pa = buffer->GetPhyAddr();
508 CAMERA_LOGI("consumer receive buffer add = %{public}llu", pa);
509 if (callback_ != nullptr) {
510 callback_(addr, size);
511 }
512 consumer_->ReleaseBuffer(buffer, -1);
513 CAMERA_LOGI("consumer release buffer add = %{public}llu", pa);
514 shotCount_--;
515 if (shotCount_ == 0) {
516 std::unique_lock<std::mutex> l(l_);
517 cv_.notify_one();
518 }
519 }
520 if (running_ == false) {
521 break;
522 }
523 }
524 return;
525 });
526 return producer;
527 }
528 #endif
529
StopConsumer()530 void Test::StreamConsumer::StopConsumer()
531 {
532 running_ = false;
533 }
534 }
535