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