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