1 /*
2 * Copyright (c) 2025-2025 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 "session/mech_session.h"
17
18 #include "camera_error_code.h"
19 #include "camera_log.h"
20 #include "camera_util.h"
21
22 namespace OHOS {
23 namespace CameraStandard {
24 constexpr int32_t FOCUS_TRACKING_REGION_DATA_CNT = 4;
25 constexpr int32_t LOG_INTERVAL_FREQUENCY = 10;
26
OnFocusTrackingInfo(int32_t streamId,bool isNeedMirror,bool isNeedFlip,const std::shared_ptr<OHOS::Camera::CameraMetadata> & result)27 int32_t MechSessionCallbackImpl::OnFocusTrackingInfo(int32_t streamId, bool isNeedMirror, bool isNeedFlip,
28 const std::shared_ptr<OHOS::Camera::CameraMetadata>& result)
29 {
30 MEDIA_DEBUG_LOG("%{public}s is called!", __FUNCTION__);
31 int32_t ret = CAMERA_OK;
32 CHECK_RETURN_RET(result == nullptr, ret);
33 auto mechSession = mechSession_.promote();
34 CHECK_RETURN_RET(!mechSession, ret);
35 auto appCallback = mechSession->GetCallback();
36 CHECK_RETURN_RET(!appCallback, ret);
37
38 FocusTrackingMetaInfo info;
39 FocusTrackingMode mode = FOCUS_TRACKING_MODE_AUTO;
40 Rect region = {0.0, 0.0, 0.0, 0.0};
41 std::vector<sptr<MetadataObject>> metaObjects;
42
43 MetadataCommonUtils::ProcessFocusTrackingModeInfo(result, mode);
44 info.SetTrackingMode(mode);
45
46 ProcessRectInfo(result, region);
47 info.SetTrackingRegion(region);
48
49 MetadataCommonUtils::ProcessMetaObjects(streamId, result, metaObjects, isNeedMirror, isNeedFlip,
50 RectBoxType::RECT_MECH);
51 info.SetDetectedObjects(metaObjects);
52
53 camera_metadata_item_t item;
54 ret = Camera::FindCameraMetadataItem(result->get(), OHOS_CONTROL_FOCUS_TRACKING_OBJECT_ID, &item);
55 if (ret == CAM_META_SUCCESS && item.count > 0) {
56 info.SetTrackingObjectId(item.data.i32[0]);
57 }
58 PrintFocusTrackingInfo(info);
59 appCallback->OnFocusTrackingInfo(info);
60 return ret;
61 }
62
OnCaptureSessionConfiged(const CaptureSessionInfo & captureSessionInfo)63 int32_t MechSessionCallbackImpl::OnCaptureSessionConfiged(const CaptureSessionInfo& captureSessionInfo)
64 {
65 MEDIA_INFO_LOG("%{public}s is called!", __FUNCTION__);
66 int32_t ret = CAMERA_OK;
67 auto mechSession = mechSession_.promote();
68 CHECK_RETURN_RET(!mechSession, ret);
69 auto appCallback = mechSession->GetCallback();
70 CHECK_RETURN_RET(!appCallback, ret);
71 PrintCaptureSessionInfo(captureSessionInfo);
72 appCallback->OnCaptureSessionConfiged(captureSessionInfo);
73 return CAMERA_OK;
74 }
75
OnZoomInfoChange(int32_t sessionid,const ZoomInfo & zoomInfo)76 int32_t MechSessionCallbackImpl::OnZoomInfoChange(int32_t sessionid, const ZoomInfo& zoomInfo)
77 {
78 MEDIA_INFO_LOG("%{public}s is called!", __FUNCTION__);
79 int32_t ret = CAMERA_OK;
80 auto mechSession = mechSession_.promote();
81 CHECK_RETURN_RET(!mechSession, ret);
82 auto appCallback = mechSession->GetCallback();
83 CHECK_RETURN_RET(!appCallback, ret);
84 MEDIA_INFO_LOG("%{public}s sessionid:%{public}d, zoomValue:%{public}f,"
85 "equivalentFocus:%{public}d, focusStatus:%{public}d,"
86 "focusMode:%{public}d, videoStabilizationMode:%{public}d",
87 __FUNCTION__, sessionid, zoomInfo.zoomValue,
88 zoomInfo.equivalentFocus, zoomInfo.focusStatus,
89 zoomInfo.focusMode, zoomInfo.videoStabilizationMode);
90 appCallback->OnZoomInfoChange(sessionid, zoomInfo);
91 return CAMERA_OK;
92 }
93
OnSessionStatusChange(int32_t sessionid,bool status)94 int32_t MechSessionCallbackImpl::OnSessionStatusChange(int32_t sessionid, bool status)
95 {
96 MEDIA_INFO_LOG("%{public}s is called!", __FUNCTION__);
97 int32_t ret = CAMERA_OK;
98 auto mechSession = mechSession_.promote();
99 CHECK_RETURN_RET(!mechSession, ret);
100 auto appCallback = mechSession->GetCallback();
101 CHECK_RETURN_RET(!appCallback, ret);
102 MEDIA_INFO_LOG("%{public}s sessionid:%{public}d, status:%{public}d",
103 __FUNCTION__, sessionid, status);
104 appCallback->OnSessionStatusChange(sessionid, status);
105 return CAMERA_OK;
106 }
107
ProcessRectInfo(const std::shared_ptr<OHOS::Camera::CameraMetadata> & metadata,Rect & rect)108 bool MechSessionCallbackImpl::ProcessRectInfo(const std::shared_ptr<OHOS::Camera::CameraMetadata>& metadata,
109 Rect& rect)
110 {
111 constexpr int32_t scale = 1000000;
112 constexpr int32_t offsetOne = 1;
113 constexpr int32_t offsetTwo = 2;
114 constexpr int32_t offsetThree = 3;
115
116 CHECK_RETURN_RET_ELOG(metadata == nullptr, false, "metadata is nullptr");
117 camera_metadata_item_t item;
118 int ret = Camera::FindCameraMetadataItem(metadata->get(), OHOS_ABILITY_FOCUS_TRACKING_REGION, &item);
119 if (ret != CAM_META_SUCCESS || item.count < FOCUS_TRACKING_REGION_DATA_CNT) {
120 MEDIA_DEBUG_LOG("%{public}s FindCameraMetadataItem failed", __FUNCTION__);
121 return false;
122 }
123 int32_t left = item.data.i32[0];
124 int32_t top = item.data.i32[offsetOne];
125 int32_t width = item.data.i32[offsetTwo];
126 int32_t height = item.data.i32[offsetThree];
127
128 double rectLeft = static_cast<double>(left);
129 double rectTop = static_cast<double>(top);
130 double rectWidth = static_cast<double>(width);
131 double rectHeight = static_cast<double>(height);
132
133 rect = { rectLeft / scale, rectTop / scale, rectWidth / scale, rectHeight / scale};
134 return true;
135 }
136
PrintFocusTrackingInfo(FocusTrackingMetaInfo & info)137 void MechSessionCallbackImpl::PrintFocusTrackingInfo(FocusTrackingMetaInfo& info)
138 {
139 logCount_ ++;
140 CHECK_RETURN(logCount_ % LOG_INTERVAL_FREQUENCY != 0);
141 auto trackingRegion = info.GetTrackingRegion();
142 MEDIA_INFO_LOG("OnFocusTrackingInfo trackingRegion: "
143 "[%{public}f, %{public}f, %{public}f, %{public}f], "
144 "trackingObjectId:%{public}d ",
145 trackingRegion.topLeftX, trackingRegion.topLeftY,
146 trackingRegion.width, trackingRegion.height,
147 info.GetTrackingObjectId());
148
149 auto detectedObjects = info.GetDetectedObjects();
150 MEDIA_INFO_LOG("OnFocusTrackingInfo detectedObjects size:%{public}d", static_cast<int32_t>(detectedObjects.size()));
151 for (size_t i = 0; i < detectedObjects.size(); i++) {
152 auto metadataObject = detectedObjects[i];
153 auto type = metadataObject->GetType();
154 auto box = metadataObject->GetBoundingBox();
155 int32_t objectId = metadataObject->GetObjectId();
156 int32_t confidence = metadataObject->GetConfidence();
157 MEDIA_INFO_LOG("OnFocusTrackingInfo detectedObject type:%{public}d, "
158 "boundingBox:[%{public}f, %{public}f, %{public}f, %{public}f], "
159 "objectId:%{public}d, confidence:%{public}d",
160 type, box.topLeftX, box.topLeftY,
161 box.width, box.height, objectId, confidence);
162 }
163 }
164
PrintCaptureSessionInfo(const CaptureSessionInfo & captureSessionInfo)165 void MechSessionCallbackImpl::PrintCaptureSessionInfo(const CaptureSessionInfo& captureSessionInfo)
166 {
167 MEDIA_INFO_LOG("OnCaptureSessionConfiged sessionId:%{public}d, "
168 "cameraId:%{public}s, position:%{public}d, sessionMode:%{public}d, "
169 "colorSpace:%{public}d, sessionStatus:%{public}d",
170 captureSessionInfo.sessionId, captureSessionInfo.cameraId.c_str(),
171 captureSessionInfo.position, captureSessionInfo.sessionMode,
172 captureSessionInfo.colorSpace, captureSessionInfo.sessionStatus);
173
174 auto outputInfos = captureSessionInfo.outputInfos;
175 MEDIA_INFO_LOG("OnCaptureSessionConfiged outputInfos size:%{public}d", static_cast<int32_t>(outputInfos.size()));
176 for (size_t i = 0; i < outputInfos.size(); i++) {
177 auto outputInfo = outputInfos[i];
178 MEDIA_INFO_LOG("OnCaptureSessionConfiged outputInfo type:%{public}d, "
179 "minfps:%{public}d, maxfps:%{public}d, width:%{public}d, "
180 "height:%{public}d",
181 outputInfo.type, outputInfo.minfps, outputInfo.minfps,
182 outputInfo.width, outputInfo.height);
183 }
184
185 auto zoomInfo = captureSessionInfo.zoomInfo;
186 MEDIA_INFO_LOG("OnCaptureSessionConfiged zoomInfo zoomValue:%{public}f, "
187 "equivalentFocus:%{public}d, focusStatus:%{public}d, focusMode:%{public}d, "
188 "videoStabilizationMode:%{public}d",
189 zoomInfo.zoomValue, zoomInfo.equivalentFocus, zoomInfo.focusStatus,
190 zoomInfo.focusMode, zoomInfo.videoStabilizationMode);
191 }
192
MechSession(sptr<IMechSession> session)193 MechSession::MechSession(sptr<IMechSession> session) : remoteSession_(session)
194 {
195 MEDIA_INFO_LOG("%{public}s is called!", __FUNCTION__);
196 sptr<IRemoteObject> object = remoteSession_->AsObject();
197 pid_t pid = 0;
198 deathRecipient_ = new (std::nothrow) CameraDeathRecipient(pid);
199 CHECK_RETURN_ELOG(deathRecipient_ == nullptr, "failed to new CameraDeathRecipient.");
200
201 deathRecipient_->SetNotifyCb([this](pid_t pid) { CameraServerDied(pid); });
202 bool result = object->AddDeathRecipient(deathRecipient_);
203 if (!result) {
204 MEDIA_ERR_LOG("failed to add deathRecipient");
205 return;
206 }
207 }
208
~MechSession()209 MechSession::~MechSession()
210 {
211 MEDIA_INFO_LOG("%{public}s is called!", __FUNCTION__);
212 RemoveDeathRecipient();
213 }
214
EnableMechDelivery(bool isEnableMech)215 int32_t MechSession::EnableMechDelivery(bool isEnableMech)
216 {
217 MEDIA_INFO_LOG("%{public}s is called, isEnableMech:%{public}d", __FUNCTION__, isEnableMech);
218 auto remoteSession = GetRemoteSession();
219 CHECK_RETURN_RET_ELOG(remoteSession == nullptr, CameraErrorCode::INVALID_ARGUMENT,
220 "MechSession::EnableMechDelivery mechSession is nullptr");
221
222 int32_t retCode = remoteSession->EnableMechDelivery(isEnableMech);
223 CHECK_RETURN_RET_ELOG(retCode != CAMERA_OK, retCode,
224 "Failed to EnableMechDelivery!, %{public}d", retCode);
225 return CameraErrorCode::SUCCESS;
226 }
227
SetCallback(std::shared_ptr<MechSessionCallback> callback)228 void MechSession::SetCallback(std::shared_ptr<MechSessionCallback> callback)
229 {
230 MEDIA_INFO_LOG("%{public}s is called!", __FUNCTION__);
231 std::lock_guard<std::mutex> lock(callbackMutex_);
232 auto remoteSession = GetRemoteSession();
233 CHECK_RETURN_ELOG(remoteSession == nullptr,
234 "MechSession::SetCallback mechSession is null");
235 sptr<IMechSessionCallback> remoteCallback = new(std::nothrow) MechSessionCallbackImpl(this);
236 CHECK_RETURN_ELOG(remoteCallback == nullptr,
237 "MechSession::SetCallback failed to new MechSessionCallbackImpl!");
238 remoteSession->SetCallback(remoteCallback);
239
240 appCallback_ = callback;
241 }
242
GetCallback()243 std::shared_ptr<MechSessionCallback> MechSession::GetCallback()
244 {
245 std::lock_guard<std::mutex> lock(callbackMutex_);
246 return appCallback_;
247 }
248
Release()249 int32_t MechSession::Release()
250 {
251 MEDIA_INFO_LOG("%{public}s is called!", __FUNCTION__);
252 auto remoteSession = GetRemoteSession();
253 CHECK_RETURN_RET_ELOG(remoteSession == nullptr, CameraErrorCode::INVALID_ARGUMENT,
254 "MechSession::Release remoteSession is nullptr");
255 int32_t retCode = remoteSession->Release();
256 CHECK_RETURN_RET_ELOG(retCode != CAMERA_OK, retCode,
257 "Failed to Release!, %{public}d", retCode);
258 return CameraErrorCode::SUCCESS;
259 }
260
GetRemoteSession()261 sptr<IMechSession> MechSession::GetRemoteSession()
262 {
263 std::lock_guard<std::mutex> lock(remoteSessionMutex_);
264 return remoteSession_;
265 }
266
SetRemoteSession(sptr<IMechSession> remoteSession)267 void MechSession::SetRemoteSession(sptr<IMechSession> remoteSession)
268 {
269 std::lock_guard<std::mutex> lock(remoteSessionMutex_);
270 remoteSession_ = remoteSession;
271 }
272
RemoveDeathRecipient()273 void MechSession::RemoveDeathRecipient()
274 {
275 auto remoteSession = GetRemoteSession();
276 if (remoteSession != nullptr) {
277 auto asObject = remoteSession->AsObject();
278 if (asObject) {
279 (void)asObject->RemoveDeathRecipient(deathRecipient_);
280 }
281 SetRemoteSession(nullptr);
282 }
283 deathRecipient_ = nullptr;
284 }
285
CameraServerDied(pid_t pid)286 void MechSession::CameraServerDied(pid_t pid)
287 {
288 MEDIA_ERR_LOG("camera server has died, pid:%{public}d!", pid);
289 RemoveDeathRecipient();
290 }
291 } // namespace CameraStandard
292 } // namespace OHOS
293
294