1 /*
2 * Copyright (c) 2021-2024 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 "dstream_operator.h"
17 #include "dbuffer_manager.h"
18 #include "dcamera_provider.h"
19 #include "dcamera.h"
20 #include "distributed_hardware_log.h"
21 #include "metadata_utils.h"
22 #include "constants.h"
23
24 namespace OHOS {
25 namespace DistributedHardware {
DStreamOperator(std::shared_ptr<DMetadataProcessor> & dMetadataProcessor)26 DStreamOperator::DStreamOperator(std::shared_ptr<DMetadataProcessor> &dMetadataProcessor)
27 : dMetadataProcessor_(dMetadataProcessor)
28 {
29 DHLOGI("DStreamOperator construct");
30 }
31
IsStreamsSupported(OperationMode mode,const std::vector<uint8_t> & modeSetting,const std::vector<StreamInfo> & infos,StreamSupportType & type)32 int32_t DStreamOperator::IsStreamsSupported(OperationMode mode, const std::vector<uint8_t> &modeSetting,
33 const std::vector<StreamInfo> &infos, StreamSupportType &type)
34 {
35 if (IsStreamInfosInvalid(infos)) {
36 DHLOGE("DStreamOperator::IsStreamsSupported, input stream infos is invalid.");
37 return CamRetCode::INVALID_ARGUMENT;
38 }
39
40 (void)mode;
41 (void)modeSetting;
42 type = DYNAMIC_SUPPORTED;
43
44 for (const auto &it : infos) {
45 int id = it.streamId_;
46 if (FindHalStreamById(id) != nullptr) {
47 DHLOGE("Repeat streamId.");
48 return CamRetCode::INVALID_ARGUMENT;
49 }
50 }
51 return CamRetCode::NO_ERROR;
52 }
53
IsStreamsSupported_V1_1(OperationMode_V1_1 mode,const std::vector<uint8_t> & modeSetting,const std::vector<StreamInfo_V1_1> & infos,StreamSupportType & type)54 int32_t DStreamOperator::IsStreamsSupported_V1_1(OperationMode_V1_1 mode, const std::vector<uint8_t> &modeSetting,
55 const std::vector<StreamInfo_V1_1> &infos, StreamSupportType &type)
56 {
57 DHLOGI("IsStreamsSupported_V1_1 start.");
58 std::vector<StreamInfo> streamInfos_v1_0;
59 for (auto info_v1_1 : infos) {
60 streamInfos_v1_0.push_back(info_v1_1.v1_0);
61 }
62 OperationMode modeV0 = static_cast<OperationMode>(mode);
63 return IsStreamsSupported(modeV0, modeSetting, streamInfos_v1_0, type);
64 }
65
CreateStreams(const std::vector<StreamInfo> & streamInfos)66 int32_t DStreamOperator::CreateStreams(const std::vector<StreamInfo> &streamInfos)
67 {
68 if (IsStreamInfosInvalid(streamInfos)) {
69 DHLOGE("DStreamOperator::CreateStreams, input stream Infos is invalid.");
70 return CamRetCode::INVALID_ARGUMENT;
71 }
72
73 DHLOGI("DStreamOperator::CreateStreams, input stream info size=%{public}zu.", streamInfos.size());
74
75 for (const auto &info : streamInfos) {
76 DHLOGI("DStreamOperator::CreateStreams, streamInfo: id=%{public}d, width=%{public}d, "
77 "height=%{public}d, format=%{public}d, dataspace=%{public}d, encodeType=%{public}d",
78 info.streamId_, info.width_, info.height_, info.format_, info.dataspace_, info.encodeType_);
79 if (FindHalStreamById(info.streamId_) != nullptr) {
80 return CamRetCode::INVALID_ARGUMENT;
81 }
82 if (!info.tunneledMode_) {
83 return CamRetCode::METHOD_NOT_SUPPORTED;
84 }
85
86 std::shared_ptr<DCameraStream> dcStream = std::make_shared<DCameraStream>();
87 DCamRetCode ret = dcStream->InitDCameraStream(info);
88 if (ret != SUCCESS) {
89 DHLOGE("Init distributed camera stream failed.");
90 return CamRetCode::INVALID_ARGUMENT;
91 }
92 InsertHalStream(info.streamId_, dcStream);
93
94 std::shared_ptr<DCStreamInfo> dcStreamInfo = std::make_shared<DCStreamInfo>();
95 ConvertStreamInfo(info, dcStreamInfo);
96 InsertDCStream(info.streamId_, dcStreamInfo);
97 DHLOGI("DStreamOperator::CreateStreams, dcStreamInfo: id=%{public}d, type=%{public}d, width=%{public}d, "
98 "height=%{public}d, format=%{public}d, dataspace=%{public}d, encodeType=%{public}d",
99 dcStreamInfo->streamId_, dcStreamInfo->type_, dcStreamInfo->width_,
100 dcStreamInfo->height_, dcStreamInfo->format_, dcStreamInfo->dataspace_, dcStreamInfo->encodeType_);
101 }
102 DHLOGI("DStreamOperator::Create distributed camera streams success.");
103 return CamRetCode::NO_ERROR;
104 }
105
CreateStreams_V1_1(const std::vector<StreamInfo_V1_1> & streamInfos)106 int32_t DStreamOperator::CreateStreams_V1_1(const std::vector<StreamInfo_V1_1> &streamInfos)
107 {
108 DHLOGI("CreateStreams_V1_1 start.");
109 std::vector<StreamInfo> streamInfos_v1_0;
110 for (auto info_v1_1 : streamInfos) {
111 streamInfos_v1_0.push_back(info_v1_1.v1_0);
112 }
113 return CreateStreams(streamInfos_v1_0);
114 }
115
ReleaseStreams(const std::vector<int32_t> & streamIds)116 int32_t DStreamOperator::ReleaseStreams(const std::vector<int32_t> &streamIds)
117 {
118 if (streamIds.empty() || streamIds.size() > CONTAINER_CAPACITY_MAX_SIZE) {
119 DHLOGE("DStreamOperator::ReleaseStreams, input streamIds is invalid.");
120 return CamRetCode::INVALID_ARGUMENT;
121 }
122
123 DHLOGI("DStreamOperator::ReleaseStreams, input stream id list size=%{public}zu.", streamIds.size());
124
125 if (IsCapturing()) {
126 DHLOGE("Can not release streams when capture.");
127 return CamRetCode::CAMERA_BUSY;
128 }
129
130 for (int id : streamIds) {
131 auto stream = FindHalStreamById(id);
132 if (stream != nullptr) {
133 DCamRetCode ret = stream->ReleaseDCameraBufferQueue();
134 if (ret != SUCCESS) {
135 DHLOGE("Release distributed camera buffer queue for stream %{public}d failed.", id);
136 return MapToExternalRetCode(ret);
137 } else {
138 DHLOGI("Release distributed camera buffer queue for stream %{public}d success.", id);
139 }
140 stream = nullptr;
141 EraseHalStream(id);
142 EraseDCStream(id);
143 } else {
144 DHLOGE("Error streamId %{public}d.", id);
145 return CamRetCode::INVALID_ARGUMENT;
146 }
147 }
148
149 OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
150 if (provider == nullptr) {
151 DHLOGE("DCameraProvider not init.");
152 return CamRetCode::DEVICE_ERROR;
153 }
154 int32_t ret = provider->ReleaseStreams(dhBase_, streamIds);
155 if (ret != SUCCESS) {
156 DHLOGE("Release distributed camera streams failed.");
157 return MapToExternalRetCode(static_cast<DCamRetCode>(ret));
158 }
159
160 DHLOGI("DStreamOperator::Release distributed camera streams success.");
161 return CamRetCode::NO_ERROR;
162 }
163
ExtractStreamInfo(std::vector<DCStreamInfo> & dCameraStreams)164 int32_t DStreamOperator::ExtractStreamInfo(std::vector<DCStreamInfo>& dCameraStreams)
165 {
166 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
167 if (dcStreamInfoMap_.size() == 0) {
168 DHLOGE("No stream to extract.");
169 return CamRetCode::INVALID_ARGUMENT;
170 }
171 for (auto streamInfo : dcStreamInfoMap_) {
172 DCStreamInfo dstStreamInfo;
173 dstStreamInfo.streamId_ = streamInfo.second->streamId_;
174 dstStreamInfo.width_ = streamInfo.second->width_;
175 dstStreamInfo.height_ = streamInfo.second->height_;
176 dstStreamInfo.stride_ = streamInfo.second->stride_;
177 dstStreamInfo.format_ = streamInfo.second->format_;
178 dstStreamInfo.dataspace_ = streamInfo.second->dataspace_;
179 dstStreamInfo.encodeType_ = streamInfo.second->encodeType_;
180 dstStreamInfo.type_ = streamInfo.second->type_;
181 dstStreamInfo.mode_ = currentOperMode_;
182 dCameraStreams.push_back(dstStreamInfo);
183 }
184 return CamRetCode::NO_ERROR;
185 }
186
UpdateStreams(const std::vector<StreamInfo_V1_1> & streamInfos)187 int32_t DStreamOperator::UpdateStreams(const std::vector<StreamInfo_V1_1> &streamInfos)
188 {
189 (void)streamInfos;
190 return CamRetCode::NO_ERROR;
191 }
192
ConfirmCapture(int32_t cId)193 int32_t DStreamOperator::ConfirmCapture(int32_t cId)
194 {
195 (void)cId;
196 return CamRetCode::NO_ERROR;
197 }
198
CommitStreams(OperationMode mode,const std::vector<uint8_t> & modeSetting)199 int32_t DStreamOperator::CommitStreams(OperationMode mode, const std::vector<uint8_t> &modeSetting)
200 {
201 OperationMode_V1_1 modeV1 = static_cast<OperationMode_V1_1>(mode);
202 return CommitStreams_V1_1(modeV1, modeSetting);
203 }
204
CommitStreams_V1_1(OperationMode_V1_1 mode,const std::vector<uint8_t> & modeSetting)205 int32_t DStreamOperator::CommitStreams_V1_1(OperationMode_V1_1 mode, const std::vector<uint8_t> &modeSetting)
206 {
207 DHLOGI("DStreamOperator::CommitStreams, input operation mode=%{public}d.", mode);
208
209 if (modeSetting.empty() || modeSetting.size() > METADATA_CAPACITY_MAX_SIZE) {
210 DHLOGE("DStreamOperator::CommitStreams, input modeSetting is invalid.");
211 return CamRetCode::INVALID_ARGUMENT;
212 }
213
214 if (IsCapturing()) {
215 DHLOGE("Can not commit streams when capture.");
216 return CamRetCode::CAMERA_BUSY;
217 }
218
219 currentOperMode_ = mode;
220
221 std::shared_ptr<OHOS::Camera::CameraMetadata> setting = nullptr;
222 OHOS::Camera::MetadataUtils::ConvertVecToMetadata(modeSetting, setting);
223 if (setting == nullptr || setting.get() == nullptr) {
224 DHLOGE("Input stream mode setting is invalid.");
225 } else {
226 latestStreamSetting_ = setting;
227 }
228
229 std::vector<DCStreamInfo> dCameraStreams;
230 int32_t ret = ExtractStreamInfo(dCameraStreams);
231 if (ret != CamRetCode::NO_ERROR) {
232 DHLOGE("No stream to commit.");
233 return ret;
234 }
235
236 OHOS::sptr<DCameraProvider> dProvider = DCameraProvider::GetInstance();
237 if (dProvider == nullptr) {
238 DHLOGE("DCameraProvider not init.");
239 return CamRetCode::DEVICE_ERROR;
240 }
241 ret = dProvider->ConfigureStreams(dhBase_, dCameraStreams);
242 if (ret != DCamRetCode::SUCCESS) {
243 DHLOGE("Commit distributed camera streams failed.");
244 return MapToExternalRetCode(static_cast<DCamRetCode>(ret));
245 }
246
247 for (size_t i = 0; i < dCameraStreams.size(); i++) {
248 auto streamInfo = dCameraStreams[i];
249 HalStreamCommit(streamInfo);
250 }
251 DHLOGI("DStreamOperator::Commit distributed camera streams success.");
252 return CamRetCode::NO_ERROR;
253 }
254
HalStreamCommit(const DCStreamInfo & streamInfo)255 int32_t DStreamOperator::HalStreamCommit(const DCStreamInfo &streamInfo)
256 {
257 auto stream = FindHalStreamById(streamInfo.streamId_);
258 if (stream != nullptr) {
259 int32_t ret = stream->FinishCommitStream();
260 if (ret != DCamRetCode::SUCCESS) {
261 DHLOGE("Stream %{public}d cannot init.", streamInfo.streamId_);
262 return MapToExternalRetCode(static_cast<DCamRetCode>(ret));
263 }
264 }
265 return CamRetCode::NO_ERROR;
266 }
267
GetStreamAttributes(std::vector<StreamAttribute> & attributes)268 int32_t DStreamOperator::GetStreamAttributes(std::vector<StreamAttribute> &attributes)
269 {
270 attributes.clear();
271 std::lock_guard<std::mutex> autoLock(halStreamLock_);
272 for (const auto &stream : halStreamMap_) {
273 StreamAttribute attribute;
274 DCamRetCode ret = stream.second->GetDCameraStreamAttribute(attribute);
275 if (ret != SUCCESS) {
276 DHLOGE("Get distributed camera stream attribute failed.");
277 attributes.clear();
278 return MapToExternalRetCode(ret);
279 }
280 attributes.push_back(attribute);
281 }
282 return CamRetCode::NO_ERROR;
283 }
284
AttachBufferQueue(int32_t streamId,const sptr<BufferProducerSequenceable> & bufferProducer)285 int32_t DStreamOperator::AttachBufferQueue(int32_t streamId, const sptr<BufferProducerSequenceable> &bufferProducer)
286 {
287 if (streamId < 0) {
288 DHLOGE("DStreamOperator::AttachBufferQueue, input streamId is invalid.");
289 return CamRetCode::INVALID_ARGUMENT;
290 }
291
292 if (bufferProducer == nullptr) {
293 DHLOGE("DStreamOperator::AttachBufferQueue, input bufferProducer is null.");
294 return CamRetCode::INVALID_ARGUMENT;
295 }
296
297 if (IsCapturing()) {
298 DHLOGE("Can not attach buffer queue when capture.");
299 return CamRetCode::CAMERA_BUSY;
300 }
301
302 auto stream = FindHalStreamById(streamId);
303 if (stream != nullptr) {
304 DCamRetCode ret = stream->SetDCameraBufferQueue(bufferProducer);
305 if (ret != SUCCESS) {
306 DHLOGE("Attach distributed camera buffer queue failed.");
307 }
308 return MapToExternalRetCode(ret);
309 } else {
310 DHLOGE("Not found stream id %{public}d when attach bubfer queue.", streamId);
311 return CamRetCode::INVALID_ARGUMENT;
312 }
313 }
314
IsStreamInfosInvalid(const std::vector<StreamInfo> & infos)315 bool DStreamOperator::IsStreamInfosInvalid(const std::vector<StreamInfo> &infos)
316 {
317 if (infos.empty() || infos.size() > CONTAINER_CAPACITY_MAX_SIZE) {
318 return true;
319 }
320 for (auto streamInfo : infos) {
321 if (streamInfo.streamId_ < 0 ||
322 streamInfo.width_ < 0 ||
323 streamInfo.width_ > (STREAM_WIDTH_MAX_SIZE * STREAM_HEIGHT_MAX_SIZE) ||
324 streamInfo.height_ < 0 ||
325 streamInfo.height_ > (STREAM_WIDTH_MAX_SIZE * STREAM_HEIGHT_MAX_SIZE) ||
326 streamInfo.format_ < 0 ||
327 streamInfo.dataspace_ < 0) {
328 return true;
329 }
330 }
331 return false;
332 }
333
IsCaptureInfoInvalid(const CaptureInfo & info)334 bool DStreamOperator::IsCaptureInfoInvalid(const CaptureInfo &info)
335 {
336 return info.streamIds_.size() == 0 || info.streamIds_.size() > CONTAINER_CAPACITY_MAX_SIZE ||
337 info.captureSetting_.size() == 0 || info.captureSetting_.size() > CONTAINER_CAPACITY_MAX_SIZE;
338 }
339
DetachBufferQueue(int32_t streamId)340 int32_t DStreamOperator::DetachBufferQueue(int32_t streamId)
341 {
342 if (streamId < 0) {
343 DHLOGE("DStreamOperator::DetachBufferQueue, input streamId is invalid.");
344 return CamRetCode::INVALID_ARGUMENT;
345 }
346
347 if (IsCapturing()) {
348 DHLOGE("Can not detach buffer queue when capture.");
349 return CamRetCode::CAMERA_BUSY;
350 }
351
352 auto stream = FindHalStreamById(streamId);
353 if (stream != nullptr) {
354 DCamRetCode ret = stream->ReleaseDCameraBufferQueue();
355 if (ret != SUCCESS) {
356 DHLOGE("Detach distributed camera buffer queue failed.");
357 }
358 return MapToExternalRetCode(ret);
359 } else {
360 DHLOGE("Not found stream id %{public}d when detach bubfer queue.", streamId);
361 return CamRetCode::INVALID_ARGUMENT;
362 }
363 }
364
ExtractCaptureInfo(std::vector<DCCaptureInfo> & captureInfos)365 void DStreamOperator::ExtractCaptureInfo(std::vector<DCCaptureInfo> &captureInfos)
366 {
367 for (const auto &captureInfo : cachedDCaptureInfoList_) {
368 DCCaptureInfo capture;
369 capture.streamIds_.assign(captureInfo->streamIds_.begin(), captureInfo->streamIds_.end());
370 capture.width_ = captureInfo->width_;
371 capture.height_ = captureInfo->height_;
372 capture.stride_ = captureInfo->stride_;
373 capture.format_ = captureInfo->format_;
374 capture.dataspace_ = captureInfo->dataspace_;
375 capture.isCapture_ = captureInfo->isCapture_;
376 capture.encodeType_ = captureInfo->encodeType_;
377 capture.type_ = captureInfo->type_;
378 capture.captureSettings_.assign(captureInfo->captureSettings_.begin(), captureInfo->captureSettings_.end());
379 captureInfos.emplace_back(capture);
380 }
381 }
382
Capture(int32_t captureId,const CaptureInfo & info,bool isStreaming)383 int32_t DStreamOperator::Capture(int32_t captureId, const CaptureInfo &info, bool isStreaming)
384 {
385 if (IsCaptureInfoInvalid(info)) {
386 DHLOGE("DStreamOperator::Capture, input capture info is invalid.");
387 return CamRetCode::INVALID_ARGUMENT;
388 }
389 if (captureId < 0 || FindCaptureInfoById(captureId) != nullptr) {
390 DHLOGE("Input captureId %{public}d is exist.", captureId);
391 return CamRetCode::INVALID_ARGUMENT;
392 }
393 DHLOGI("get currentOperMode_ %{public}d", currentOperMode_);
394 DCamRetCode ret = InitOutputConfigurations(dhBase_, sinkAbilityInfo_, sourceCodecInfo_);
395 if (ret != SUCCESS) {
396 DHLOGE("Init distributed camera output configurations failed, ret=%{public}d.", ret);
397 return ret;
398 }
399 return DoCapture(captureId, info, isStreaming);
400 }
401
DoCapture(int32_t captureId,const CaptureInfo & info,bool isStreaming)402 int32_t DStreamOperator::DoCapture(int32_t captureId, const CaptureInfo &info, bool isStreaming)
403 {
404 for (const auto &id : info.streamIds_) {
405 InsertNotifyCaptureMap(id);
406 auto stream = FindHalStreamById(id);
407 if (stream == nullptr) {
408 DHLOGE("Invalid stream id %{public}d", id);
409 return CamRetCode::INVALID_ARGUMENT;
410 }
411 if (!stream->HasBufferQueue()) {
412 DHLOGE("Stream %{public}d has not bufferQueue.", id);
413 return CamRetCode::INVALID_ARGUMENT;
414 }
415 stream->DoCapture();
416 InsertEnableShutter(id, info.enableShutterCallback_);
417 DHLOGI("DStreamOperator::DoCapture info: "
418 "captureId=%{public}d, streamId=%{public}d, isStreaming=%{public}d", captureId, id, isStreaming);
419 }
420
421 DCamRetCode ret = NegotiateSuitableCaptureInfo(info, isStreaming);
422 if (ret != SUCCESS) {
423 DHLOGE("Negotiate suitable capture info failed.");
424 return MapToExternalRetCode(ret);
425 }
426
427 OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
428 if (provider == nullptr) {
429 DHLOGE("Distributed camera provider not init.");
430 return CamRetCode::DEVICE_ERROR;
431 }
432 std::vector<DCCaptureInfo> captureInfos;
433 ExtractCaptureInfo(captureInfos);
434 int32_t retProv = provider->StartCapture(dhBase_, captureInfos);
435 if (retProv != SUCCESS) {
436 DHLOGE("Start distributed camera capture failed.");
437 return MapToExternalRetCode(static_cast<DCamRetCode>(retProv));
438 }
439 std::shared_ptr<CaptureInfo> captureInfo = std::make_shared<CaptureInfo>();
440 captureInfo->streamIds_.assign(info.streamIds_.begin(), info.streamIds_.end());
441 captureInfo->captureSetting_.assign(info.captureSetting_.begin(), info.captureSetting_.end());
442 captureInfo->enableShutterCallback_ = info.enableShutterCallback_;
443 InsertCaptureInfo(captureId, captureInfo);
444
445 SetCapturing(true);
446 DHLOGI("DStreamOperator::DoCapture, start distributed camera capture success.");
447
448 return CamRetCode::NO_ERROR;
449 }
450
CancelCapture(int32_t captureId)451 int32_t DStreamOperator::CancelCapture(int32_t captureId)
452 {
453 if (captureId < 0) {
454 DHLOGE("DStreamOperator::CancelCapture, input captureId is valid.");
455 return CamRetCode::INVALID_ARGUMENT;
456 }
457
458 DHLOGI("DStreamOperator::CancelCapture, cancel distributed camera capture, captureId=%{public}d.", captureId);
459 auto halCaptureInfo = FindCaptureInfoById(captureId);
460 if (captureId < 0 || halCaptureInfo == nullptr) {
461 DHLOGE("Input captureId %{public}d is not exist.", captureId);
462 return CamRetCode::INVALID_ARGUMENT;
463 }
464
465 OHOS::sptr<DCameraProvider> provider = DCameraProvider::GetInstance();
466 if (provider == nullptr) {
467 DHLOGE("Distributed camera provider not init.");
468 return CamRetCode::DEVICE_ERROR;
469 }
470
471 std::vector<int> streamIds = halCaptureInfo->streamIds_;
472 int32_t ret = provider->StopCapture(dhBase_, streamIds);
473 if (ret != SUCCESS) {
474 DHLOGE("Cancel distributed camera capture failed.");
475 return MapToExternalRetCode(static_cast<DCamRetCode>(ret));
476 }
477
478 std::vector<CaptureEndedInfo> info;
479 for (auto id : streamIds) {
480 auto stream = FindHalStreamById(id);
481 if (stream != nullptr) {
482 stream->CancelCaptureWait();
483 }
484 CaptureEndedInfo tmp;
485 tmp.frameCount_ = FindStreamCaptureBufferNum(std::make_pair(captureId, id));
486 tmp.streamId_ = id;
487 info.push_back(tmp);
488 EraseStreamCaptureBufferNum(std::make_pair(captureId, id));
489 EraseNotifyCaptureMap(id);
490 }
491 if (dcStreamOperatorCallback_) {
492 dcStreamOperatorCallback_->OnCaptureEnded(captureId, info);
493 }
494
495 EraseCaptureInfo(captureId);
496 if (!HasContinuousCaptureInfo(captureId)) {
497 SetCapturing(false);
498 cachedDCaptureInfoList_.clear();
499 }
500 DHLOGI("DStreamOperator::CancelCapture success, captureId=%{public}d.", captureId);
501 return CamRetCode::NO_ERROR;
502 }
503
HasContinuousCaptureInfo(int captureId)504 bool DStreamOperator::HasContinuousCaptureInfo(int captureId)
505 {
506 bool flag = false;
507 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
508 for (auto iter : halCaptureInfoMap_) {
509 for (auto id : iter.second->streamIds_) {
510 auto dcStreamInfo = dcStreamInfoMap_.find(id);
511 if (dcStreamInfo == dcStreamInfoMap_.end()) {
512 continue;
513 }
514
515 DHLOGI("DStreamOperator::HasContinuousCaptureInfo, captureId=%{public}d, streamId=%{public}d, streamType="
516 "%{public}d", captureId, id, dcStreamInfo->second->type_);
517 if (dcStreamInfo->second->type_ == DCStreamType::CONTINUOUS_FRAME) {
518 DHLOGI("DStreamOperator::HasContinuousCaptureInfo, captureId=%d, stream %d is continuous stream.",
519 captureId, id);
520 flag = true;
521 break;
522 }
523 }
524 }
525 return flag;
526 }
527
ChangeToOfflineStream(const std::vector<int32_t> & streamIds,const sptr<IStreamOperatorCallback> & callbackObj,sptr<IOfflineStreamOperator> & offlineOperator)528 int32_t DStreamOperator::ChangeToOfflineStream(const std::vector<int32_t> &streamIds,
529 const sptr<IStreamOperatorCallback> &callbackObj, sptr<IOfflineStreamOperator> &offlineOperator)
530 {
531 (void)streamIds;
532 (void)callbackObj;
533 offlineOperator = nullptr;
534 return CamRetCode::METHOD_NOT_SUPPORTED;
535 }
536
537
EnableResult(int32_t streamId,const std::vector<uint8_t> & results)538 int32_t DStreamOperator::EnableResult(int32_t streamId, const std::vector<uint8_t> &results)
539 {
540 return CamRetCode::NO_ERROR;
541 }
542
DisableResult(int32_t streamId,const std::vector<uint8_t> & results)543 int32_t DStreamOperator::DisableResult(int32_t streamId, const std::vector<uint8_t> &results)
544 {
545 return CamRetCode::NO_ERROR;
546 }
547
GetFormatObj(const std::string rootNode,cJSON * rootValue,std::string & formatStr)548 cJSON* DStreamOperator::GetFormatObj(const std::string rootNode, cJSON* rootValue, std::string& formatStr)
549 {
550 cJSON* nodeObj = cJSON_GetObjectItemCaseSensitive(rootValue, rootNode.c_str());
551 if (nodeObj == nullptr || !cJSON_IsObject(nodeObj)) {
552 return nullptr;
553 }
554 cJSON* resObj = cJSON_GetObjectItemCaseSensitive(nodeObj, "Resolution");
555 if (resObj == nullptr || !cJSON_IsObject(resObj)) {
556 return nullptr;
557 }
558 cJSON *formatObj = cJSON_GetObjectItemCaseSensitive(resObj, formatStr.c_str());
559 if (formatObj == nullptr || !cJSON_IsArray(formatObj) || cJSON_GetArraySize(formatObj) == 0 ||
560 static_cast<uint32_t>(cJSON_GetArraySize(formatObj)) > JSON_ARRAY_MAX_SIZE) {
561 return nullptr;
562 }
563 return formatObj;
564 }
565
ExtractCameraAttr(cJSON * rootValue,std::vector<int> & formats,const std::string rootNode)566 void DStreamOperator::ExtractCameraAttr(cJSON* rootValue, std::vector<int>& formats, const std::string rootNode)
567 {
568 for (const auto &format : formats) {
569 std::string formatStr = std::to_string(format);
570 cJSON *formatObj = GetFormatObj(rootNode, rootValue, formatStr);
571 if (formatObj == nullptr) {
572 DHLOGE("Resolution or %{public}s error.", formatStr.c_str());
573 continue;
574 }
575 GetCameraAttr(rootValue, formatStr, rootNode, format);
576 }
577 }
578
GetCameraAttr(cJSON * rootValue,std::string formatStr,const std::string rootNode,int format)579 void DStreamOperator::GetCameraAttr(cJSON *rootValue, std::string formatStr, const std::string rootNode,
580 int format)
581 {
582 std::vector<DCResolution> resolutionVec;
583 cJSON *formatObj = GetFormatObj(rootNode, rootValue, formatStr);
584 if (formatObj == nullptr) {
585 return;
586 }
587 int32_t size = cJSON_GetArraySize(formatObj);
588 for (int32_t i = 0; i < size; i++) {
589 cJSON *item = cJSON_GetArrayItem(formatObj, i);
590 if (item == nullptr || !cJSON_IsString(item)) {
591 DHLOGE("Resolution %{public}s %{public}d ,is not string.", formatStr.c_str(), i);
592 continue;
593 }
594 std::string resoStr = std::string(item->valuestring);
595 std::vector<std::string> reso;
596 SplitString(resoStr, reso, STAR_SEPARATOR);
597 if (reso.size() != SIZE_FMT_LEN) {
598 continue;
599 }
600 uint32_t width = static_cast<uint32_t>(std::stoi(reso[0]));
601 uint32_t height = static_cast<uint32_t>(std::stoi(reso[1]));
602 if (height == 0 || width == 0 ||
603 ((rootNode == "Photo") &&
604 ((width * height) > (MAX_SUPPORT_PHOTO_WIDTH * MAX_SUPPORT_PHOTO_HEIGHT))) ||
605 ((rootNode != "Photo") &&
606 (width > MAX_SUPPORT_PREVIEW_WIDTH || height > MAX_SUPPORT_PREVIEW_HEIGHT))) {
607 continue;
608 }
609 DCResolution resolution(width, height);
610 resolutionVec.push_back(resolution);
611 }
612 if (!resolutionVec.empty()) {
613 std::sort(resolutionVec.begin(), resolutionVec.end());
614 if (rootNode == "Preview") {
615 dcSupportedPreviewResolutionMap_[format] = resolutionVec;
616 } else if (rootNode == "Video") {
617 dcSupportedVideoResolutionMap_[format] = resolutionVec;
618 } else if (rootNode == "Photo") {
619 dcSupportedPhotoResolutionMap_[format] = resolutionVec;
620 }
621 }
622 }
623
SetOutputVal(const DHBase & dhBase,const std::string & sinkAbilityInfo,const std::string & sourceCodecInfo)624 DCamRetCode DStreamOperator::SetOutputVal(const DHBase &dhBase, const std::string &sinkAbilityInfo,
625 const std::string &sourceCodecInfo)
626 {
627 dhBase_ = dhBase;
628 sinkAbilityInfo_ = sinkAbilityInfo;
629 sourceCodecInfo_ = sourceCodecInfo;
630 return SUCCESS;
631 }
632
InitOutputConfigurations(const DHBase & dhBase,const std::string & sinkAbilityInfo,const std::string & sourceCodecInfo)633 DCamRetCode DStreamOperator::InitOutputConfigurations(const DHBase &dhBase, const std::string &sinkAbilityInfo,
634 const std::string &sourceCodecInfo)
635 {
636 cJSON *rootValue = cJSON_Parse(sinkAbilityInfo.c_str());
637 CHECK_NULL_RETURN_LOG(rootValue, DCamRetCode::INVALID_ARGUMENT, "The sinkAbilityInfo is null.");
638 CHECK_OBJECT_FREE_RETURN(rootValue, DCamRetCode::INVALID_ARGUMENT, "The sinkAbilityInfo is not object.");
639
640 cJSON *srcRootValue = cJSON_Parse(sourceCodecInfo.c_str());
641 CHECK_NULL_FREE_RETURN(srcRootValue, DCamRetCode::INVALID_ARGUMENT, rootValue);
642 if (!cJSON_IsObject(srcRootValue)) {
643 cJSON_Delete(srcRootValue);
644 cJSON_Delete(rootValue);
645 DHLOGE("Input source ablity info is not json object.");
646 return DCamRetCode::INVALID_ARGUMENT;
647 }
648 dcSupportedCodecType_ = ParseEncoderTypes(rootValue);
649 sourceEncodeTypes_ = ParseEncoderTypes(srcRootValue);
650 if (dcSupportedCodecType_.empty() || sourceEncodeTypes_.empty()) {
651 DHLOGE("Get CodeType failed.");
652 cJSON_Delete(rootValue);
653 cJSON_Delete(srcRootValue);
654 return DCamRetCode::INVALID_ARGUMENT;
655 }
656
657 if (currentOperMode_ == 0) {
658 if (ParsePhotoFormats(rootValue) != SUCCESS || ParsePreviewFormats(rootValue) != SUCCESS ||
659 ParseVideoFormats(rootValue) != SUCCESS) {
660 cJSON_Delete(rootValue);
661 cJSON_Delete(srcRootValue);
662 return DCamRetCode::INVALID_ARGUMENT;
663 }
664 } else {
665 cJSON *modeValue = cJSON_GetObjectItemCaseSensitive(rootValue, std::to_string(currentOperMode_).c_str());
666 if (modeValue == nullptr || !cJSON_IsObject(modeValue)) {
667 cJSON_Delete(rootValue);
668 cJSON_Delete(srcRootValue);
669 return DCamRetCode::INVALID_ARGUMENT;
670 }
671 if (ParsePhotoFormats(modeValue) != SUCCESS || ParsePreviewFormats(modeValue) != SUCCESS ||
672 ParseVideoFormats(modeValue) != SUCCESS) {
673 cJSON_Delete(rootValue);
674 cJSON_Delete(srcRootValue);
675 return DCamRetCode::INVALID_ARGUMENT;
676 }
677 }
678
679 if (!CheckInputInfo()) {
680 cJSON_Delete(rootValue);
681 cJSON_Delete(srcRootValue);
682 return DEVICE_NOT_INIT;
683 }
684 cJSON_Delete(rootValue);
685 cJSON_Delete(srcRootValue);
686 return SUCCESS;
687 }
688
CheckInputInfo()689 bool DStreamOperator::CheckInputInfo()
690 {
691 bool resolutionMap = false;
692 if (!dcSupportedPhotoResolutionMap_.empty() || !dcSupportedPreviewResolutionMap_.empty() ||
693 !dcSupportedVideoResolutionMap_.empty()) {
694 resolutionMap = true;
695 }
696
697 if (dcSupportedCodecType_.empty() || dcSupportedFormatMap_.empty() || !resolutionMap) {
698 DHLOGE("Input ablity info is invalid.");
699 return false;
700 }
701 return true;
702 }
703
ParseEncoderTypes(cJSON * rootValue)704 std::vector<DCEncodeType> DStreamOperator::ParseEncoderTypes(cJSON* rootValue)
705 {
706 std::vector<DCEncodeType> enCoders;
707 cJSON *codecObj = cJSON_GetObjectItemCaseSensitive(rootValue, "CodecType");
708 if (codecObj == nullptr || !cJSON_IsArray(codecObj) || cJSON_GetArraySize(codecObj) == 0 ||
709 static_cast<uint32_t>(cJSON_GetArraySize(codecObj)) > JSON_ARRAY_MAX_SIZE) {
710 DHLOGE("Get CodecType error.");
711 return enCoders;
712 }
713
714 int32_t size = cJSON_GetArraySize(codecObj);
715 for (int32_t i = 0; i < size; i++) {
716 cJSON *item = cJSON_GetArrayItem(codecObj, i);
717 if (item == nullptr || !cJSON_IsString(item)) {
718 DHLOGE("Get CodecType error.");
719 return enCoders;
720 }
721 std::string codeType = std::string(item->valuestring);
722 enCoders.push_back(ConvertDCEncodeType(codeType));
723 }
724 return enCoders;
725 }
726
ParsePhotoFormats(cJSON * rootValue)727 DCamRetCode DStreamOperator::ParsePhotoFormats(cJSON* rootValue)
728 {
729 cJSON *photoObj = cJSON_GetObjectItemCaseSensitive(rootValue, "Photo");
730 if (photoObj == nullptr || !cJSON_IsObject(photoObj)) {
731 DHLOGE("Photo error.");
732 return DCamRetCode::INVALID_ARGUMENT;
733 }
734 cJSON *formatObj = cJSON_GetObjectItemCaseSensitive(photoObj, "OutputFormat");
735 if (formatObj == nullptr || !cJSON_IsArray(formatObj) || cJSON_GetArraySize(formatObj) == 0 ||
736 static_cast<uint32_t>(cJSON_GetArraySize(formatObj)) > JSON_ARRAY_MAX_SIZE) {
737 DHLOGE("Photo output format error.");
738 return DCamRetCode::INVALID_ARGUMENT;
739 }
740
741 std::vector<int> photoFormats;
742 int32_t size = cJSON_GetArraySize(formatObj);
743 for (int32_t i = 0; i < size; i++) {
744 cJSON *item = cJSON_GetArrayItem(formatObj, i);
745 if (item != nullptr && cJSON_IsNumber(item)) {
746 photoFormats.push_back(item->valueint);
747 }
748 }
749 dcSupportedFormatMap_[DCSceneType::PHOTO] = photoFormats;
750 ExtractCameraAttr(rootValue, photoFormats, "Photo");
751 return SUCCESS;
752 }
753
ParsePreviewFormats(cJSON * rootValue)754 DCamRetCode DStreamOperator::ParsePreviewFormats(cJSON* rootValue)
755 {
756 cJSON *previewObj = cJSON_GetObjectItemCaseSensitive(rootValue, "Preview");
757 if (previewObj == nullptr || !cJSON_IsObject(previewObj)) {
758 DHLOGE("Preview error.");
759 return DCamRetCode::INVALID_ARGUMENT;
760 }
761 cJSON *formatObj = cJSON_GetObjectItemCaseSensitive(previewObj, "OutputFormat");
762 if (formatObj == nullptr || !cJSON_IsArray(formatObj) || cJSON_GetArraySize(formatObj) == 0 ||
763 static_cast<uint32_t>(cJSON_GetArraySize(formatObj)) > JSON_ARRAY_MAX_SIZE) {
764 DHLOGE("Preview output format error.");
765 return DCamRetCode::INVALID_ARGUMENT;
766 }
767
768 std::vector<int> previewFormats;
769 int32_t size = cJSON_GetArraySize(formatObj);
770 for (int32_t i = 0; i < size; i++) {
771 cJSON* item = cJSON_GetArrayItem(formatObj, i);
772 if (item != nullptr && cJSON_IsNumber(item)) {
773 previewFormats.push_back(item->valueint);
774 }
775 }
776 dcSupportedFormatMap_[DCSceneType::PREVIEW] = previewFormats;
777 ExtractCameraAttr(rootValue, previewFormats, "Preview");
778 return SUCCESS;
779 }
780
ParseVideoFormats(cJSON * rootValue)781 DCamRetCode DStreamOperator::ParseVideoFormats(cJSON* rootValue)
782 {
783 cJSON *videoObj = cJSON_GetObjectItemCaseSensitive(rootValue, "Video");
784 if (videoObj == nullptr || !cJSON_IsObject(videoObj)) {
785 DHLOGE("Video error.");
786 return DCamRetCode::INVALID_ARGUMENT;
787 }
788 cJSON *formatObj = cJSON_GetObjectItemCaseSensitive(videoObj, "OutputFormat");
789 if (formatObj == nullptr || !cJSON_IsArray(formatObj) || cJSON_GetArraySize(formatObj) == 0 ||
790 static_cast<uint32_t>(cJSON_GetArraySize(formatObj)) > JSON_ARRAY_MAX_SIZE) {
791 DHLOGE("Video output format error.");
792 return DCamRetCode::INVALID_ARGUMENT;
793 }
794 std::vector<int> videoFormats;
795 int32_t size = cJSON_GetArraySize(formatObj);
796 for (int32_t i = 0; i < size; i++) {
797 cJSON* item = cJSON_GetArrayItem(formatObj, i);
798 if (item != nullptr && cJSON_IsNumber(item)) {
799 videoFormats.push_back(item->valueint);
800 }
801 }
802 dcSupportedFormatMap_[DCSceneType::VIDEO] = videoFormats;
803 ExtractCameraAttr(rootValue, videoFormats, "Video");
804 return SUCCESS;
805 }
806
AcquireBuffer(int streamId,DCameraBuffer & buffer)807 DCamRetCode DStreamOperator::AcquireBuffer(int streamId, DCameraBuffer &buffer)
808 {
809 if (!IsCapturing()) {
810 DHLOGE("Not in capturing state, can not acquire buffer.");
811 return DCamRetCode::CAMERA_OFFLINE;
812 }
813
814 auto stream = FindHalStreamById(streamId);
815 if (stream == nullptr) {
816 DHLOGE("streamId %{public}d is invalid, can not acquire buffer.", streamId);
817 return DCamRetCode::INVALID_ARGUMENT;
818 }
819
820 DCamRetCode ret = stream->GetDCameraBuffer(buffer);
821 if (ret == DCamRetCode::EXCEED_MAX_NUMBER) {
822 DHLOGE("Buffer list is full, cannot get new idle buffer.");
823 } else if (ret == DCamRetCode::INVALID_ARGUMENT) {
824 DHLOGE("Get distributed camera buffer failed, invalid buffer parameter.");
825 }
826 return ret;
827 }
828
ShutterBuffer(int streamId,const DCameraBuffer & buffer)829 DCamRetCode DStreamOperator::ShutterBuffer(int streamId, const DCameraBuffer &buffer)
830 {
831 DHLOGD("DStreamOperator::ShutterBuffer begin shutter buffer for streamId = %{public}d", streamId);
832
833 int32_t captureId = FindCaptureIdByStreamId(streamId);
834 if (captureId == -1) {
835 DHLOGE("ShutterBuffer failed, invalid streamId = %{public}d", streamId);
836 return DCamRetCode::INVALID_ARGUMENT;
837 }
838
839 auto iter = notifyCaptureStartedMap_.find(streamId);
840 if (iter != notifyCaptureStartedMap_.end()) {
841 if (!iter->second && dcStreamOperatorCallback_ != nullptr) {
842 vector<int> tmpStreamIds;
843 tmpStreamIds.push_back(streamId);
844 dcStreamOperatorCallback_->OnCaptureStarted(captureId, tmpStreamIds);
845 iter->second = true;
846 }
847 }
848
849 auto stream = FindHalStreamById(streamId);
850 if (stream != nullptr) {
851 DCamRetCode ret = stream->ReturnDCameraBuffer(buffer);
852 if (ret != DCamRetCode::SUCCESS) {
853 DHLOGE("Flush distributed camera buffer failed.");
854 return ret;
855 }
856 AddStreamCaptureBufferNum(std::make_pair(captureId, streamId));
857
858 SnapShotStreamOnCaptureEnded(captureId, streamId);
859 }
860
861 uint64_t resultTimestamp = GetCurrentLocalTimeStamp();
862 if (dMetadataProcessor_ != nullptr) {
863 dMetadataProcessor_->UpdateResultMetadata(resultTimestamp);
864 }
865
866 bool enableShutter = FindEnableShutter(streamId);
867 if (!enableShutter) {
868 if (dcStreamOperatorCallback_ == nullptr) {
869 DHLOGE("DStreamOperator::ShutterBuffer failed, need shutter frame, but stream operator callback is null.");
870 return DCamRetCode::FAILED;
871 }
872 std::vector<int32_t> streamIds;
873 streamIds.push_back(streamId);
874 dcStreamOperatorCallback_->OnFrameShutter(captureId, streamIds, resultTimestamp);
875 }
876 return DCamRetCode::SUCCESS;
877 }
878
SetCallBack(OHOS::sptr<IStreamOperatorCallback> const & callback)879 DCamRetCode DStreamOperator::SetCallBack(OHOS::sptr<IStreamOperatorCallback> const &callback)
880 {
881 dcStreamOperatorCallback_ = callback;
882 return SUCCESS;
883 }
884
SetDeviceCallback(std::function<void (ErrorType,int)> & errorCbk,std::function<void (uint64_t,std::shared_ptr<OHOS::Camera::CameraMetadata>)> & resultCbk)885 DCamRetCode DStreamOperator::SetDeviceCallback(
886 std::function<void(ErrorType, int)> &errorCbk,
887 std::function<void(uint64_t, std::shared_ptr<OHOS::Camera::CameraMetadata>)> &resultCbk)
888 {
889 errorCallback_ = errorCbk;
890 if (dMetadataProcessor_ != nullptr) {
891 dMetadataProcessor_->SetResultCallback(resultCbk);
892 }
893 return SUCCESS;
894 }
895
SnapShotStreamOnCaptureEnded(int32_t captureId,int streamId)896 void DStreamOperator::SnapShotStreamOnCaptureEnded(int32_t captureId, int streamId)
897 {
898 auto dcStreamInfo = FindDCStreamById(streamId);
899 if (dcStreamInfo == nullptr) {
900 return;
901 }
902 if (dcStreamInfo->type_ != DCStreamType::SNAPSHOT_FRAME) {
903 return;
904 }
905 if (dcStreamOperatorCallback_ == nullptr) {
906 return;
907 }
908 std::vector<CaptureEndedInfo> info;
909 CaptureEndedInfo tmp;
910 tmp.frameCount_ = FindStreamCaptureBufferNum(std::make_pair(captureId, streamId));
911 tmp.streamId_ = streamId;
912 info.push_back(tmp);
913 dcStreamOperatorCallback_->OnCaptureEnded(captureId, info);
914 DHLOGD("snapshot stream successfully reported captureId = %{public}d streamId = %{public}d.", captureId, streamId);
915 }
916
Release()917 void DStreamOperator::Release()
918 {
919 DHLOGI("DStreamOperator::Release, begin release stream operator.");
920
921 std::vector<int> streamIds = GetStreamIds();
922 SetCapturing(false);
923 ReleaseStreams(streamIds);
924 if (latestStreamSetting_) {
925 latestStreamSetting_ = nullptr;
926 }
927 {
928 std::lock_guard<std::mutex> lockStream(halStreamLock_);
929 halStreamMap_.clear();
930 }
931 std::lock_guard<std::mutex> lock(streamAttrLock_);
932 dcStreamInfoMap_.clear();
933 halCaptureInfoMap_.clear();
934 enableShutterCbkMap_.clear();
935 acceptedBufferNum_.clear();
936 cachedDCaptureInfoList_.clear();
937 notifyCaptureStartedMap_.clear();
938 dcStreamOperatorCallback_ = nullptr;
939 }
940
GetStreamIds()941 std::vector<int> DStreamOperator::GetStreamIds()
942 {
943 DHLOGI("DStreamOperator::GetStreamIds, begin get stream id.");
944 std::lock_guard<std::mutex> autoLock(halStreamLock_);
945 std::vector<int> streamIds;
946 std::string idString = "";
947 for (auto iter : halStreamMap_) {
948 streamIds.push_back(iter.first);
949 idString += (std::to_string(iter.first) + ", ");
950 }
951 DHLOGI("DStreamOperator::GetStreamIds, ids=[%{public}s]", idString.c_str());
952 return streamIds;
953 }
954
IsCapturing()955 bool DStreamOperator::IsCapturing()
956 {
957 std::unique_lock<mutex> lock(isCapturingLock_);
958 return isCapturing_;
959 }
960
SetCapturing(bool isCapturing)961 void DStreamOperator::SetCapturing(bool isCapturing)
962 {
963 std::unique_lock<mutex> lock(isCapturingLock_);
964 isCapturing_ = isCapturing;
965 }
966
ConvertStreamInfo(const StreamInfo & srcInfo,std::shared_ptr<DCStreamInfo> & dstInfo)967 void DStreamOperator::ConvertStreamInfo(const StreamInfo &srcInfo, std::shared_ptr<DCStreamInfo> &dstInfo)
968 {
969 dstInfo->streamId_ = srcInfo.streamId_;
970 dstInfo->width_ = srcInfo.width_;
971 dstInfo->stride_ = srcInfo.width_;
972 dstInfo->height_ = srcInfo.height_;
973 dstInfo->dataspace_ = srcInfo.dataspace_;
974 dstInfo->encodeType_ = (DCEncodeType)srcInfo.encodeType_;
975
976 if ((srcInfo.intent_ == STILL_CAPTURE) || (srcInfo.intent_ == POST_VIEW)) {
977 dstInfo->type_ = DCStreamType::SNAPSHOT_FRAME;
978 if (srcInfo.format_ == PIXEL_FMT_RGBA_8888) {
979 dstInfo->format_ = OHOS_CAMERA_FORMAT_RGBA_8888;
980 } else if (srcInfo.format_ == PIXEL_FMT_YCRCB_420_SP) {
981 dstInfo->format_ = OHOS_CAMERA_FORMAT_JPEG;
982 } else if (dstInfo->encodeType_ == DCEncodeType::ENCODE_TYPE_NULL) {
983 dstInfo->format_ = OHOS_CAMERA_FORMAT_YCRCB_420_SP;
984 }
985 } else {
986 // Distributed Camera Do Not Support Encoding at HAL
987 dstInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_NULL;
988 dstInfo->type_ = DCStreamType::CONTINUOUS_FRAME;
989 dstInfo->format_ =
990 static_cast<int>(DBufferManager::PixelFormatToDCameraFormat(static_cast<PixelFormat>(srcInfo.format_)));
991 }
992 }
993
NegotiateSuitableCaptureInfo(const CaptureInfo & srcCaptureInfo,bool isStreaming)994 DCamRetCode DStreamOperator::NegotiateSuitableCaptureInfo(const CaptureInfo& srcCaptureInfo, bool isStreaming)
995 {
996 for (auto streamId : srcCaptureInfo.streamIds_) {
997 DHLOGI("DStreamOperator::NegotiateSuitableCaptureInfo, streamId=%{public}d, isStreaming=%{public}d",
998 streamId, isStreaming);
999 }
1000
1001 std::shared_ptr<DCCaptureInfo> inputCaptureInfo = nullptr;
1002 DCamRetCode ret = GetInputCaptureInfo(srcCaptureInfo, isStreaming, inputCaptureInfo);
1003 if (ret != DCamRetCode::SUCCESS) {
1004 DHLOGE("Negotiate input capture info failed.");
1005 return ret;
1006 }
1007
1008 std::shared_ptr<DCCaptureInfo> appendCaptureInfo = nullptr;
1009 AppendCaptureInfo(appendCaptureInfo, isStreaming, inputCaptureInfo, srcCaptureInfo);
1010 cachedDCaptureInfoList_.clear();
1011 cachedDCaptureInfoList_.push_back(inputCaptureInfo);
1012 if (appendCaptureInfo != nullptr) {
1013 cachedDCaptureInfoList_.push_back(appendCaptureInfo);
1014 }
1015
1016 for (auto info : cachedDCaptureInfoList_) {
1017 std::string idString = "";
1018 for (auto id : info->streamIds_) {
1019 idString += (std::to_string(id) + ", ");
1020 }
1021 DHLOGI("cachedDCaptureInfo: ids=%{public}s width=%{public}d, height=%{public}d, format=%{public}d, "
1022 "dataspace=%{public}d, isCapture=%{public}d, encodeType=%{public}d, streamType=%{public}d",
1023 idString.c_str(), info->width_, info->height_, info->format_,
1024 info->dataspace_, info->isCapture_, info->encodeType_, info->type_);
1025 }
1026 return SUCCESS;
1027 }
1028
AppendCaptureInfo(std::shared_ptr<DCCaptureInfo> & appendCaptureInfo,bool isStreaming,std::shared_ptr<DCCaptureInfo> & inputCaptureInfo,const CaptureInfo & srcCaptureInfo)1029 void DStreamOperator::AppendCaptureInfo(std::shared_ptr<DCCaptureInfo> &appendCaptureInfo, bool isStreaming,
1030 std::shared_ptr<DCCaptureInfo> &inputCaptureInfo, const CaptureInfo& srcCaptureInfo)
1031 {
1032 if (cachedDCaptureInfoList_.empty()) {
1033 std::vector<std::shared_ptr<DCStreamInfo>> appendStreamInfo;
1034 ExtractNotCaptureStream(isStreaming, appendStreamInfo);
1035 if (!appendStreamInfo.empty()) {
1036 appendCaptureInfo = BuildSuitableCaptureInfo(srcCaptureInfo, appendStreamInfo);
1037 appendCaptureInfo->type_ = isStreaming ? DCStreamType::SNAPSHOT_FRAME : DCStreamType::CONTINUOUS_FRAME;
1038 appendCaptureInfo->isCapture_ = false;
1039 }
1040 } else {
1041 for (auto cacheCapture : cachedDCaptureInfoList_) {
1042 if ((isStreaming && (cacheCapture->type_ == DCStreamType::SNAPSHOT_FRAME)) ||
1043 (!isStreaming && (cacheCapture->type_ == DCStreamType::CONTINUOUS_FRAME))) {
1044 cacheCapture->isCapture_ = false;
1045 appendCaptureInfo = cacheCapture;
1046 break;
1047 }
1048 }
1049 if (inputCaptureInfo->type_ == DCStreamType::SNAPSHOT_FRAME) {
1050 ChooseSuitableStreamId(appendCaptureInfo);
1051 }
1052 inputCaptureInfo->isCapture_ = isStreaming ? false : true;
1053 }
1054 }
1055
GetInputCaptureInfo(const CaptureInfo & srcCaptureInfo,bool isStreaming,std::shared_ptr<DCCaptureInfo> & inputCaptureInfo)1056 DCamRetCode DStreamOperator::GetInputCaptureInfo(const CaptureInfo& srcCaptureInfo, bool isStreaming,
1057 std::shared_ptr<DCCaptureInfo>& inputCaptureInfo)
1058 {
1059 std::vector<std::shared_ptr<DCStreamInfo>> srcStreamInfo;
1060 for (auto &id : srcCaptureInfo.streamIds_) {
1061 auto dcStreamInfo = FindDCStreamById(id);
1062 if (dcStreamInfo != nullptr) {
1063 srcStreamInfo.push_back(dcStreamInfo);
1064 }
1065 }
1066
1067 if (srcStreamInfo.empty()) {
1068 DHLOGE("Input source stream info vector is empty.");
1069 return DCamRetCode::INVALID_ARGUMENT;
1070 }
1071
1072 inputCaptureInfo = BuildSuitableCaptureInfo(srcCaptureInfo, srcStreamInfo);
1073 inputCaptureInfo->type_ = isStreaming ? DCStreamType::CONTINUOUS_FRAME : DCStreamType::SNAPSHOT_FRAME;
1074 inputCaptureInfo->isCapture_ = true;
1075 return DCamRetCode::SUCCESS;
1076 }
1077
BuildSuitableCaptureInfo(const CaptureInfo & srcCaptureInfo,std::vector<std::shared_ptr<DCStreamInfo>> & srcStreamInfo)1078 std::shared_ptr<DCCaptureInfo> DStreamOperator::BuildSuitableCaptureInfo(const CaptureInfo& srcCaptureInfo,
1079 std::vector<std::shared_ptr<DCStreamInfo>> &srcStreamInfo)
1080 {
1081 std::shared_ptr<DCCaptureInfo> captureInfo = std::make_shared<DCCaptureInfo>();
1082
1083 ChooseSuitableFormat(srcStreamInfo, captureInfo);
1084 ChooseSuitableResolution(srcStreamInfo, captureInfo);
1085 ChooseSuitableDataSpace(srcStreamInfo, captureInfo);
1086 ChooseSuitableEncodeType(srcStreamInfo, captureInfo);
1087
1088 DCameraSettings dcSetting;
1089 dcSetting.type_ = DCSettingsType::UPDATE_METADATA;
1090 std::shared_ptr<OHOS::Camera::CameraMetadata> captureSetting = nullptr;
1091 OHOS::Camera::MetadataUtils::ConvertVecToMetadata(srcCaptureInfo.captureSetting_, captureSetting);
1092 std::string settingStr = OHOS::Camera::MetadataUtils::EncodeToString(captureSetting);
1093 dcSetting.value_ = Base64Encode(reinterpret_cast<const unsigned char *>(settingStr.c_str()), settingStr.length());
1094
1095 captureInfo->captureSettings_.push_back(dcSetting);
1096
1097 return captureInfo;
1098 }
1099
ChooseSuitableFormat(std::vector<std::shared_ptr<DCStreamInfo>> & streamInfo,std::shared_ptr<DCCaptureInfo> & captureInfo)1100 void DStreamOperator::ChooseSuitableFormat(std::vector<std::shared_ptr<DCStreamInfo>> &streamInfo,
1101 std::shared_ptr<DCCaptureInfo> &captureInfo)
1102 {
1103 for (auto stream : streamInfo) {
1104 if ((streamInfo.at(0)->type_ == DCStreamType::CONTINUOUS_FRAME &&
1105 dcSupportedVideoResolutionMap_.count(stream->format_) > 0) ||
1106 (streamInfo.at(0)->type_ == DCStreamType::SNAPSHOT_FRAME &&
1107 dcSupportedPhotoResolutionMap_.count(stream->format_) > 0)) {
1108 captureInfo->format_ = stream->format_;
1109 return;
1110 }
1111 }
1112 if ((streamInfo.at(0))->type_ == DCStreamType::CONTINUOUS_FRAME) {
1113 if (dcSupportedFormatMap_.count(DCSceneType::PREVIEW) > 0) {
1114 captureInfo->format_ = dcSupportedFormatMap_[DCSceneType::PREVIEW].at(0);
1115 } else if (dcSupportedFormatMap_.count(DCSceneType::VIDEO) > 0) {
1116 captureInfo->format_ = dcSupportedFormatMap_[DCSceneType::VIDEO].at(0);
1117 } else {
1118 captureInfo->format_ = OHOS_CAMERA_FORMAT_YCRCB_420_SP;
1119 }
1120 } else {
1121 if (dcSupportedFormatMap_.count(DCSceneType::PHOTO) > 0) {
1122 captureInfo->format_ = dcSupportedFormatMap_[DCSceneType::PHOTO].at(0);
1123 } else {
1124 if ((streamInfo.at(0))->encodeType_ == DCEncodeType::ENCODE_TYPE_JPEG) {
1125 captureInfo->format_ = OHOS_CAMERA_FORMAT_JPEG;
1126 } else {
1127 captureInfo->format_ = OHOS_CAMERA_FORMAT_YCRCB_420_SP;
1128 }
1129 }
1130 }
1131 }
1132
ChooseSuitableResolution(std::vector<std::shared_ptr<DCStreamInfo>> & streamInfo,std::shared_ptr<DCCaptureInfo> & captureInfo)1133 void DStreamOperator::ChooseSuitableResolution(std::vector<std::shared_ptr<DCStreamInfo>> &streamInfo,
1134 std::shared_ptr<DCCaptureInfo> &captureInfo)
1135 {
1136 if (captureInfo == nullptr) {
1137 DHLOGE("DStreamOperator::ChooseSuitableResolution, captureInfo is null.");
1138 return;
1139 }
1140
1141 std::vector<DCResolution> supportedResolutionList;
1142 if ((streamInfo.at(0))->type_ == DCStreamType::CONTINUOUS_FRAME) {
1143 supportedResolutionList = dcSupportedVideoResolutionMap_[captureInfo->format_];
1144 } else {
1145 supportedResolutionList = dcSupportedPhotoResolutionMap_[captureInfo->format_];
1146 }
1147
1148 for (auto stream : streamInfo) {
1149 captureInfo->streamIds_.push_back(stream->streamId_);
1150 }
1151
1152 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1153 DCResolution tempResolution = { 0, 0 };
1154 for (auto iter : dcStreamInfoMap_) {
1155 if (iter.second->type_ != (streamInfo.at(0))->type_) {
1156 continue;
1157 }
1158 for (auto resolution : supportedResolutionList) {
1159 if ((resolution.width_ == iter.second->width_) &&
1160 (resolution.height_ == iter.second->height_) &&
1161 (tempResolution < resolution)) {
1162 tempResolution = resolution;
1163 break;
1164 }
1165 }
1166 }
1167
1168 if ((tempResolution.width_ == 0) || (tempResolution.height_ == 0)) {
1169 DHLOGI("DStreamOperator::ChooseSuitableResolution, captureInfo. width = %{public}d, height = %{public}d. ",
1170 captureInfo->width_, captureInfo->height_);
1171 if (supportedResolutionList.size() > 0) {
1172 captureInfo->width_ = supportedResolutionList[supportedResolutionList.size() - 1].width_;
1173 captureInfo->height_ = supportedResolutionList[supportedResolutionList.size() - 1].height_;
1174 }
1175 } else {
1176 captureInfo->width_ = tempResolution.width_;
1177 captureInfo->height_ = tempResolution.height_;
1178 }
1179 }
1180
ChooseSuitableDataSpace(std::vector<std::shared_ptr<DCStreamInfo>> & streamInfo,std::shared_ptr<DCCaptureInfo> & captureInfo)1181 void DStreamOperator::ChooseSuitableDataSpace(std::vector<std::shared_ptr<DCStreamInfo>> &streamInfo,
1182 std::shared_ptr<DCCaptureInfo> &captureInfo)
1183 {
1184 captureInfo->dataspace_ = (streamInfo.at(0))->dataspace_;
1185 }
1186
ChooseSuitableEncodeType(std::vector<std::shared_ptr<DCStreamInfo>> & streamInfo,std::shared_ptr<DCCaptureInfo> & captureInfo)1187 void DStreamOperator::ChooseSuitableEncodeType(std::vector<std::shared_ptr<DCStreamInfo>> &streamInfo,
1188 std::shared_ptr<DCCaptureInfo> &captureInfo)
1189 {
1190 if ((streamInfo.at(0))->type_ == DCStreamType::CONTINUOUS_FRAME) {
1191 if (count(dcSupportedCodecType_.begin(), dcSupportedCodecType_.end(), DCEncodeType::ENCODE_TYPE_H265) &&
1192 count(sourceEncodeTypes_.begin(), sourceEncodeTypes_.end(), DCEncodeType::ENCODE_TYPE_H265)) {
1193 captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_H265;
1194 } else if (count(dcSupportedCodecType_.begin(), dcSupportedCodecType_.end(), DCEncodeType::ENCODE_TYPE_H264) &&
1195 count(sourceEncodeTypes_.begin(), sourceEncodeTypes_.end(), DCEncodeType::ENCODE_TYPE_H264)) {
1196 captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_H264;
1197 } else {
1198 captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_NULL;
1199 }
1200 } else {
1201 if ((streamInfo.at(0))->encodeType_ == DCEncodeType::ENCODE_TYPE_JPEG) {
1202 captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_JPEG;
1203 } else {
1204 captureInfo->encodeType_ = DCEncodeType::ENCODE_TYPE_NULL;
1205 }
1206 }
1207 }
1208
ChooseSuitableStreamId(std::shared_ptr<DCCaptureInfo> & captureInfo)1209 void DStreamOperator::ChooseSuitableStreamId(std::shared_ptr<DCCaptureInfo> &captureInfo)
1210 {
1211 if (captureInfo == nullptr) {
1212 DHLOGE("DStreamOperator::ChooseSuitableStreamId captureInfo is null");
1213 return;
1214 }
1215
1216 captureInfo->streamIds_.clear();
1217 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1218 for (auto iter : halCaptureInfoMap_) {
1219 for (auto id : iter.second->streamIds_) {
1220 auto dcStreamInfo = dcStreamInfoMap_.find(id);
1221 if (dcStreamInfo == dcStreamInfoMap_.end()) {
1222 continue;
1223 }
1224
1225 if (dcStreamInfo->second->type_ == DCStreamType::CONTINUOUS_FRAME) {
1226 DHLOGI("DStreamOperator::ChooseSuitableStreamId, streamId: %{public}d", id);
1227 captureInfo->streamIds_.push_back(id);
1228 }
1229 }
1230 }
1231 }
1232
ConvertDCEncodeType(std::string & srcEncodeType)1233 DCEncodeType DStreamOperator::ConvertDCEncodeType(std::string &srcEncodeType)
1234 {
1235 DHLOGI("DStreamOperator::ConvertDCEncodeType %{public}s", srcEncodeType.c_str());
1236 if (srcEncodeType == ENCODE_TYPE_STR_H264) {
1237 return DCEncodeType::ENCODE_TYPE_H264;
1238 } else if (srcEncodeType == ENCODE_TYPE_STR_H265) {
1239 return DCEncodeType::ENCODE_TYPE_H265;
1240 } else if (srcEncodeType == ENCODE_TYPE_STR_JPEG) {
1241 return DCEncodeType::ENCODE_TYPE_JPEG;
1242 } else if (srcEncodeType == ENCODE_TYPE_STR_MPEG4_ES) {
1243 return DCEncodeType::ENCODE_TYPE_MPEG4_ES;
1244 } else {
1245 return DCEncodeType::ENCODE_TYPE_NULL;
1246 }
1247 }
1248
FindHalStreamById(int32_t streamId)1249 std::shared_ptr<DCameraStream> DStreamOperator::FindHalStreamById(int32_t streamId)
1250 {
1251 std::lock_guard<std::mutex> autoLock(halStreamLock_);
1252 auto iter = halStreamMap_.find(streamId);
1253 if (iter == halStreamMap_.end()) {
1254 return nullptr;
1255 }
1256 return iter->second;
1257 }
1258
InsertHalStream(int32_t streamId,std::shared_ptr<DCameraStream> & dcStream)1259 void DStreamOperator::InsertHalStream(int32_t streamId, std::shared_ptr<DCameraStream>& dcStream)
1260 {
1261 std::lock_guard<std::mutex> autoLock(halStreamLock_);
1262 halStreamMap_.emplace(streamId, dcStream);
1263 }
1264
EraseHalStream(int32_t streamId)1265 void DStreamOperator::EraseHalStream(int32_t streamId)
1266 {
1267 std::lock_guard<std::mutex> autoLock(halStreamLock_);
1268 halStreamMap_.erase(streamId);
1269 }
1270
FindCaptureInfoById(int32_t captureId)1271 std::shared_ptr<CaptureInfo> DStreamOperator::FindCaptureInfoById(int32_t captureId)
1272 {
1273 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1274 auto iter = halCaptureInfoMap_.find(captureId);
1275 if (iter == halCaptureInfoMap_.end()) {
1276 return nullptr;
1277 }
1278 return iter->second;
1279 }
1280
InsertCaptureInfo(int32_t captureId,std::shared_ptr<CaptureInfo> & captureInfo)1281 void DStreamOperator::InsertCaptureInfo(int32_t captureId, std::shared_ptr<CaptureInfo>& captureInfo)
1282 {
1283 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1284 halCaptureInfoMap_.emplace(captureId, captureInfo);
1285 }
1286
FindCaptureIdByStreamId(int32_t streamId)1287 int32_t DStreamOperator::FindCaptureIdByStreamId(int32_t streamId)
1288 {
1289 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1290 int32_t captureId = -1;
1291 for (auto iter = halCaptureInfoMap_.begin(); iter != halCaptureInfoMap_.end(); iter++) {
1292 std::shared_ptr<CaptureInfo> captureInfo = iter->second;
1293 std::vector<int> streamIds = captureInfo->streamIds_;
1294 if (std::find(streamIds.begin(), streamIds.end(), streamId) != streamIds.end()) {
1295 captureId = iter->first;
1296 break;
1297 }
1298 }
1299 return captureId;
1300 }
1301
EraseCaptureInfo(int32_t captureId)1302 void DStreamOperator::EraseCaptureInfo(int32_t captureId)
1303 {
1304 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1305 halCaptureInfoMap_.erase(captureId);
1306 }
1307
FindDCStreamById(int32_t streamId)1308 std::shared_ptr<DCStreamInfo> DStreamOperator::FindDCStreamById(int32_t streamId)
1309 {
1310 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1311 auto iter = dcStreamInfoMap_.find(streamId);
1312 if (iter == dcStreamInfoMap_.end()) {
1313 return nullptr;
1314 }
1315 return iter->second;
1316 }
1317
InsertDCStream(int32_t streamId,std::shared_ptr<DCStreamInfo> & dcStreamInfo)1318 void DStreamOperator::InsertDCStream(int32_t streamId, std::shared_ptr<DCStreamInfo>& dcStreamInfo)
1319 {
1320 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1321 dcStreamInfoMap_.emplace(streamId, dcStreamInfo);
1322 }
1323
EraseDCStream(int32_t streamId)1324 void DStreamOperator::EraseDCStream(int32_t streamId)
1325 {
1326 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1327 dcStreamInfoMap_.erase(streamId);
1328 }
1329
ExtractNotCaptureStream(bool isStreaming,std::vector<std::shared_ptr<DCStreamInfo>> & appendStreamInfo)1330 void DStreamOperator::ExtractNotCaptureStream(bool isStreaming,
1331 std::vector<std::shared_ptr<DCStreamInfo>>& appendStreamInfo)
1332 {
1333 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1334 for (auto iter = dcStreamInfoMap_.begin(); iter != dcStreamInfoMap_.end(); iter++) {
1335 if ((isStreaming && (iter->second->type_ == DCStreamType::SNAPSHOT_FRAME)) ||
1336 (!isStreaming && (iter->second->type_ == DCStreamType::CONTINUOUS_FRAME))) {
1337 appendStreamInfo.push_back(iter->second);
1338 }
1339 }
1340 }
1341
FindEnableShutter(int32_t streamId)1342 bool DStreamOperator::FindEnableShutter(int32_t streamId)
1343 {
1344 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1345 auto iter = enableShutterCbkMap_.find(streamId);
1346 if (iter == enableShutterCbkMap_.end()) {
1347 return false;
1348 }
1349 return iter->second;
1350 }
1351
InsertEnableShutter(int32_t streamId,bool enableShutterCallback)1352 void DStreamOperator::InsertEnableShutter(int32_t streamId, bool enableShutterCallback)
1353 {
1354 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1355 enableShutterCbkMap_.emplace(streamId, enableShutterCallback);
1356 }
1357
EraseEnableShutter(int32_t streamId)1358 void DStreamOperator::EraseEnableShutter(int32_t streamId)
1359 {
1360 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1361 enableShutterCbkMap_.erase(streamId);
1362 }
1363
FindStreamCaptureBufferNum(const pair<int,int> & streamPair)1364 int32_t DStreamOperator::FindStreamCaptureBufferNum(const pair<int, int>& streamPair)
1365 {
1366 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1367 auto iter = acceptedBufferNum_.find(streamPair);
1368 if (iter == acceptedBufferNum_.end()) {
1369 return 0;
1370 }
1371 return iter->second;
1372 }
1373
AddStreamCaptureBufferNum(const pair<int,int> & streamPair)1374 void DStreamOperator::AddStreamCaptureBufferNum(const pair<int, int>& streamPair)
1375 {
1376 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1377 acceptedBufferNum_[streamPair]++;
1378 }
1379
EraseStreamCaptureBufferNum(const pair<int,int> & streamPair)1380 void DStreamOperator::EraseStreamCaptureBufferNum(const pair<int, int>& streamPair)
1381 {
1382 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1383 acceptedBufferNum_.erase(streamPair);
1384 }
1385
InsertNotifyCaptureMap(int32_t streamId)1386 void DStreamOperator::InsertNotifyCaptureMap(int32_t streamId)
1387 {
1388 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1389 notifyCaptureStartedMap_.emplace(streamId, false);
1390 }
1391
EraseNotifyCaptureMap(int32_t streamId)1392 void DStreamOperator::EraseNotifyCaptureMap(int32_t streamId)
1393 {
1394 std::lock_guard<std::mutex> autoLock(streamAttrLock_);
1395 notifyCaptureStartedMap_.erase(streamId);
1396 }
1397 } // namespace DistributedHardware
1398 } // namespace OHOS
1399