1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "Hidl-Camera3-OffLnSsn"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20
21 #include <inttypes.h>
22
23 #include <utils/Trace.h>
24
25 #include <android/hardware/ICameraService.h>
26 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
27 #include <camera/StringUtils.h>
28
29 #include "device3/hidl/HidlCamera3OfflineSession.h"
30 #include "device3/Camera3OutputStream.h"
31 #include "device3/hidl/HidlCamera3OutputUtils.h"
32 #include "device3/Camera3InputStream.h"
33 #include "device3/Camera3SharedOutputStream.h"
34 #include "utils/CameraTraces.h"
35
36 using namespace android::camera3;
37 using namespace android::hardware::camera;
38
39 namespace android {
40
~HidlCamera3OfflineSession()41 HidlCamera3OfflineSession::~HidlCamera3OfflineSession() {
42 ATRACE_CALL();
43 ALOGV("%s: Tearing down hidl offline session for camera id %s", __FUNCTION__, mId.c_str());
44 Camera3OfflineSession::disconnectImpl();
45 }
46
initialize(wp<NotificationListener> listener)47 status_t HidlCamera3OfflineSession::initialize(wp<NotificationListener> listener) {
48 ATRACE_CALL();
49
50 if (mSession == nullptr) {
51 ALOGE("%s: HIDL session is null!", __FUNCTION__);
52 return DEAD_OBJECT;
53 }
54
55 {
56 std::lock_guard<std::mutex> lock(mLock);
57
58 mListener = listener;
59
60 // setup result FMQ
61 std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
62 auto resultQueueRet = mSession->getCaptureResultMetadataQueue(
63 [&resQueue](const auto& descriptor) {
64 resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
65 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
66 ALOGE("HAL returns empty result metadata fmq, not use it");
67 resQueue = nullptr;
68 // Don't use resQueue onwards.
69 }
70 });
71 if (!resultQueueRet.isOk()) {
72 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
73 resultQueueRet.description().c_str());
74 return DEAD_OBJECT;
75 }
76 mStatus = STATUS_ACTIVE;
77 }
78
79 mSession->setCallback(this);
80
81 return OK;
82 }
83
processCaptureResult_3_4(const hardware::hidl_vec<hardware::camera::device::V3_4::CaptureResult> & results)84 hardware::Return<void> HidlCamera3OfflineSession::processCaptureResult_3_4(
85 const hardware::hidl_vec<
86 hardware::camera::device::V3_4::CaptureResult>& results) {
87 sp<NotificationListener> listener;
88 {
89 std::lock_guard<std::mutex> lock(mLock);
90 if (mStatus != STATUS_ACTIVE) {
91 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
92 return hardware::Void();
93 }
94 listener = mListener.promote();
95 }
96
97 std::string activePhysicalId("");
98 HidlCaptureOutputStates states {
99 { mId,
100 mOfflineReqsLock, mLastCompletedRegularFrameNumber,
101 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
102 mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
103 mNextShutterFrameNumber,
104 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
105 mNextResultFrameNumber,
106 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
107 mUseHalBufManager, mHalBufManagedStreamIds, mUsePartialResult, mNeedFixupMonochromeTags,
108 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
109 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
110 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
111 mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
112 hardware::ICameraService::ROTATION_OVERRIDE_NONE, activePhysicalId}, mResultMetadataQueue
113 };
114
115 std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
116 for (const auto& result : results) {
117 processOneCaptureResultLocked(states, result.v3_2, result.physicalCameraMetadata);
118 }
119 return hardware::Void();
120 }
121
processCaptureResult(const hardware::hidl_vec<hardware::camera::device::V3_2::CaptureResult> & results)122 hardware::Return<void> HidlCamera3OfflineSession::processCaptureResult(
123 const hardware::hidl_vec<
124 hardware::camera::device::V3_2::CaptureResult>& results) {
125 // TODO: changed impl to call into processCaptureResult_3_4 instead?
126 // might need to figure how to reduce copy though.
127 sp<NotificationListener> listener;
128 {
129 std::lock_guard<std::mutex> lock(mLock);
130 if (mStatus != STATUS_ACTIVE) {
131 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
132 return hardware::Void();
133 }
134 listener = mListener.promote();
135 }
136
137 hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
138
139 std::string activePhysicalId("");
140 HidlCaptureOutputStates states {
141 { mId,
142 mOfflineReqsLock, mLastCompletedRegularFrameNumber,
143 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
144 mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
145 mNextShutterFrameNumber,
146 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
147 mNextResultFrameNumber,
148 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
149 mUseHalBufManager, mHalBufManagedStreamIds, mUsePartialResult, mNeedFixupMonochromeTags,
150 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
151 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
152 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
153 mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
154 hardware::ICameraService::ROTATION_OVERRIDE_NONE, activePhysicalId}, mResultMetadataQueue
155 };
156
157 std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
158 for (const auto& result : results) {
159 processOneCaptureResultLocked(states, result, noPhysMetadata);
160 }
161 return hardware::Void();
162 }
163
notify(const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg> & msgs)164 hardware::Return<void> HidlCamera3OfflineSession::notify(
165 const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg>& msgs) {
166 sp<NotificationListener> listener;
167 {
168 std::lock_guard<std::mutex> lock(mLock);
169 if (mStatus != STATUS_ACTIVE) {
170 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
171 return hardware::Void();
172 }
173 listener = mListener.promote();
174 }
175
176 std::string activePhysicalId("");
177 HidlCaptureOutputStates states {
178 { mId,
179 mOfflineReqsLock, mLastCompletedRegularFrameNumber,
180 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
181 mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
182 mNextShutterFrameNumber,
183 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
184 mNextResultFrameNumber,
185 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
186 mUseHalBufManager, mHalBufManagedStreamIds, mUsePartialResult, mNeedFixupMonochromeTags,
187 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
188 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
189 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
190 mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
191 hardware::ICameraService::ROTATION_OVERRIDE_NONE, activePhysicalId}, mResultMetadataQueue
192 };
193 for (const auto& msg : msgs) {
194 camera3::notify(states, msg);
195 }
196 return hardware::Void();
197 }
198
requestStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest> & bufReqs,requestStreamBuffers_cb _hidl_cb)199 hardware::Return<void> HidlCamera3OfflineSession::requestStreamBuffers(
200 const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
201 requestStreamBuffers_cb _hidl_cb) {
202 {
203 std::lock_guard<std::mutex> lock(mLock);
204 if (mStatus != STATUS_ACTIVE) {
205 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
206 return hardware::Void();
207 }
208 }
209
210 RequestBufferStates states {
211 mId, mRequestBufferInterfaceLock, mUseHalBufManager,mHalBufManagedStreamIds,
212 mOutputStreams, mSessionStatsBuilder,
213 *this, mBufferRecords, *this};
214 camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
215 return hardware::Void();
216 }
217
returnStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer> & buffers)218 hardware::Return<void> HidlCamera3OfflineSession::returnStreamBuffers(
219 const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
220 {
221 std::lock_guard<std::mutex> lock(mLock);
222 if (mStatus != STATUS_ACTIVE) {
223 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
224 return hardware::Void();
225 }
226 }
227
228 ReturnBufferStates states {
229 mId, mUseHalBufManager, mHalBufManagedStreamIds, mOutputStreams, mSessionStatsBuilder,
230 mBufferRecords};
231
232 camera3::returnStreamBuffers(states, buffers);
233 return hardware::Void();
234 }
235
closeSessionLocked()236 void HidlCamera3OfflineSession::closeSessionLocked() {
237 if (mSession != nullptr) {
238 auto err = mSession->close();
239 if (!err.isOk()) {
240 ALOGE("%s: Close transaction error: %s", __FUNCTION__, err.description().c_str());
241 }
242 }
243 }
244
releaseSessionLocked()245 void HidlCamera3OfflineSession::releaseSessionLocked() {
246 mSession.clear();
247 }
248
249 }; // namespace android
250