• 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 <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