1 /*
2 * Copyright (C) 2019 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 "Camera3-OffLnSsn"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 //#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22 #ifdef LOG_NNDEBUG
23 #define ALOGVV(...) ALOGV(__VA_ARGS__)
24 #else
25 #define ALOGVV(...) ((void)0)
26 #endif
27
28 #include <inttypes.h>
29
30 #include <android-base/stringprintf.h>
31 #include <utils/Trace.h>
32 #include <camera/StringUtils.h>
33
34 #include <android/hardware/camera2/ICameraDeviceCallbacks.h>
35
36 #include "device3/Camera3OfflineSession.h"
37 #include "device3/Camera3OutputStream.h"
38 #include "device3/Camera3InputStream.h"
39 #include "device3/Camera3SharedOutputStream.h"
40 #include "utils/CameraTraces.h"
41
42 using namespace android::camera3;
43 using namespace android::hardware::camera;
44
45 namespace android {
46
Camera3OfflineSession(const std::string & id,const sp<camera3::Camera3Stream> & inputStream,const camera3::StreamSet & offlineStreamSet,camera3::BufferRecords && bufferRecords,const camera3::InFlightRequestMap & offlineReqs,const Camera3OfflineStates & offlineStates)47 Camera3OfflineSession::Camera3OfflineSession(const std::string &id,
48 const sp<camera3::Camera3Stream>& inputStream,
49 const camera3::StreamSet& offlineStreamSet,
50 camera3::BufferRecords&& bufferRecords,
51 const camera3::InFlightRequestMap& offlineReqs,
52 const Camera3OfflineStates& offlineStates) :
53 mId(id),
54 mInputStream(inputStream),
55 mOutputStreams(offlineStreamSet),
56 mBufferRecords(std::move(bufferRecords)),
57 mOfflineReqs(offlineReqs),
58 mTagMonitor(offlineStates.mTagMonitor),
59 mVendorTagId(offlineStates.mVendorTagId),
60 mUseHalBufManager(offlineStates.mUseHalBufManager),
61 mHalBufManagedStreamIds(offlineStates.mHalBufManagedStreamIds),
62 mNeedFixupMonochromeTags(offlineStates.mNeedFixupMonochromeTags),
63 mUsePartialResult(offlineStates.mUsePartialResult),
64 mNumPartialResults(offlineStates.mNumPartialResults),
65 mLastCompletedRegularFrameNumber(offlineStates.mLastCompletedRegularFrameNumber),
66 mLastCompletedReprocessFrameNumber(offlineStates.mLastCompletedReprocessFrameNumber),
67 mLastCompletedZslFrameNumber(offlineStates.mLastCompletedZslFrameNumber),
68 mNextResultFrameNumber(offlineStates.mNextResultFrameNumber),
69 mNextReprocessResultFrameNumber(offlineStates.mNextReprocessResultFrameNumber),
70 mNextZslStillResultFrameNumber(offlineStates.mNextZslStillResultFrameNumber),
71 mNextShutterFrameNumber(offlineStates.mNextShutterFrameNumber),
72 mNextReprocessShutterFrameNumber(offlineStates.mNextReprocessShutterFrameNumber),
73 mNextZslStillShutterFrameNumber(offlineStates.mNextZslStillShutterFrameNumber),
74 mDeviceInfo(offlineStates.mDeviceInfo),
75 mPhysicalDeviceInfoMap(offlineStates.mPhysicalDeviceInfoMap),
76 mDistortionMappers(offlineStates.mDistortionMappers),
77 mZoomRatioMappers(offlineStates.mZoomRatioMappers),
78 mRotateAndCropMappers(offlineStates.mRotateAndCropMappers),
79 mStatus(STATUS_UNINITIALIZED) {
80 ATRACE_CALL();
81 ALOGV("%s: Created offline session for camera %s", __FUNCTION__, mId.c_str());
82 }
83
~Camera3OfflineSession()84 Camera3OfflineSession::~Camera3OfflineSession() {
85 ATRACE_CALL();
86 ALOGV("%s: Tearing down offline session for camera id %s", __FUNCTION__, mId.c_str());
87 }
88
getId() const89 const std::string& Camera3OfflineSession::getId() const {
90 return mId;
91 }
92
dump(int)93 status_t Camera3OfflineSession::dump(int /*fd*/) {
94 ATRACE_CALL();
95 std::lock_guard<std::mutex> il(mInterfaceLock);
96 return OK;
97 }
98
disconnect()99 status_t Camera3OfflineSession::disconnect() {
100 ATRACE_CALL();
101 return disconnectImpl();
102 }
103
disconnectImpl()104 status_t Camera3OfflineSession::disconnectImpl() {
105 ATRACE_CALL();
106 std::lock_guard<std::mutex> il(mInterfaceLock);
107
108 sp<NotificationListener> listener;
109 {
110 std::lock_guard<std::mutex> lock(mLock);
111 if (mStatus == STATUS_CLOSED) {
112 return OK; // don't close twice
113 } else if (mStatus == STATUS_ERROR) {
114 ALOGE("%s: offline session %s shutting down in error state",
115 __FUNCTION__, mId.c_str());
116 }
117 listener = mListener.promote();
118 }
119
120 ALOGV("%s: E", __FUNCTION__);
121
122 {
123 std::lock_guard<std::mutex> lock(mRequestBufferInterfaceLock);
124 mAllowRequestBuffer = false;
125 }
126
127 std::vector<wp<Camera3StreamInterface>> streams;
128 streams.reserve(mOutputStreams.size() + (mInputStream != nullptr ? 1 : 0));
129 for (size_t i = 0; i < mOutputStreams.size(); i++) {
130 streams.push_back(mOutputStreams[i]);
131 }
132 if (mInputStream != nullptr) {
133 streams.push_back(mInputStream);
134 }
135
136 closeSessionLocked();
137
138 FlushInflightReqStates states {
139 mId, mOfflineReqsLock, mOfflineReqs, mUseHalBufManager,
140 mHalBufManagedStreamIds, listener, *this, mBufferRecords, *this, mSessionStatsBuilder};
141
142 camera3::flushInflightRequests(states);
143
144 {
145 std::lock_guard<std::mutex> lock(mLock);
146 releaseSessionLocked();
147 mOutputStreams.clear();
148 mInputStream.clear();
149 mStatus = STATUS_CLOSED;
150 }
151
152 for (auto& weakStream : streams) {
153 sp<Camera3StreamInterface> stream = weakStream.promote();
154 if (stream != nullptr) {
155 ALOGE("%s: Stream %d leaked! strong reference (%d)!",
156 __FUNCTION__, stream->getId(), stream->getStrongCount() - 1);
157 }
158 }
159
160 ALOGV("%s: X", __FUNCTION__);
161 return OK;
162 }
163
waitForNextFrame(nsecs_t timeout)164 status_t Camera3OfflineSession::waitForNextFrame(nsecs_t timeout) {
165 ATRACE_CALL();
166 std::unique_lock<std::mutex> lk(mOutputLock);
167
168 while (mResultQueue.empty()) {
169 auto st = mResultSignal.wait_for(lk, std::chrono::nanoseconds(timeout));
170 if (st == std::cv_status::timeout) {
171 return TIMED_OUT;
172 }
173 }
174 return OK;
175 }
176
getNextResult(CaptureResult * frame)177 status_t Camera3OfflineSession::getNextResult(CaptureResult* frame) {
178 ATRACE_CALL();
179 std::lock_guard<std::mutex> l(mOutputLock);
180
181 if (mResultQueue.empty()) {
182 return NOT_ENOUGH_DATA;
183 }
184
185 if (frame == nullptr) {
186 ALOGE("%s: argument cannot be NULL", __FUNCTION__);
187 return BAD_VALUE;
188 }
189
190 CaptureResult &result = *(mResultQueue.begin());
191 frame->mResultExtras = result.mResultExtras;
192 frame->mMetadata.acquire(result.mMetadata);
193 frame->mPhysicalMetadatas = std::move(result.mPhysicalMetadatas);
194 mResultQueue.erase(mResultQueue.begin());
195
196 return OK;
197 }
198
setErrorState(const char * fmt,...)199 void Camera3OfflineSession::setErrorState(const char *fmt, ...) {
200 ATRACE_CALL();
201 std::lock_guard<std::mutex> lock(mLock);
202 va_list args;
203 va_start(args, fmt);
204
205 setErrorStateLockedV(fmt, args);
206
207 va_end(args);
208
209 //FIXME: automatically disconnect here?
210 }
211
setErrorStateLocked(const char * fmt,...)212 void Camera3OfflineSession::setErrorStateLocked(const char *fmt, ...) {
213 va_list args;
214 va_start(args, fmt);
215
216 setErrorStateLockedV(fmt, args);
217
218 va_end(args);
219 }
220
setErrorStateLockedV(const char * fmt,va_list args)221 void Camera3OfflineSession::setErrorStateLockedV(const char *fmt, va_list args) {
222 // Print out all error messages to log
223 std::string errorCause;
224 base::StringAppendV(&errorCause, fmt, args);
225 ALOGE("Camera %s: %s", mId.c_str(), errorCause.c_str());
226
227 // But only do error state transition steps for the first error
228 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
229
230 mErrorCause = errorCause;
231
232 mStatus = STATUS_ERROR;
233
234 // Notify upstream about a device error
235 sp<NotificationListener> listener = mListener.promote();
236 if (listener != NULL) {
237 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
238 CaptureResultExtras());
239 }
240
241 // Save stack trace. View by dumping it later.
242 CameraTraces::saveTrace();
243 }
244
onInflightEntryRemovedLocked(nsecs_t)245 void Camera3OfflineSession::onInflightEntryRemovedLocked(nsecs_t /*duration*/) {
246 if (mOfflineReqs.size() == 0) {
247 std::lock_guard<std::mutex> lock(mRequestBufferInterfaceLock);
248 mAllowRequestBuffer = false;
249 }
250 }
251
checkInflightMapLengthLocked()252 void Camera3OfflineSession::checkInflightMapLengthLocked() {
253 // Intentional empty impl.
254 }
255
onInflightMapFlushedLocked()256 void Camera3OfflineSession::onInflightMapFlushedLocked() {
257 // Intentional empty impl.
258 }
259
startRequestBuffer()260 bool Camera3OfflineSession::startRequestBuffer() {
261 return mAllowRequestBuffer;
262 }
263
endRequestBuffer()264 void Camera3OfflineSession::endRequestBuffer() {
265 // Intentional empty impl.
266 }
267
getWaitDuration()268 nsecs_t Camera3OfflineSession::getWaitDuration() {
269 const nsecs_t kBaseGetBufferWait = 3000000000; // 3 sec.
270 return kBaseGetBufferWait;
271 }
272
getInflightBufferKeys(std::vector<std::pair<int32_t,int32_t>> * out)273 void Camera3OfflineSession::getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out) {
274 mBufferRecords.getInflightBufferKeys(out);
275 }
276
getInflightRequestBufferKeys(std::vector<uint64_t> * out)277 void Camera3OfflineSession::getInflightRequestBufferKeys(std::vector<uint64_t>* out) {
278 mBufferRecords.getInflightRequestBufferKeys(out);
279 }
280
getAllStreams()281 std::vector<sp<Camera3StreamInterface>> Camera3OfflineSession::getAllStreams() {
282 std::vector<sp<Camera3StreamInterface>> ret;
283 bool hasInputStream = mInputStream != nullptr;
284 ret.reserve(mOutputStreams.size() + ((hasInputStream) ? 1 : 0));
285 if (hasInputStream) {
286 ret.push_back(mInputStream);
287 }
288 for (size_t i = 0; i < mOutputStreams.size(); i++) {
289 ret.push_back(mOutputStreams[i]);
290 }
291 return ret;
292 }
293
info() const294 const CameraMetadata& Camera3OfflineSession::info() const {
295 return mDeviceInfo;
296 }
297
298 }; // namespace android
299