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