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/camera2/ICameraDeviceCallbacks.h>
26
27 #include "device3/hidl/HidlCamera3OfflineSession.h"
28 #include "device3/Camera3OutputStream.h"
29 #include "device3/hidl/HidlCamera3OutputUtils.h"
30 #include "device3/Camera3InputStream.h"
31 #include "device3/Camera3SharedOutputStream.h"
32 #include "utils/CameraTraces.h"
33
34 using namespace android::camera3;
35 using namespace android::hardware::camera;
36
37 namespace android {
38
~HidlCamera3OfflineSession()39 HidlCamera3OfflineSession::~HidlCamera3OfflineSession() {
40 ATRACE_CALL();
41 ALOGV("%s: Tearing down hidl offline session for camera id %s", __FUNCTION__, mId.string());
42 HidlCamera3OfflineSession::disconnectSession();
43 }
44
initialize(wp<NotificationListener> listener)45 status_t HidlCamera3OfflineSession::initialize(wp<NotificationListener> listener) {
46 ATRACE_CALL();
47
48 if (mSession == nullptr) {
49 ALOGE("%s: HIDL session is null!", __FUNCTION__);
50 return DEAD_OBJECT;
51 }
52
53 {
54 std::lock_guard<std::mutex> lock(mLock);
55
56 mListener = listener;
57
58 // setup result FMQ
59 std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
60 auto resultQueueRet = mSession->getCaptureResultMetadataQueue(
61 [&resQueue](const auto& descriptor) {
62 resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
63 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
64 ALOGE("HAL returns empty result metadata fmq, not use it");
65 resQueue = nullptr;
66 // Don't use resQueue onwards.
67 }
68 });
69 if (!resultQueueRet.isOk()) {
70 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
71 resultQueueRet.description().c_str());
72 return DEAD_OBJECT;
73 }
74 mStatus = STATUS_ACTIVE;
75 }
76
77 mSession->setCallback(this);
78
79 return OK;
80 }
81
processCaptureResult_3_4(const hardware::hidl_vec<hardware::camera::device::V3_4::CaptureResult> & results)82 hardware::Return<void> HidlCamera3OfflineSession::processCaptureResult_3_4(
83 const hardware::hidl_vec<
84 hardware::camera::device::V3_4::CaptureResult>& results) {
85 sp<NotificationListener> listener;
86 {
87 std::lock_guard<std::mutex> lock(mLock);
88 if (mStatus != STATUS_ACTIVE) {
89 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
90 return hardware::Void();
91 }
92 listener = mListener.promote();
93 }
94
95 std::string activePhysicalId("");
96 HidlCaptureOutputStates states {
97 {mId,
98 mOfflineReqsLock, mLastCompletedRegularFrameNumber,
99 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
100 mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
101 mNextShutterFrameNumber,
102 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
103 mNextResultFrameNumber,
104 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
105 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
106 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
107 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
108 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
109 mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
110 /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
111 };
112
113 std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
114 for (const auto& result : results) {
115 processOneCaptureResultLocked(states, result.v3_2, result.physicalCameraMetadata);
116 }
117 return hardware::Void();
118 }
119
processCaptureResult(const hardware::hidl_vec<hardware::camera::device::V3_2::CaptureResult> & results)120 hardware::Return<void> HidlCamera3OfflineSession::processCaptureResult(
121 const hardware::hidl_vec<
122 hardware::camera::device::V3_2::CaptureResult>& results) {
123 // TODO: changed impl to call into processCaptureResult_3_4 instead?
124 // might need to figure how to reduce copy though.
125 sp<NotificationListener> listener;
126 {
127 std::lock_guard<std::mutex> lock(mLock);
128 if (mStatus != STATUS_ACTIVE) {
129 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
130 return hardware::Void();
131 }
132 listener = mListener.promote();
133 }
134
135 hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
136
137 std::string activePhysicalId("");
138 HidlCaptureOutputStates states {
139 {mId,
140 mOfflineReqsLock, mLastCompletedRegularFrameNumber,
141 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
142 mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
143 mNextShutterFrameNumber,
144 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
145 mNextResultFrameNumber,
146 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
147 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
148 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
149 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
150 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
151 mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
152 /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
153 };
154
155 std::lock_guard<std::mutex> lock(mProcessCaptureResultLock);
156 for (const auto& result : results) {
157 processOneCaptureResultLocked(states, result, noPhysMetadata);
158 }
159 return hardware::Void();
160 }
161
notify(const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg> & msgs)162 hardware::Return<void> HidlCamera3OfflineSession::notify(
163 const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg>& msgs) {
164 sp<NotificationListener> listener;
165 {
166 std::lock_guard<std::mutex> lock(mLock);
167 if (mStatus != STATUS_ACTIVE) {
168 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
169 return hardware::Void();
170 }
171 listener = mListener.promote();
172 }
173
174 std::string activePhysicalId("");
175 HidlCaptureOutputStates states {
176 {mId,
177 mOfflineReqsLock, mLastCompletedRegularFrameNumber,
178 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
179 mOfflineReqs, mOutputLock, mResultQueue, mResultSignal,
180 mNextShutterFrameNumber,
181 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
182 mNextResultFrameNumber,
183 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
184 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
185 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
186 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
187 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
188 mBufferRecords, /*legacyClient*/ false, mMinExpectedDuration, mIsFixedFps,
189 /*overrideToPortrait*/false, activePhysicalId}, mResultMetadataQueue
190 };
191 for (const auto& msg : msgs) {
192 camera3::notify(states, msg);
193 }
194 return hardware::Void();
195 }
196
requestStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest> & bufReqs,requestStreamBuffers_cb _hidl_cb)197 hardware::Return<void> HidlCamera3OfflineSession::requestStreamBuffers(
198 const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
199 requestStreamBuffers_cb _hidl_cb) {
200 {
201 std::lock_guard<std::mutex> lock(mLock);
202 if (mStatus != STATUS_ACTIVE) {
203 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
204 return hardware::Void();
205 }
206 }
207
208 RequestBufferStates states {
209 mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
210 *this, mBufferRecords, *this};
211 camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
212 return hardware::Void();
213 }
214
returnStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer> & buffers)215 hardware::Return<void> HidlCamera3OfflineSession::returnStreamBuffers(
216 const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
217 {
218 std::lock_guard<std::mutex> lock(mLock);
219 if (mStatus != STATUS_ACTIVE) {
220 ALOGE("%s called in wrong state %d", __FUNCTION__, mStatus);
221 return hardware::Void();
222 }
223 }
224
225 ReturnBufferStates states {
226 mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, mBufferRecords};
227
228 camera3::returnStreamBuffers(states, buffers);
229 return hardware::Void();
230 }
231
disconnectSession()232 void HidlCamera3OfflineSession::disconnectSession() {
233 // TODO: Make sure this locking is correct.
234 std::lock_guard<std::mutex> lock(mLock);
235 if (mSession != nullptr) {
236 mSession->close();
237 }
238 mSession.clear();
239 }
240
241 }; // namespace android
242