• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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