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