• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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