• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 
18 namespace OHOS {
19 namespace DistributedHardware {
20 class DCameraHostCallback : public ICameraHostCallback {
21 public:
22     DCameraHostCallback() = default;
23     virtual ~DCameraHostCallback() = default;
24 
OnCameraStatus(const std::string & cameraId,CameraStatus status)25     int32_t OnCameraStatus(const std::string& cameraId, CameraStatus status)
26     {
27         (void)cameraId;
28         (void)status;
29         return 0;
30     }
31 
OnFlashlightStatus(const std::string & cameraId,FlashlightStatus status)32     int32_t OnFlashlightStatus(const std::string& cameraId, FlashlightStatus status)
33     {
34         (void)cameraId;
35         (void)status;
36         return 0;
37     }
38 
OnCameraEvent(const std::string & cameraId,CameraEvent event)39     int32_t OnCameraEvent(const std::string& cameraId, CameraEvent event)
40     {
41         (void)cameraId;
42         (void)event;
43         return 0;
44     }
45 };
46 
47 class DCameraDeviceCallback : public ICameraDeviceCallback {
48 public:
49     DCameraDeviceCallback() = default;
50     virtual ~DCameraDeviceCallback() = default;
51 
OnError(ErrorType type,int32_t errorCode)52     int32_t OnError(ErrorType type, int32_t errorCode)
53     {
54         (void)type;
55         (void)errorCode;
56         return 0;
57     }
58 
OnResult(uint64_t timestamp,const std::vector<uint8_t> & result)59     int32_t OnResult(uint64_t timestamp, const std::vector<uint8_t>& result)
60     {
61         (void)timestamp;
62         (void)result;
63         return 0;
64     }
65 };
66 
67 class DStreamOperatorCallback : public IStreamOperatorCallback {
68 public:
69     DStreamOperatorCallback() = default;
70     virtual ~DStreamOperatorCallback() = default;
71 
OnCaptureStarted(int32_t captureId,const std::vector<int32_t> & streamIds)72     int32_t OnCaptureStarted(int32_t captureId, const std::vector<int32_t>& streamIds)
73     {
74         (void)captureId;
75         (void)streamIds;
76         return 0;
77     }
78 
OnCaptureEnded(int32_t captureId,const std::vector<CaptureEndedInfo> & infos)79     int32_t OnCaptureEnded(int32_t captureId, const std::vector<CaptureEndedInfo>& infos)
80     {
81         (void)captureId;
82         (void)infos;
83         return 0;
84     }
85 
OnCaptureError(int32_t captureId,const std::vector<CaptureErrorInfo> & infos)86     int32_t OnCaptureError(int32_t captureId, const std::vector<CaptureErrorInfo>& infos)
87     {
88         (void)captureId;
89         (void)infos;
90         return 0;
91     }
92 
OnFrameShutter(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)93     int32_t OnFrameShutter(int32_t captureId, const std::vector<int32_t>& streamIds, uint64_t timestamp)
94     {
95         (void)captureId;
96         (void)streamIds;
97         (void)timestamp;
98         return 0;
99     }
100 };
101 
GetCurrentLocalTimeStamp()102 uint64_t Test::GetCurrentLocalTimeStamp()
103 {
104     std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
105         std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
106     auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
107     return static_cast<uint64_t>(tmp.count());
108 }
109 
SaveYUV(const char * type,const void * buffer,int32_t size)110 int32_t Test::SaveYUV(const char* type, const void* buffer, int32_t size)
111 {
112     if (strncmp(type, "preview", strlen(type)) == 0) {
113         previewBufCnt += 1;
114         int cycNum = 8;
115         if (previewBufCnt % cycNum != 0) {
116             std::cout << "receive preview buffer not save" << std::endl;
117             return 0;
118         }
119     }
120     char path[PATH_MAX] = {0};
121     if (strncmp(type, "preview", strlen(type)) == 0) {
122         system("mkdir -p /data/dcamera/preview");
123         if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/preview/%s_%lld.yuv",
124             type, GetCurrentLocalTimeStamp()) < 0) {
125             std::cout << "SaveYUV : preview sprintf_s fail." << std::endl;
126             return -1;
127         }
128     } else {
129         system("mkdir -p /data/dcamera/capture");
130         if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/capture/%s_%lld.jpg",
131             type, GetCurrentLocalTimeStamp()) < 0) {
132             std::cout << "SaveYUV : capture sprintf_s fail." << std::endl;
133             return -1;
134         }
135     }
136     std::cout << "save yuv to file:" << path << std::endl;
137 
138     int mode = 00766;
139     int imgFd = open(path, O_RDWR | O_CREAT, mode);
140     if (imgFd == -1) {
141         std::cout << "open file failed, errno = " << strerror(errno) << std::endl;
142         return -1;
143     }
144 
145     int ret = write(imgFd, buffer, size);
146     if (ret == -1) {
147         std::cout << "write file failed, error = " << strerror(errno) << std::endl;
148         close(imgFd);
149         return -1;
150     }
151     close(imgFd);
152     return 0;
153 }
154 
SaveVideoFile(const char * type,const void * buffer,int32_t size,int32_t operationMode)155 int32_t Test::SaveVideoFile(const char* type, const void* buffer, int32_t size, int32_t operationMode)
156 {
157     if (operationMode == 0) {
158         char path[PATH_MAX] = {0};
159         system("mkdir -p /data/dcamera/video");
160         if (sprintf_s(path, sizeof(path) / sizeof(path[0]), "/data/dcamera/video/%s_%lld.h265",
161             type, GetCurrentLocalTimeStamp()) < 0) {
162             std::cout << "SaveVideoFile : video sprintf_s fail." << std::endl;
163             return -1;
164         }
165         std::cout << "save yuv to file " << std::string(path) << std::endl;
166         int mode = 00766;
167         videoFd = open(path, O_RDWR | O_CREAT, mode);
168         if (videoFd == -1) {
169             std::cout << "open file failed, errno = " << strerror(errno) << std::endl;
170             return -1;
171         }
172     } else if (operationMode == 1 && videoFd != -1) {
173         int32_t ret = write(videoFd, buffer, size);
174         if (ret == -1) {
175             std::cout << "write file failed, error = " << strerror(errno) << std::endl;
176             close(videoFd);
177             return -1;
178         }
179     } else {
180         if (videoFd != -1) {
181             close(videoFd);
182         }
183     }
184     return 0;
185 }
186 
Init()187 void Test::Init()
188 {
189     if (service == nullptr) {
190         service = ICameraHost::Get("distributed_camera_service");
191         if (service == nullptr) {
192             std::cout << "==========[test log]ICameraHost get failed."<< std::endl;
193             return;
194         } else {
195             std::cout << "==========[test log]ICameraHost get success."<< std::endl;
196         }
197     }
198     hostCallback = new DCameraHostCallback();
199     service->SetCallback(hostCallback);
200 }
201 
GetCameraAbility()202 std::vector<uint8_t> Test::GetCameraAbility()
203 {
204     if (cameraDevice == nullptr) {
205         rc = service->GetCameraIds(cameraIds);
206         if (rc != NO_ERROR) {
207             std::cout << "==========[test log]GetCameraIds failed." << std::endl;
208             return ability;
209         } else {
210             std::cout << "==========[test log]GetCameraIds success." << std::endl;
211         }
212         if (cameraIds.size() == 0) {
213             std::cout << "==========[test log]camera device list is empty." << std::endl;
214             return ability;
215         }
216         GetCameraMetadata();
217     }
218     return ability;
219 }
220 
GetCameraMetadata()221 void Test::GetCameraMetadata()
222 {
223     rc = service->GetCameraAbility(cameraIds.front(), ability);
224     if (rc != NO_ERROR) {
225         std::cout << "==========[test log]GetCameraAbility failed, rc = " << rc << std::endl;
226     }
227     std::shared_ptr<OHOS::Camera::CameraMetadata> abililyMeta = nullptr;
228     OHOS::Camera::MetadataUtils::ConvertVecToMetadata(abilily, abililyMeta);
229     common_metadata_header_t* data = abililyMeta->get();
230     camera_metadata_item_t entry;
231     int ret = OHOS::Camera::FindCameraMetadataItem(data, OHOS_CONTROL_AE_AVAILABLE_MODES, &entry);
232     if (ret == 0) {
233         std::cout << "==========[test log] get OHOS_CONTROL_AE_AVAILABLE_MODES success" << std::endl;
234     }
235 }
236 
Open()237 void Test::Open()
238 {
239     if (cameraDevice == nullptr) {
240         service->GetCameraIds(cameraIds);
241         if (cameraIds.size() == 0) {
242             std::cout << "==========[test log]camera device list empty." << std::endl;
243             return;
244         }
245         GetCameraMetadata();
246         deviceCallback = new DCameraDeviceCallback();
247         rc = service->OpenCamera(cameraIds.front(), deviceCallback, cameraDevice);
248         if (rc != NO_ERROR || cameraDevice == nullptr) {
249             std::cout << "==========[test log]OpenCamera failed, rc = " << rc << std::endl;
250             return;
251         }
252         std::cout << "==========[test log]OpenCamera success." << std::endl;
253     }
254 }
255 
Close()256 void Test::Close()
257 {
258     if (cameraDevice != nullptr) {
259         cameraDevice->Close();
260         std::cout << "cameraDevice->Close" << std::endl;
261         cameraDevice = nullptr;
262     }
263     consumerMap_.clear();
264     if (hostCallback != nullptr) {
265         hostCallback = nullptr;
266     }
267     if (deviceCallback != nullptr) {
268         deviceCallback = nullptr;
269     }
270     if (streamOperatorCallback != nullptr) {
271         streamOperatorCallback = nullptr;
272     }
273 }
274 
SetPreviewStreamInfo()275 void Test::SetPreviewStreamInfo()
276 {
277     int dataspace = 8;
278     int tunneledMode = 5;
279     int bufferQueueSize = 8;
280     streamInfo_pre.streamId_ = streamId_preview;
281     streamInfo_pre.width_ = preview_width;
282     streamInfo_pre.height_ = preview_height;
283     streamInfo_pre.format_ = preview_format;
284     streamInfo_pre.dataspace_ = dataspace;
285     streamInfo_pre.intent_ = PREVIEW;
286     streamInfo_pre.tunneledMode_ = tunneledMode;
287     std::shared_ptr<StreamConsumer> consumer_pre = std::make_shared<StreamConsumer>();
288     std::cout << "==========[test log]received a preview buffer ... 0" << std::endl;
289     streamInfo_pre.bufferQueue_ = new BufferProducerSequenceable();
290     streamInfo_pre.bufferQueue_->producer_ = consumer_pre->CreateProducer([this](void* addr, uint32_t size) {
291         SaveYUV("preview", addr, size);
292     });
293     streamInfo_pre.bufferQueue_->producer_->SetQueueSize(bufferQueueSize);
294     consumerMap_[intent] = consumer_pre;
295     streamInfos.push_back(streamInfo_pre);
296 }
297 
SetVideoStreamInfo()298 void Test::SetVideoStreamInfo()
299 {
300     int dataspace = 8;
301     int tunneledMode = 5;
302     int bufferQueueSize = 8;
303     streamInfo_video.streamId_ = streamId_video;
304     streamInfo_video.width_ = video_width;
305     streamInfo_video.height_ = video_height;
306     streamInfo_video.format_ = video_format;
307     streamInfo_video.dataspace_ = dataspace;
308     streamInfo_video.intent_ = VIDEO;
309     streamInfo_video.encodeType_ = OHOS::HDI::Camera::V1_0::ENCODE_TYPE_H265;
310     streamInfo_video.tunneledMode_ = tunneledMode;
311     std::shared_ptr<StreamConsumer> consumer_video = std::make_shared<StreamConsumer>();
312     std::cout << "==========[test log]received a video buffer ... 1" << std::endl;
313     SaveVideoFile("video", nullptr, 0, 0);
314     streamInfo_video.bufferQueue_ = new BufferProducerSequenceable();
315     streamInfo_video.bufferQueue_->producer_ = consumer_video->CreateProducer([this](void* addr, uint32_t size) {
316         SaveVideoFile("video", addr, size, 1);
317     });
318     streamInfo_video.bufferQueue_->producer_->SetQueueSize(bufferQueueSize);
319     consumerMap_[intent] = consumer_video;
320     streamInfos.push_back(streamInfo_video);
321 }
322 
SetPhotoStreamInfo()323 void Test::SetPhotoStreamInfo()
324 {
325     int dataspace = 8;
326     int tunneledMode = 5;
327     int bufferQueueSize = 8;
328     streamInfo_capture.streamId_ = streamId_capture;
329     streamInfo_capture.width_ = snapshot_width;
330     streamInfo_capture.height_ = snapshot_height;
331     streamInfo_capture.format_ = snapshot_format;
332     streamInfo_capture.dataspace_ = dataspace;
333     streamInfo_capture.intent_ = STILL_CAPTURE;
334     streamInfo_capture.encodeType_ = OHOS::HDI::Camera::V1_0::ENCODE_TYPE_JPEG;
335     streamInfo_capture.tunneledMode_ = tunneledMode;
336     std::shared_ptr<StreamConsumer> consumer_capture = std::make_shared<StreamConsumer>();
337     std::cout << "==========[test log]received a capture buffer ... 2" << std::endl;
338     streamInfo_capture.bufferQueue_ = new BufferProducerSequenceable();
339     streamInfo_capture.bufferQueue_->producer_ =
340         consumer_capture->CreateProducer([this](void* addr, uint32_t size) {
341             SaveYUV("capture", addr, size);
342     });
343     streamInfo_capture.bufferQueue_->producer_->SetQueueSize(bufferQueueSize);
344     consumerMap_[intent] = consumer_capture;
345     streamInfos.push_back(streamInfo_capture);
346 }
347 
StartStream(std::vector<StreamIntent> intents)348 void Test::StartStream(std::vector<StreamIntent> intents)
349 {
350     streamOperatorCallback = new DStreamOperatorCallback();
351     rc = cameraDevice->GetStreamOperator(streamOperatorCallback, streamOperator);
352     if (rc == NO_ERROR) {
353         std::cout << "==========[test log]GetStreamOperator success." << std::endl;
354     } else {
355         std::cout << "==========[test log]GetStreamOperator fail, rc = " << rc << std::endl;
356     }
357     int dataspace = 8;
358     int tunneledMode = 5;
359     int bufferQueueSize = 8;
360     for (auto& intent : intents) {
361         if (intent == 0) {
362             SetPreviewStreamInfo();
363         } else if (intent == 1) {
364             SetVideoStreamInfo();
365         } else {
366             SetPhotoStreamInfo();
367         }
368     }
369 
370     rc = streamOperator->CreateStreams(streamInfos);
371     if (rc == NO_ERROR) {
372         std::cout << "==========[test log]CreateStreams success." << std::endl;
373     } else {
374         std::cout << "==========[test log]CreateStreams fail, rc = " << rc << std::endl;
375     }
376     rc = streamOperator->CommitStreams(NORMAL, ability);
377     if (rc == NO_ERROR) {
378         std::cout << "==========[test log]CommitStreams success." << std::endl;
379     } else {
380         std::cout << "==========[test log]CommitStreams fail, rc = " << rc << std::endl;
381     }
382     unsigned int sleepSeconds = 2;
383     sleep(sleepSeconds);
384     std::vector<std::shared_ptr<StreamInfo>>().swap(streamInfos);
385 }
386 
StartCapture(int streamId,int captureId,bool shutterCallback,bool isStreaming)387 void Test::StartCapture(int streamId, int captureId, bool shutterCallback, bool isStreaming)
388 {
389     captureInfo.streamIds_ = { streamId };
390     captureInfo.captureSetting_ = ability;
391     captureInfo.enableShutterCallback_ = shutterCallback;
392     rc = streamOperator->Capture(captureId, captureInfo, isStreaming);
393     if (rc == NO_ERROR) {
394         std::cout << "==========[test log]check Capture: Capture success, " << captureId << std::endl;
395     } else {
396         std::cout << "==========[test log]check Capture: Capture fail, rc = " << rc << std::endl;
397     }
398     unsigned int sleepSeconds = 5;
399     sleep(sleepSeconds);
400 }
401 
StopStream(std::vector<int> & captureIds,std::vector<int> & streamIds)402 void Test::StopStream(std::vector<int>& captureIds, std::vector<int>& streamIds)
403 {
404     if (sizeof(captureIds) > 0) {
405         for (auto &captureId : captureIds) {
406             rc = streamOperator->CancelCapture(captureId);
407             if (rc == NO_ERROR) {
408                 std::cout << "==========[test log]check Capture: CancelCapture success," << captureId << std::endl;
409             } else {
410                 std::cout << "==========[test log]check Capture: CancelCapture fail, rc = " << rc;
411                 std::cout << "captureId = " << captureId << std::endl;
412             }
413         }
414     }
415     int32_t operationMode = 2;
416     SaveVideoFile("video", nullptr, 0, operationMode);
417     if (sizeof(streamIds) > 0) {
418         rc = streamOperator->ReleaseStreams(streamIds);
419         if (rc == NO_ERROR) {
420             std::cout << "==========[test log]check Capture: ReleaseStreams success." << std::endl;
421         } else {
422             std::cout << "==========[test log]check Capture: ReleaseStreams fail, rc = " << rc << std::endl;
423         }
424     }
425 }
426 
StopOfflineStream(int captureId)427 void Test::StopOfflineStream(int captureId)
428 {
429     rc = offlineStreamOperator->CancelCapture(captureId);
430     if (rc == NO_ERROR) {
431         std::cout << "==========[test log]check offline: CancelCapture success," << captureId << std::endl;
432     } else {
433         std::cout << "==========[test log]check offline: CancelCapture fail, rc = " << rc;
434         std::cout << "captureId = " << captureId << std::endl;
435     }
436     rc = offlineStreamOperator->Release();
437     if (rc == NO_ERROR) {
438         std::cout << "==========[test log]Check offline stream: offline Release success." << std::endl;
439     } else {
440         std::cout << "==========[test log]Check offline stream: offline Release fail, rc = " << rc << std::endl;
441     }
442 }
443 
CreateProducer(std::function<void (void *,uint32_t)> callback)444 OHOS::sptr<OHOS::IBufferProducer> Test::StreamConsumer::CreateProducer(std::function<void(void*, uint32_t)> callback)
445 {
446     consumer_ = OHOS::Surface::CreateSurfaceAsConsumer();
447     if (consumer_ == nullptr) {
448         return nullptr;
449     }
450     sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
451     consumer_->RegisterConsumerListener(listener);
452     auto producer = consumer_->GetProducer();
453     std::cout << "create a buffer queue producer:" << producer.GetRefPtr() << std::endl;
454     if (producer == nullptr) {
455         return nullptr;
456     }
457     callback_ = callback;
458     consumerThread_ = new std::thread([this] {
459         int32_t flushFence = 0;
460         int64_t timestamp = 0;
461         OHOS::Rect damage;
462         while (running_) {
463             OHOS::sptr<OHOS::SurfaceBuffer> buffer = nullptr;
464             consumer_->AcquireBuffer(buffer, flushFence, timestamp, damage);
465             if (buffer != nullptr) {
466                 void* addr = buffer->GetVirAddr();
467                 uint32_t size = buffer->GetSize();
468 
469                 int32_t gotSize = 0;
470                 int32_t isKey = 0;
471                 int64_t timestamp;
472                 buffer->ExtraGet("dataSize", gotSize);
473                 buffer->ExtraGet("isKeyFrame", isKey);
474                 buffer->ExtraGet("timeStamp", timestamp);
475                 if (gotSize) {
476                     std::cout << "dataSize: " << gotSize << ", isKeyFrame: "
477                              << isKey << " timeStamp:" << timestamp << endl;
478                 }
479 
480                 callback_(addr, size);
481                 consumer_->ReleaseBuffer(buffer, -1);
482                 shotCount_--;
483                 if (shotCount_ == 0) {
484                     std::unique_lock<std::mutex> l(l_);
485                     cv_.notify_one();
486                 }
487             }
488             if (!running_) {
489                 break;
490             }
491             std::this_thread::sleep_for(1ms);
492         }
493     });
494     return producer;
495 }
496 } // namespace DistributedHardware
497 } // namespace OHOS
498