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