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