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