• 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     int32_t expo = 0;
228     camera_metadata_item_t entry;
229     int ret = Camera::FindCameraMetadataItem(data, OHOS_CONTROL_AE_AVAILABLE_MODES, &entry);
230     if (ret == 0) {
231         std::cout << "==========[test log] get OHOS_CONTROL_AE_AVAILABLE_MODES success" << std::endl;
232     }
233 }
234 
Open()235 void Test::Open()
236 {
237     if (cameraDevice == nullptr) {
238         service->GetCameraIds(cameraIds);
239 #ifdef CAMERA_BUILT_ON_OHOS_LITE
240         deviceCallback = std::make_shared<HdiDeviceCallback>(this);
241 #else
242         deviceCallback = new HdiDeviceCallback(this);
243 #endif
244         rc = service->OpenCamera(cameraIds.front(), deviceCallback, cameraDevice);
245         if (rc != Camera::NO_ERROR || cameraDevice == nullptr) {
246             std::cout << "==========[test log]OpenCamera failed, rc = " << rc << std::endl;
247             return;
248         }
249         std::cout << "==========[test log]OpenCamera success." << std::endl;
250         GetCameraMetadata();
251     }
252 }
253 
Close()254 void Test::Close()
255 {
256     if (cameraDevice != nullptr) {
257         cameraDevice->Close();
258         std::cout << "cameraDevice->Close" << std::endl;
259         cameraDevice = nullptr;
260     }
261 }
262 
StartStream(std::vector<Camera::StreamIntent> intents)263 void Test::StartStream(std::vector<Camera::StreamIntent> intents)
264 {
265     EXPECT_EQ(true, cameraDevice != nullptr);
266     CreateStreamOperatorCallback();
267     rc = cameraDevice->GetStreamOperator(streamOperatorCallback, streamOperator);
268     EXPECT_EQ(true, rc == Camera::NO_ERROR);
269     if (rc == Camera::NO_ERROR) {
270         std::cout << "==========[test log]GetStreamOperator success." << std::endl;
271     } else {
272         std::cout << "==========[test log]GetStreamOperator fail, rc = " << rc << std::endl;
273     }
274     streamInfo = std::make_shared<Camera::StreamInfo>();
275     streamInfo_video = std::make_shared<Camera::StreamInfo>();
276     streamInfo_capture = std::make_shared<Camera::StreamInfo>();
277     for (auto& intent : intents) {
278         if (intent == 0) {
279             streamInfo->streamId_ = streamId_preview;
280             streamInfo->width_ = 640; // 640:width of stream
281             streamInfo->height_ = 480; // 480: height of stream
282             streamInfo->datasapce_ = 8; // 8:datasapce of stream
283             streamInfo->intent_ = intent;
284             streamInfo->tunneledMode_ = 5; // 5:tunneledMode of stream
285             StreamInfoFormat();
286             std::shared_ptr<StreamConsumer> consumer_pre = std::make_shared<StreamConsumer>();
287             std::cout << "==========[test log]received a preview buffer ... 0" << std::endl;
288 #ifdef CAMERA_BUILT_ON_OHOS_LITE
289             streamInfo->bufferQueue_ = consumer_pre->CreateProducer([this](OHOS::SurfaceBuffer* buffer) {
290                 SaveYUV("preview", buffer->GetVirAddr(), buffer->GetSize());
291             });
292 #else
293             streamInfo->bufferQueue_ = consumer_pre->CreateProducer([this](void* addr, uint32_t size) {
294                 SaveYUV("preview", addr, size);
295             });
296 #endif
297             streamInfo->bufferQueue_->SetQueueSize(8); // 8:bufferqueue size
298             consumerMap_[intent] = consumer_pre;
299             streamInfos.push_back(streamInfo);
300         } else if (intent == 1) {
301             streamInfo_video->streamId_ = streamId_video;
302             streamInfo_video->width_ = 1280; // 1280:width of stream
303             streamInfo_video->height_ = 960; // 960: height of stream
304             streamInfo_video->datasapce_ = 8; // 8:datasapce of stream
305             streamInfo_video->intent_ = intent;
306             streamInfo_video->encodeType_ = ENCODE_TYPE_H265;
307             streamInfo_video->tunneledMode_ = 5; // 5:tunneledMode of stream
308 #ifdef CAMERA_BUILT_ON_OHOS_LITE
309             streamInfo_video->format_ = IMAGE_PIXEL_FORMAT_NV21;
310 #else
311             streamInfo_video->format_ = PIXEL_FMT_YCRCB_420_SP;
312 #endif
313             std::shared_ptr<StreamConsumer> consumer_video = std::make_shared<StreamConsumer>();
314             std::cout << "==========[test log]received a video buffer ... 1" << std::endl;
315             SaveVideoFile("video", nullptr, 0, 0);
316 #ifdef CAMERA_BUILT_ON_OHOS_LITE
317             streamInfo_video->bufferQueue_ = consumer_video->CreateProducer([this](OHOS::SurfaceBuffer* buffer) {
318                 int32_t size = 0;
319                 buffer->GetInt32(OHOS::Camera::VIDEO_KEY_INFO_DATA_SIZE, size);
320                 SaveVideoFile("video", buffer->GetVirAddr(), size, 1);
321             });
322 #else
323             streamInfo_video->bufferQueue_ = consumer_video->CreateProducer([this](void* addr, uint32_t size) {
324                 SaveVideoFile("video", addr, size, 1);
325             });
326 #endif
327             streamInfo_video->bufferQueue_->SetQueueSize(8); // 8:bufferqueue size
328             consumerMap_[intent] = consumer_video;
329             streamInfos.push_back(streamInfo_video);
330         } else {
331             streamInfo_capture->streamId_ = streamId_capture;
332             streamInfo_capture->width_ = 1280; // 1280:width of stream
333             streamInfo_capture->height_ = 960; // 960: height of stream
334             streamInfo_capture->datasapce_ = 8; // 8:datasapce of stream
335             streamInfo_capture->intent_ = intent;
336             streamInfo_capture->encodeType_ = ENCODE_TYPE_JPEG;
337             streamInfo_capture->tunneledMode_ = 5; // 5:tunneledMode of stream
338 #ifdef CAMERA_BUILT_ON_OHOS_LITE
339             streamInfo_capture->format_ = IMAGE_PIXEL_FORMAT_NV21;
340 #else
341             streamInfo_capture->format_ = PIXEL_FMT_YCRCB_420_SP;
342 #endif
343             std::shared_ptr<StreamConsumer> consumer_capture = std::make_shared<StreamConsumer>();
344             std::cout << "==========[test log]received a capture buffer ... 2" << std::endl;
345 #ifdef CAMERA_BUILT_ON_OHOS_LITE
346             streamInfo_capture->bufferQueue_ = consumer_capture->CreateProducer([this](OHOS::SurfaceBuffer* buffer) {
347                 SaveYUV("capture", buffer->GetVirAddr(), buffer->GetSize());
348             });
349 #else
350             streamInfo_capture->bufferQueue_ = consumer_capture->CreateProducer([this](void* addr, uint32_t size) {
351                 SaveYUV("capture", addr, size);
352             });
353 #endif
354             streamInfo_capture->bufferQueue_->SetQueueSize(8); // 8:bufferqueue size
355             consumerMap_[intent] = consumer_capture;
356             streamInfos.push_back(streamInfo_capture);
357         }
358     }
359     rc = streamOperator->CreateStreams(streamInfos);
360     EXPECT_EQ(false, rc != Camera::NO_ERROR);
361     if (rc == Camera::NO_ERROR) {
362         std::cout << "==========[test log]CreateStreams success." << std::endl;
363     } else {
364         std::cout << "==========[test log]CreateStreams fail, rc = " << rc << std::endl;
365     }
366 
367     rc = streamOperator->CommitStreams(Camera::NORMAL, ability);
368     EXPECT_EQ(false, rc != Camera::NO_ERROR);
369     if (rc == Camera::NO_ERROR) {
370         std::cout << "==========[test log]CommitStreams success." << std::endl;
371     } else {
372         std::cout << "==========[test log]CommitStreams fail, rc = " << rc << std::endl;
373     }
374     sleep(2); // 2:The program waits two seconds
375     std::vector<std::shared_ptr<Camera::StreamInfo>>().swap(streamInfos);
376 }
377 
StartCapture(int streamId,int captureId,bool shutterCallback,bool isStreaming)378 void Test::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)
379 {
380     captureInfo = std::make_shared<Camera::CaptureInfo>();
381     captureInfo->streamIds_.push_back(streamId);
382     captureInfo->captureSetting_ = ability;
383     captureInfo->enableShutterCallback_ = shutterCallback;
384     rc = streamOperator->Capture(captureId, captureInfo, isStreaming);
385     EXPECT_EQ(true, rc == Camera::NO_ERROR);
386     if (rc == Camera::NO_ERROR) {
387         std::cout << "==========[test log]check Capture: Capture success, " << captureId << std::endl;
388     } else {
389         std::cout << "==========[test log]check Capture: Capture fail, rc = " << rc << std::endl;
390     }
391     sleep(1); // 1:Wait 1 seconds for the program to run
392 }
393 
StopStream(std::vector<int> & captureIds,std::vector<int> & streamIds)394 void Test::StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)
395 {
396     if (captureIds.size() > 0) {
397         std::cout << "captureIds.size() = " << captureIds.size() << std::endl;
398         for (auto &captureId : captureIds) {
399             std::cout << "captureId = " << captureId << std::endl;
400             rc = streamOperator->CancelCapture(captureId);
401             EXPECT_EQ(true, rc == Camera::NO_ERROR);
402             if (rc == Camera::NO_ERROR) {
403                 std::cout << "==========[test log]check Capture: CancelCapture success," << captureId << std::endl;
404             } else {
405                 std::cout << "==========[test log]check Capture: CancelCapture fail, rc = " << rc << std::endl;
406                 std::cout << "captureId = " << captureId << std::endl;
407             }
408             if (captureId == captureId_preview) {
409                 captureId_preview++;
410             } else if (captureId == captureId_capture) {
411                 captureId_capture++;
412             } else if (captureId == captureId_video) {
413                 captureId_video++;
414             }
415         }
416     }
417     SaveVideoFile("video", nullptr, 0, 2); // 2:Operation Mode
418     if (streamIds.size() > 0) {
419         rc = streamOperator->ReleaseStreams(streamIds);
420         EXPECT_EQ(true, rc == Camera::NO_ERROR);
421         if (rc == Camera::NO_ERROR) {
422             std::cout << "==========[test log]check Capture: ReleaseStreams success." << std::endl;
423         } else {
424             std::cout << "==========[test log]check Capture: ReleaseStreams fail, rc = " << rc << std::endl;
425         }
426     }
427     streamIds.clear();
428 }
429 
StopConsumer(std::vector<Camera::StreamIntent> intents)430 void Test::StopConsumer(std::vector<Camera::StreamIntent> intents)
431 {
432     for (auto& intent : intents) {
433         consumerMap_[intent]->StopConsumer();
434     }
435 }
436 
StopOfflineStream(int captureId)437 void Test::StopOfflineStream(int captureId)
438 {
439     captureId--;
440     rc = offlineStreamOperator->CancelCapture(captureId);
441     EXPECT_EQ(rc, Camera::NO_ERROR);
442     if (rc == Camera::NO_ERROR) {
443         std::cout << "==========[test log]check offline: CancelCapture success," << captureId << std::endl;
444     } else {
445         std::cout << "==========[test log]check offline: CancelCapture fail, rc = " << rc;
446         std::cout << "captureId = " << captureId << std::endl;
447     }
448     rc = offlineStreamOperator->Release();
449     EXPECT_EQ(rc, Camera::NO_ERROR);
450     if (rc == Camera::NO_ERROR) {
451         std::cout << "==========[test log]Check offline stream: offline Release success." << std::endl;
452     } else {
453         std::cout << "==========[test log]Check offline stream: offline Release fail, rc = " << rc << std::endl;
454     }
455 }
456 
457 #ifdef CAMERA_BUILT_ON_OHOS_LITE
CreateProducer(std::function<void (OHOS::SurfaceBuffer *)> callback)458 std::shared_ptr<OHOS::Surface> Test::StreamConsumer::CreateProducer(std::function<void(OHOS::SurfaceBuffer*)> callback)
459 {
460     Surface* surface = OHOS::Surface::CreateSurface();
461     consumer_ = std::shared_ptr<OHOS::Surface>(surface);
462     if (consumer_ == nullptr) {
463         return nullptr;
464     }
465     callback_ = callback;
466 
467     consumerThread_ = new std::thread([this] {
468         while (running_ == true) {
469             OHOS::SurfaceBuffer* buffer = consumer_->AcquireBuffer();
470             if (buffer != nullptr) {
471                 if (callback_ != nullptr) {
472                     callback_(buffer);
473                 }
474                 consumer_->ReleaseBuffer(buffer);
475             }
476         }
477     });
478     return consumer_;
479 }
480 #else
CreateProducer(std::function<void (void *,uint32_t)> callback)481 OHOS::sptr<OHOS::IBufferProducer> Test::StreamConsumer::CreateProducer(std::function<void(void*, uint32_t)> callback)
482 {
483     consumer_ = OHOS::Surface::CreateSurfaceAsConsumer();
484     if (consumer_ == nullptr) {
485         return nullptr;
486     }
487     sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
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