• 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     disconnectImpl();
85 }
86 
getId() const87 const String8& Camera3OfflineSession::getId() const {
88     return mId;
89 }
90 
dump(int)91 status_t Camera3OfflineSession::dump(int /*fd*/) {
92     ATRACE_CALL();
93     std::lock_guard<std::mutex> il(mInterfaceLock);
94     return OK;
95 }
96 
disconnect()97 status_t Camera3OfflineSession::disconnect() {
98     ATRACE_CALL();
99     disconnectSession();
100     return disconnectImpl();
101 }
102 
disconnectImpl()103 status_t Camera3OfflineSession::disconnectImpl() {
104     ATRACE_CALL();
105     std::lock_guard<std::mutex> il(mInterfaceLock);
106 
107     sp<NotificationListener> listener;
108     {
109         std::lock_guard<std::mutex> lock(mLock);
110         if (mStatus == STATUS_CLOSED) {
111             return OK; // don't close twice
112         } else if (mStatus == STATUS_ERROR) {
113             ALOGE("%s: offline session %s shutting down in error state",
114                     __FUNCTION__, mId.string());
115         }
116         listener = mListener.promote();
117     }
118 
119     ALOGV("%s: E", __FUNCTION__);
120 
121     {
122         std::lock_guard<std::mutex> lock(mRequestBufferInterfaceLock);
123         mAllowRequestBuffer = false;
124     }
125 
126     std::vector<wp<Camera3StreamInterface>> streams;
127     streams.reserve(mOutputStreams.size() + (mInputStream != nullptr ? 1 : 0));
128     for (size_t i = 0; i < mOutputStreams.size(); i++) {
129         streams.push_back(mOutputStreams[i]);
130     }
131     if (mInputStream != nullptr) {
132         streams.push_back(mInputStream);
133     }
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         mOutputStreams.clear();
144         mInputStream.clear();
145         mStatus = STATUS_CLOSED;
146     }
147 
148     for (auto& weakStream : streams) {
149         sp<Camera3StreamInterface> stream = weakStream.promote();
150         if (stream != nullptr) {
151             ALOGE("%s: Stream %d leaked! strong reference (%d)!",
152                     __FUNCTION__, stream->getId(), stream->getStrongCount() - 1);
153         }
154     }
155 
156     ALOGV("%s: X", __FUNCTION__);
157     return OK;
158 }
159 
waitForNextFrame(nsecs_t timeout)160 status_t Camera3OfflineSession::waitForNextFrame(nsecs_t timeout) {
161     ATRACE_CALL();
162     std::unique_lock<std::mutex> lk(mOutputLock);
163 
164     while (mResultQueue.empty()) {
165         auto st = mResultSignal.wait_for(lk, std::chrono::nanoseconds(timeout));
166         if (st == std::cv_status::timeout) {
167             return TIMED_OUT;
168         }
169     }
170     return OK;
171 }
172 
getNextResult(CaptureResult * frame)173 status_t Camera3OfflineSession::getNextResult(CaptureResult* frame) {
174     ATRACE_CALL();
175     std::lock_guard<std::mutex> l(mOutputLock);
176 
177     if (mResultQueue.empty()) {
178         return NOT_ENOUGH_DATA;
179     }
180 
181     if (frame == nullptr) {
182         ALOGE("%s: argument cannot be NULL", __FUNCTION__);
183         return BAD_VALUE;
184     }
185 
186     CaptureResult &result = *(mResultQueue.begin());
187     frame->mResultExtras = result.mResultExtras;
188     frame->mMetadata.acquire(result.mMetadata);
189     frame->mPhysicalMetadatas = std::move(result.mPhysicalMetadatas);
190     mResultQueue.erase(mResultQueue.begin());
191 
192     return OK;
193 }
194 
setErrorState(const char * fmt,...)195 void Camera3OfflineSession::setErrorState(const char *fmt, ...) {
196     ATRACE_CALL();
197     std::lock_guard<std::mutex> lock(mLock);
198     va_list args;
199     va_start(args, fmt);
200 
201     setErrorStateLockedV(fmt, args);
202 
203     va_end(args);
204 
205     //FIXME: automatically disconnect here?
206 }
207 
setErrorStateLocked(const char * fmt,...)208 void Camera3OfflineSession::setErrorStateLocked(const char *fmt, ...) {
209     va_list args;
210     va_start(args, fmt);
211 
212     setErrorStateLockedV(fmt, args);
213 
214     va_end(args);
215 }
216 
setErrorStateLockedV(const char * fmt,va_list args)217 void Camera3OfflineSession::setErrorStateLockedV(const char *fmt, va_list args) {
218     // Print out all error messages to log
219     String8 errorCause = String8::formatV(fmt, args);
220     ALOGE("Camera %s: %s", mId.string(), errorCause.string());
221 
222     // But only do error state transition steps for the first error
223     if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
224 
225     mErrorCause = errorCause;
226 
227     mStatus = STATUS_ERROR;
228 
229     // Notify upstream about a device error
230     sp<NotificationListener> listener = mListener.promote();
231     if (listener != NULL) {
232         listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
233                 CaptureResultExtras());
234     }
235 
236     // Save stack trace. View by dumping it later.
237     CameraTraces::saveTrace();
238 }
239 
onInflightEntryRemovedLocked(nsecs_t)240 void Camera3OfflineSession::onInflightEntryRemovedLocked(nsecs_t /*duration*/) {
241     if (mOfflineReqs.size() == 0) {
242         std::lock_guard<std::mutex> lock(mRequestBufferInterfaceLock);
243         mAllowRequestBuffer = false;
244     }
245 }
246 
checkInflightMapLengthLocked()247 void Camera3OfflineSession::checkInflightMapLengthLocked() {
248     // Intentional empty impl.
249 }
250 
onInflightMapFlushedLocked()251 void Camera3OfflineSession::onInflightMapFlushedLocked() {
252     // Intentional empty impl.
253 }
254 
startRequestBuffer()255 bool Camera3OfflineSession::startRequestBuffer() {
256     return mAllowRequestBuffer;
257 }
258 
endRequestBuffer()259 void Camera3OfflineSession::endRequestBuffer() {
260     // Intentional empty impl.
261 }
262 
getWaitDuration()263 nsecs_t Camera3OfflineSession::getWaitDuration() {
264     const nsecs_t kBaseGetBufferWait = 3000000000; // 3 sec.
265     return kBaseGetBufferWait;
266 }
267 
getInflightBufferKeys(std::vector<std::pair<int32_t,int32_t>> * out)268 void Camera3OfflineSession::getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out) {
269     mBufferRecords.getInflightBufferKeys(out);
270 }
271 
getInflightRequestBufferKeys(std::vector<uint64_t> * out)272 void Camera3OfflineSession::getInflightRequestBufferKeys(std::vector<uint64_t>* out) {
273     mBufferRecords.getInflightRequestBufferKeys(out);
274 }
275 
getAllStreams()276 std::vector<sp<Camera3StreamInterface>> Camera3OfflineSession::getAllStreams() {
277     std::vector<sp<Camera3StreamInterface>> ret;
278     bool hasInputStream = mInputStream != nullptr;
279     ret.reserve(mOutputStreams.size() + ((hasInputStream) ? 1 : 0));
280     if (hasInputStream) {
281         ret.push_back(mInputStream);
282     }
283     for (size_t i = 0; i < mOutputStreams.size(); i++) {
284         ret.push_back(mOutputStreams[i]);
285     }
286     return ret;
287 }
288 
info() const289 const CameraMetadata& Camera3OfflineSession::info() const {
290     return mDeviceInfo;
291 }
292 
293 }; // namespace android
294