1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker *
4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker *
8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker *
10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker */
16*4d7e907cSAndroid Build Coastguard Worker
17*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "[email protected]"
18*4d7e907cSAndroid Build Coastguard Worker #define ATRACE_TAG ATRACE_TAG_CAMERA
19*4d7e907cSAndroid Build Coastguard Worker #include <android/log.h>
20*4d7e907cSAndroid Build Coastguard Worker
21*4d7e907cSAndroid Build Coastguard Worker #include <vector>
22*4d7e907cSAndroid Build Coastguard Worker #include <utils/Trace.h>
23*4d7e907cSAndroid Build Coastguard Worker #include "CameraDeviceSession.h"
24*4d7e907cSAndroid Build Coastguard Worker
25*4d7e907cSAndroid Build Coastguard Worker namespace android {
26*4d7e907cSAndroid Build Coastguard Worker namespace hardware {
27*4d7e907cSAndroid Build Coastguard Worker namespace camera {
28*4d7e907cSAndroid Build Coastguard Worker namespace device {
29*4d7e907cSAndroid Build Coastguard Worker namespace V3_5 {
30*4d7e907cSAndroid Build Coastguard Worker namespace implementation {
31*4d7e907cSAndroid Build Coastguard Worker
CameraDeviceSession(camera3_device_t * device,const camera_metadata_t * deviceInfo,const sp<V3_2::ICameraDeviceCallback> & callback)32*4d7e907cSAndroid Build Coastguard Worker CameraDeviceSession::CameraDeviceSession(
33*4d7e907cSAndroid Build Coastguard Worker camera3_device_t* device,
34*4d7e907cSAndroid Build Coastguard Worker const camera_metadata_t* deviceInfo,
35*4d7e907cSAndroid Build Coastguard Worker const sp<V3_2::ICameraDeviceCallback>& callback) :
36*4d7e907cSAndroid Build Coastguard Worker V3_4::implementation::CameraDeviceSession(device, deviceInfo, callback) {
37*4d7e907cSAndroid Build Coastguard Worker
38*4d7e907cSAndroid Build Coastguard Worker mCallback_3_5 = nullptr;
39*4d7e907cSAndroid Build Coastguard Worker
40*4d7e907cSAndroid Build Coastguard Worker auto castResult = ICameraDeviceCallback::castFrom(callback);
41*4d7e907cSAndroid Build Coastguard Worker if (castResult.isOk()) {
42*4d7e907cSAndroid Build Coastguard Worker sp<ICameraDeviceCallback> callback3_5 = castResult;
43*4d7e907cSAndroid Build Coastguard Worker if (callback3_5 != nullptr) {
44*4d7e907cSAndroid Build Coastguard Worker mCallback_3_5 = callback3_5;
45*4d7e907cSAndroid Build Coastguard Worker }
46*4d7e907cSAndroid Build Coastguard Worker }
47*4d7e907cSAndroid Build Coastguard Worker
48*4d7e907cSAndroid Build Coastguard Worker if (mCallback_3_5 != nullptr) {
49*4d7e907cSAndroid Build Coastguard Worker camera_metadata_entry bufMgrVersion = mDeviceInfo.find(
50*4d7e907cSAndroid Build Coastguard Worker ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
51*4d7e907cSAndroid Build Coastguard Worker if (bufMgrVersion.count > 0) {
52*4d7e907cSAndroid Build Coastguard Worker mSupportBufMgr = (bufMgrVersion.data.u8[0] ==
53*4d7e907cSAndroid Build Coastguard Worker ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
54*4d7e907cSAndroid Build Coastguard Worker if (mSupportBufMgr) {
55*4d7e907cSAndroid Build Coastguard Worker request_stream_buffers = sRequestStreamBuffers;
56*4d7e907cSAndroid Build Coastguard Worker return_stream_buffers = sReturnStreamBuffers;
57*4d7e907cSAndroid Build Coastguard Worker }
58*4d7e907cSAndroid Build Coastguard Worker }
59*4d7e907cSAndroid Build Coastguard Worker }
60*4d7e907cSAndroid Build Coastguard Worker }
61*4d7e907cSAndroid Build Coastguard Worker
~CameraDeviceSession()62*4d7e907cSAndroid Build Coastguard Worker CameraDeviceSession::~CameraDeviceSession() {
63*4d7e907cSAndroid Build Coastguard Worker }
64*4d7e907cSAndroid Build Coastguard Worker
configureStreams_3_5(const StreamConfiguration & requestedConfiguration,ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb)65*4d7e907cSAndroid Build Coastguard Worker Return<void> CameraDeviceSession::configureStreams_3_5(
66*4d7e907cSAndroid Build Coastguard Worker const StreamConfiguration& requestedConfiguration,
67*4d7e907cSAndroid Build Coastguard Worker ICameraDeviceSession::configureStreams_3_5_cb _hidl_cb) {
68*4d7e907cSAndroid Build Coastguard Worker configureStreams_3_4_Impl(requestedConfiguration.v3_4, _hidl_cb,
69*4d7e907cSAndroid Build Coastguard Worker requestedConfiguration.streamConfigCounter, false /*useOverriddenFields*/);
70*4d7e907cSAndroid Build Coastguard Worker return Void();
71*4d7e907cSAndroid Build Coastguard Worker }
72*4d7e907cSAndroid Build Coastguard Worker
signalStreamFlush(const hidl_vec<int32_t> & streamIds,uint32_t streamConfigCounter)73*4d7e907cSAndroid Build Coastguard Worker Return<void> CameraDeviceSession::signalStreamFlush(
74*4d7e907cSAndroid Build Coastguard Worker const hidl_vec<int32_t>& streamIds, uint32_t streamConfigCounter) {
75*4d7e907cSAndroid Build Coastguard Worker if (mDevice->ops->signal_stream_flush == nullptr) {
76*4d7e907cSAndroid Build Coastguard Worker return Void();
77*4d7e907cSAndroid Build Coastguard Worker }
78*4d7e907cSAndroid Build Coastguard Worker
79*4d7e907cSAndroid Build Coastguard Worker uint32_t currentCounter = 0;
80*4d7e907cSAndroid Build Coastguard Worker {
81*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock _l(mStreamConfigCounterLock);
82*4d7e907cSAndroid Build Coastguard Worker currentCounter = mStreamConfigCounter;
83*4d7e907cSAndroid Build Coastguard Worker }
84*4d7e907cSAndroid Build Coastguard Worker
85*4d7e907cSAndroid Build Coastguard Worker if (streamConfigCounter < currentCounter) {
86*4d7e907cSAndroid Build Coastguard Worker ALOGV("%s: streamConfigCounter %d is stale (current %d), skipping signal_stream_flush call",
87*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, streamConfigCounter, mStreamConfigCounter);
88*4d7e907cSAndroid Build Coastguard Worker return Void();
89*4d7e907cSAndroid Build Coastguard Worker }
90*4d7e907cSAndroid Build Coastguard Worker
91*4d7e907cSAndroid Build Coastguard Worker std::vector<camera3_stream_t*> streams(streamIds.size());
92*4d7e907cSAndroid Build Coastguard Worker {
93*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock _l(mInflightLock);
94*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < streamIds.size(); i++) {
95*4d7e907cSAndroid Build Coastguard Worker int32_t id = streamIds[i];
96*4d7e907cSAndroid Build Coastguard Worker if (mStreamMap.count(id) == 0) {
97*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: unknown streamId %d", __FUNCTION__, id);
98*4d7e907cSAndroid Build Coastguard Worker return Void();
99*4d7e907cSAndroid Build Coastguard Worker }
100*4d7e907cSAndroid Build Coastguard Worker streams[i] = &mStreamMap[id];
101*4d7e907cSAndroid Build Coastguard Worker }
102*4d7e907cSAndroid Build Coastguard Worker }
103*4d7e907cSAndroid Build Coastguard Worker
104*4d7e907cSAndroid Build Coastguard Worker mDevice->ops->signal_stream_flush(mDevice, streams.size(), streams.data());
105*4d7e907cSAndroid Build Coastguard Worker return Void();
106*4d7e907cSAndroid Build Coastguard Worker }
107*4d7e907cSAndroid Build Coastguard Worker
importRequest(const CaptureRequest & request,hidl_vec<buffer_handle_t * > & allBufPtrs,hidl_vec<int> & allFences)108*4d7e907cSAndroid Build Coastguard Worker Status CameraDeviceSession::importRequest(
109*4d7e907cSAndroid Build Coastguard Worker const CaptureRequest& request,
110*4d7e907cSAndroid Build Coastguard Worker hidl_vec<buffer_handle_t*>& allBufPtrs,
111*4d7e907cSAndroid Build Coastguard Worker hidl_vec<int>& allFences) {
112*4d7e907cSAndroid Build Coastguard Worker if (mSupportBufMgr) {
113*4d7e907cSAndroid Build Coastguard Worker return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ true);
114*4d7e907cSAndroid Build Coastguard Worker }
115*4d7e907cSAndroid Build Coastguard Worker return importRequestImpl(request, allBufPtrs, allFences, /*allowEmptyBuf*/ false);
116*4d7e907cSAndroid Build Coastguard Worker }
117*4d7e907cSAndroid Build Coastguard Worker
pushBufferId(const buffer_handle_t & buf,uint64_t bufferId,int streamId)118*4d7e907cSAndroid Build Coastguard Worker void CameraDeviceSession::pushBufferId(
119*4d7e907cSAndroid Build Coastguard Worker const buffer_handle_t& buf, uint64_t bufferId, int streamId) {
120*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mBufferIdMapLock);
121*4d7e907cSAndroid Build Coastguard Worker
122*4d7e907cSAndroid Build Coastguard Worker // emplace will return existing entry if there is one.
123*4d7e907cSAndroid Build Coastguard Worker auto pair = mBufferIdMaps.emplace(streamId, BufferIdMap{});
124*4d7e907cSAndroid Build Coastguard Worker BufferIdMap& bIdMap = pair.first->second;
125*4d7e907cSAndroid Build Coastguard Worker bIdMap[buf] = bufferId;
126*4d7e907cSAndroid Build Coastguard Worker }
127*4d7e907cSAndroid Build Coastguard Worker
popBufferId(const buffer_handle_t & buf,int streamId)128*4d7e907cSAndroid Build Coastguard Worker uint64_t CameraDeviceSession::popBufferId(
129*4d7e907cSAndroid Build Coastguard Worker const buffer_handle_t& buf, int streamId) {
130*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> lock(mBufferIdMapLock);
131*4d7e907cSAndroid Build Coastguard Worker
132*4d7e907cSAndroid Build Coastguard Worker auto streamIt = mBufferIdMaps.find(streamId);
133*4d7e907cSAndroid Build Coastguard Worker if (streamIt == mBufferIdMaps.end()) {
134*4d7e907cSAndroid Build Coastguard Worker return BUFFER_ID_NO_BUFFER;
135*4d7e907cSAndroid Build Coastguard Worker }
136*4d7e907cSAndroid Build Coastguard Worker BufferIdMap& bIdMap = streamIt->second;
137*4d7e907cSAndroid Build Coastguard Worker auto it = bIdMap.find(buf);
138*4d7e907cSAndroid Build Coastguard Worker if (it == bIdMap.end()) {
139*4d7e907cSAndroid Build Coastguard Worker return BUFFER_ID_NO_BUFFER;
140*4d7e907cSAndroid Build Coastguard Worker }
141*4d7e907cSAndroid Build Coastguard Worker uint64_t bufId = it->second;
142*4d7e907cSAndroid Build Coastguard Worker bIdMap.erase(it);
143*4d7e907cSAndroid Build Coastguard Worker if (bIdMap.empty()) {
144*4d7e907cSAndroid Build Coastguard Worker mBufferIdMaps.erase(streamIt);
145*4d7e907cSAndroid Build Coastguard Worker }
146*4d7e907cSAndroid Build Coastguard Worker return bufId;
147*4d7e907cSAndroid Build Coastguard Worker }
148*4d7e907cSAndroid Build Coastguard Worker
getCapResultBufferId(const buffer_handle_t & buf,int streamId)149*4d7e907cSAndroid Build Coastguard Worker uint64_t CameraDeviceSession::getCapResultBufferId(const buffer_handle_t& buf, int streamId) {
150*4d7e907cSAndroid Build Coastguard Worker if (mSupportBufMgr) {
151*4d7e907cSAndroid Build Coastguard Worker return popBufferId(buf, streamId);
152*4d7e907cSAndroid Build Coastguard Worker }
153*4d7e907cSAndroid Build Coastguard Worker return BUFFER_ID_NO_BUFFER;
154*4d7e907cSAndroid Build Coastguard Worker }
155*4d7e907cSAndroid Build Coastguard Worker
getStreamPointer(int32_t streamId)156*4d7e907cSAndroid Build Coastguard Worker Camera3Stream* CameraDeviceSession::getStreamPointer(int32_t streamId) {
157*4d7e907cSAndroid Build Coastguard Worker Mutex::Autolock _l(mInflightLock);
158*4d7e907cSAndroid Build Coastguard Worker if (mStreamMap.count(streamId) == 0) {
159*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: unknown streamId %d", __FUNCTION__, streamId);
160*4d7e907cSAndroid Build Coastguard Worker return nullptr;
161*4d7e907cSAndroid Build Coastguard Worker }
162*4d7e907cSAndroid Build Coastguard Worker return &mStreamMap[streamId];
163*4d7e907cSAndroid Build Coastguard Worker }
164*4d7e907cSAndroid Build Coastguard Worker
cleanupInflightBufferFences(std::vector<int> & fences,std::vector<std::pair<buffer_handle_t,int>> & bufs)165*4d7e907cSAndroid Build Coastguard Worker void CameraDeviceSession::cleanupInflightBufferFences(
166*4d7e907cSAndroid Build Coastguard Worker std::vector<int>& fences, std::vector<std::pair<buffer_handle_t, int>>& bufs) {
167*4d7e907cSAndroid Build Coastguard Worker hidl_vec<int> hFences = fences;
168*4d7e907cSAndroid Build Coastguard Worker cleanupInflightFences(hFences, fences.size());
169*4d7e907cSAndroid Build Coastguard Worker for (auto& p : bufs) {
170*4d7e907cSAndroid Build Coastguard Worker popBufferId(p.first, p.second);
171*4d7e907cSAndroid Build Coastguard Worker }
172*4d7e907cSAndroid Build Coastguard Worker }
173*4d7e907cSAndroid Build Coastguard Worker
requestStreamBuffers(uint32_t num_buffer_reqs,const camera3_buffer_request_t * buffer_reqs,uint32_t * num_returned_buf_reqs,camera3_stream_buffer_ret_t * returned_buf_reqs)174*4d7e907cSAndroid Build Coastguard Worker camera3_buffer_request_status_t CameraDeviceSession::requestStreamBuffers(
175*4d7e907cSAndroid Build Coastguard Worker uint32_t num_buffer_reqs,
176*4d7e907cSAndroid Build Coastguard Worker const camera3_buffer_request_t *buffer_reqs,
177*4d7e907cSAndroid Build Coastguard Worker /*out*/uint32_t *num_returned_buf_reqs,
178*4d7e907cSAndroid Build Coastguard Worker /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) {
179*4d7e907cSAndroid Build Coastguard Worker ATRACE_CALL();
180*4d7e907cSAndroid Build Coastguard Worker *num_returned_buf_reqs = 0;
181*4d7e907cSAndroid Build Coastguard Worker hidl_vec<BufferRequest> hBufReqs(num_buffer_reqs);
182*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < num_buffer_reqs; i++) {
183*4d7e907cSAndroid Build Coastguard Worker hBufReqs[i].streamId =
184*4d7e907cSAndroid Build Coastguard Worker static_cast<Camera3Stream*>(buffer_reqs[i].stream)->mId;
185*4d7e907cSAndroid Build Coastguard Worker hBufReqs[i].numBuffersRequested = buffer_reqs[i].num_buffers_requested;
186*4d7e907cSAndroid Build Coastguard Worker }
187*4d7e907cSAndroid Build Coastguard Worker
188*4d7e907cSAndroid Build Coastguard Worker ATRACE_BEGIN("HIDL requestStreamBuffers");
189*4d7e907cSAndroid Build Coastguard Worker BufferRequestStatus status;
190*4d7e907cSAndroid Build Coastguard Worker hidl_vec<StreamBufferRet> bufRets;
191*4d7e907cSAndroid Build Coastguard Worker auto err = mCallback_3_5->requestStreamBuffers(hBufReqs,
192*4d7e907cSAndroid Build Coastguard Worker [&status, &bufRets]
193*4d7e907cSAndroid Build Coastguard Worker (BufferRequestStatus s, const hidl_vec<StreamBufferRet>& rets) {
194*4d7e907cSAndroid Build Coastguard Worker status = s;
195*4d7e907cSAndroid Build Coastguard Worker bufRets = std::move(rets);
196*4d7e907cSAndroid Build Coastguard Worker });
197*4d7e907cSAndroid Build Coastguard Worker if (!err.isOk()) {
198*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
199*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
200*4d7e907cSAndroid Build Coastguard Worker }
201*4d7e907cSAndroid Build Coastguard Worker ATRACE_END();
202*4d7e907cSAndroid Build Coastguard Worker
203*4d7e907cSAndroid Build Coastguard Worker switch (status) {
204*4d7e907cSAndroid Build Coastguard Worker case BufferRequestStatus::FAILED_CONFIGURING:
205*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_CONFIGURING;
206*4d7e907cSAndroid Build Coastguard Worker case BufferRequestStatus::FAILED_ILLEGAL_ARGUMENTS:
207*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS;
208*4d7e907cSAndroid Build Coastguard Worker default:
209*4d7e907cSAndroid Build Coastguard Worker break; // Other status Handled by following code
210*4d7e907cSAndroid Build Coastguard Worker }
211*4d7e907cSAndroid Build Coastguard Worker
212*4d7e907cSAndroid Build Coastguard Worker if (status != BufferRequestStatus::OK && status != BufferRequestStatus::FAILED_PARTIAL &&
213*4d7e907cSAndroid Build Coastguard Worker status != BufferRequestStatus::FAILED_UNKNOWN) {
214*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: unknown buffer request error code %d", __FUNCTION__, status);
215*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
216*4d7e907cSAndroid Build Coastguard Worker }
217*4d7e907cSAndroid Build Coastguard Worker
218*4d7e907cSAndroid Build Coastguard Worker // Only OK, FAILED_PARTIAL and FAILED_UNKNOWN reaches here
219*4d7e907cSAndroid Build Coastguard Worker if (bufRets.size() != num_buffer_reqs) {
220*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: expect %d buffer requests returned, only got %zu",
221*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, num_buffer_reqs, bufRets.size());
222*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
223*4d7e907cSAndroid Build Coastguard Worker }
224*4d7e907cSAndroid Build Coastguard Worker
225*4d7e907cSAndroid Build Coastguard Worker *num_returned_buf_reqs = num_buffer_reqs;
226*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < num_buffer_reqs; i++) {
227*4d7e907cSAndroid Build Coastguard Worker // maybe we can query all streams in one call to avoid frequent locking device here?
228*4d7e907cSAndroid Build Coastguard Worker Camera3Stream* stream = getStreamPointer(bufRets[i].streamId);
229*4d7e907cSAndroid Build Coastguard Worker if (stream == nullptr) {
230*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: unknown streamId %d", __FUNCTION__, bufRets[i].streamId);
231*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
232*4d7e907cSAndroid Build Coastguard Worker }
233*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].stream = stream;
234*4d7e907cSAndroid Build Coastguard Worker }
235*4d7e907cSAndroid Build Coastguard Worker
236*4d7e907cSAndroid Build Coastguard Worker // Handle failed streams
237*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < num_buffer_reqs; i++) {
238*4d7e907cSAndroid Build Coastguard Worker if (bufRets[i].val.getDiscriminator() == StreamBuffersVal::hidl_discriminator::error) {
239*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].num_output_buffers = 0;
240*4d7e907cSAndroid Build Coastguard Worker switch (bufRets[i].val.error()) {
241*4d7e907cSAndroid Build Coastguard Worker case StreamBufferRequestError::NO_BUFFER_AVAILABLE:
242*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_NO_BUFFER_AVAILABLE;
243*4d7e907cSAndroid Build Coastguard Worker break;
244*4d7e907cSAndroid Build Coastguard Worker case StreamBufferRequestError::MAX_BUFFER_EXCEEDED:
245*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_MAX_BUFFER_EXCEEDED;
246*4d7e907cSAndroid Build Coastguard Worker break;
247*4d7e907cSAndroid Build Coastguard Worker case StreamBufferRequestError::STREAM_DISCONNECTED:
248*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_STREAM_DISCONNECTED;
249*4d7e907cSAndroid Build Coastguard Worker break;
250*4d7e907cSAndroid Build Coastguard Worker case StreamBufferRequestError::UNKNOWN_ERROR:
251*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_UNKNOWN_ERROR;
252*4d7e907cSAndroid Build Coastguard Worker break;
253*4d7e907cSAndroid Build Coastguard Worker default:
254*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: Unknown StreamBufferRequestError %d",
255*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, bufRets[i].val.error());
256*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
257*4d7e907cSAndroid Build Coastguard Worker }
258*4d7e907cSAndroid Build Coastguard Worker }
259*4d7e907cSAndroid Build Coastguard Worker }
260*4d7e907cSAndroid Build Coastguard Worker
261*4d7e907cSAndroid Build Coastguard Worker if (status == BufferRequestStatus::FAILED_UNKNOWN) {
262*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_UNKNOWN;
263*4d7e907cSAndroid Build Coastguard Worker }
264*4d7e907cSAndroid Build Coastguard Worker
265*4d7e907cSAndroid Build Coastguard Worker // Only BufferRequestStatus::OK and BufferRequestStatus::FAILED_PARTIAL reaches here
266*4d7e907cSAndroid Build Coastguard Worker std::vector<int> importedFences;
267*4d7e907cSAndroid Build Coastguard Worker std::vector<std::pair<buffer_handle_t, int>> importedBuffers;
268*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < num_buffer_reqs; i++) {
269*4d7e907cSAndroid Build Coastguard Worker if (bufRets[i].val.getDiscriminator() !=
270*4d7e907cSAndroid Build Coastguard Worker StreamBuffersVal::hidl_discriminator::buffers) {
271*4d7e907cSAndroid Build Coastguard Worker continue;
272*4d7e907cSAndroid Build Coastguard Worker }
273*4d7e907cSAndroid Build Coastguard Worker int streamId = bufRets[i].streamId;
274*4d7e907cSAndroid Build Coastguard Worker const hidl_vec<StreamBuffer>& hBufs = bufRets[i].val.buffers();
275*4d7e907cSAndroid Build Coastguard Worker camera3_stream_buffer_t* outBufs = returned_buf_reqs[i].output_buffers;
276*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].num_output_buffers = hBufs.size();
277*4d7e907cSAndroid Build Coastguard Worker for (size_t b = 0; b < hBufs.size(); b++) {
278*4d7e907cSAndroid Build Coastguard Worker const StreamBuffer& hBuf = hBufs[b];
279*4d7e907cSAndroid Build Coastguard Worker camera3_stream_buffer_t& outBuf = outBufs[b];
280*4d7e907cSAndroid Build Coastguard Worker // maybe add importBuffers API to avoid frequent locking device?
281*4d7e907cSAndroid Build Coastguard Worker Status s = importBuffer(streamId,
282*4d7e907cSAndroid Build Coastguard Worker hBuf.bufferId, hBuf.buffer.getNativeHandle(),
283*4d7e907cSAndroid Build Coastguard Worker /*out*/&(outBuf.buffer),
284*4d7e907cSAndroid Build Coastguard Worker /*allowEmptyBuf*/false);
285*4d7e907cSAndroid Build Coastguard Worker // Buffer import should never fail - restart HAL since something is very wrong.
286*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(s != Status::OK,
287*4d7e907cSAndroid Build Coastguard Worker "%s: import stream %d bufferId %" PRIu64 " failed!",
288*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, streamId, hBuf.bufferId);
289*4d7e907cSAndroid Build Coastguard Worker
290*4d7e907cSAndroid Build Coastguard Worker pushBufferId(*(outBuf.buffer), hBuf.bufferId, streamId);
291*4d7e907cSAndroid Build Coastguard Worker importedBuffers.push_back(std::make_pair(*(outBuf.buffer), streamId));
292*4d7e907cSAndroid Build Coastguard Worker
293*4d7e907cSAndroid Build Coastguard Worker bool succ = sHandleImporter.importFence(hBuf.acquireFence, outBuf.acquire_fence);
294*4d7e907cSAndroid Build Coastguard Worker // Fence import should never fail - restart HAL since something is very wrong.
295*4d7e907cSAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!succ,
296*4d7e907cSAndroid Build Coastguard Worker "%s: stream %d bufferId %" PRIu64 "acquire fence is invalid",
297*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, streamId, hBuf.bufferId);
298*4d7e907cSAndroid Build Coastguard Worker importedFences.push_back(outBuf.acquire_fence);
299*4d7e907cSAndroid Build Coastguard Worker outBuf.stream = returned_buf_reqs[i].stream;
300*4d7e907cSAndroid Build Coastguard Worker outBuf.status = CAMERA3_BUFFER_STATUS_OK;
301*4d7e907cSAndroid Build Coastguard Worker outBuf.release_fence = -1;
302*4d7e907cSAndroid Build Coastguard Worker }
303*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs[i].status = CAMERA3_PS_BUF_REQ_OK;
304*4d7e907cSAndroid Build Coastguard Worker }
305*4d7e907cSAndroid Build Coastguard Worker
306*4d7e907cSAndroid Build Coastguard Worker return (status == BufferRequestStatus::OK) ?
307*4d7e907cSAndroid Build Coastguard Worker CAMERA3_BUF_REQ_OK : CAMERA3_BUF_REQ_FAILED_PARTIAL;
308*4d7e907cSAndroid Build Coastguard Worker }
309*4d7e907cSAndroid Build Coastguard Worker
returnStreamBuffers(uint32_t num_buffers,const camera3_stream_buffer_t * const * buffers)310*4d7e907cSAndroid Build Coastguard Worker void CameraDeviceSession::returnStreamBuffers(
311*4d7e907cSAndroid Build Coastguard Worker uint32_t num_buffers,
312*4d7e907cSAndroid Build Coastguard Worker const camera3_stream_buffer_t* const* buffers) {
313*4d7e907cSAndroid Build Coastguard Worker ATRACE_CALL();
314*4d7e907cSAndroid Build Coastguard Worker hidl_vec<StreamBuffer> hBufs(num_buffers);
315*4d7e907cSAndroid Build Coastguard Worker
316*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < num_buffers; i++) {
317*4d7e907cSAndroid Build Coastguard Worker hBufs[i].streamId =
318*4d7e907cSAndroid Build Coastguard Worker static_cast<Camera3Stream*>(buffers[i]->stream)->mId;
319*4d7e907cSAndroid Build Coastguard Worker hBufs[i].buffer = nullptr; // use bufferId
320*4d7e907cSAndroid Build Coastguard Worker hBufs[i].bufferId = popBufferId(*(buffers[i]->buffer), hBufs[i].streamId);
321*4d7e907cSAndroid Build Coastguard Worker if (hBufs[i].bufferId == BUFFER_ID_NO_BUFFER) {
322*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: unknown buffer is returned to stream %d",
323*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, hBufs[i].streamId);
324*4d7e907cSAndroid Build Coastguard Worker }
325*4d7e907cSAndroid Build Coastguard Worker // ERROR since the buffer is not for application to consume
326*4d7e907cSAndroid Build Coastguard Worker hBufs[i].status = BufferStatus::ERROR;
327*4d7e907cSAndroid Build Coastguard Worker // skip acquire fence since it's of no use to camera service
328*4d7e907cSAndroid Build Coastguard Worker if (buffers[i]->release_fence != -1) {
329*4d7e907cSAndroid Build Coastguard Worker native_handle_t* handle = native_handle_create(/*numFds*/1, /*numInts*/0);
330*4d7e907cSAndroid Build Coastguard Worker handle->data[0] = buffers[i]->release_fence;
331*4d7e907cSAndroid Build Coastguard Worker hBufs[i].releaseFence.setTo(handle, /*shouldOwn*/true);
332*4d7e907cSAndroid Build Coastguard Worker }
333*4d7e907cSAndroid Build Coastguard Worker }
334*4d7e907cSAndroid Build Coastguard Worker
335*4d7e907cSAndroid Build Coastguard Worker mCallback_3_5->returnStreamBuffers(hBufs);
336*4d7e907cSAndroid Build Coastguard Worker return;
337*4d7e907cSAndroid Build Coastguard Worker }
338*4d7e907cSAndroid Build Coastguard Worker
339*4d7e907cSAndroid Build Coastguard Worker /**
340*4d7e907cSAndroid Build Coastguard Worker * Static callback forwarding methods from HAL to instance
341*4d7e907cSAndroid Build Coastguard Worker */
sRequestStreamBuffers(const struct camera3_callback_ops * cb,uint32_t num_buffer_reqs,const camera3_buffer_request_t * buffer_reqs,uint32_t * num_returned_buf_reqs,camera3_stream_buffer_ret_t * returned_buf_reqs)342*4d7e907cSAndroid Build Coastguard Worker camera3_buffer_request_status_t CameraDeviceSession::sRequestStreamBuffers(
343*4d7e907cSAndroid Build Coastguard Worker const struct camera3_callback_ops *cb,
344*4d7e907cSAndroid Build Coastguard Worker uint32_t num_buffer_reqs,
345*4d7e907cSAndroid Build Coastguard Worker const camera3_buffer_request_t *buffer_reqs,
346*4d7e907cSAndroid Build Coastguard Worker /*out*/uint32_t *num_returned_buf_reqs,
347*4d7e907cSAndroid Build Coastguard Worker /*out*/camera3_stream_buffer_ret_t *returned_buf_reqs) {
348*4d7e907cSAndroid Build Coastguard Worker CameraDeviceSession *d =
349*4d7e907cSAndroid Build Coastguard Worker const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
350*4d7e907cSAndroid Build Coastguard Worker
351*4d7e907cSAndroid Build Coastguard Worker if (num_buffer_reqs == 0 || buffer_reqs == nullptr || num_returned_buf_reqs == nullptr ||
352*4d7e907cSAndroid Build Coastguard Worker returned_buf_reqs == nullptr) {
353*4d7e907cSAndroid Build Coastguard Worker ALOGE("%s: bad argument: numBufReq %d, bufReqs %p, numRetBufReq %p, retBufReqs %p",
354*4d7e907cSAndroid Build Coastguard Worker __FUNCTION__, num_buffer_reqs, buffer_reqs,
355*4d7e907cSAndroid Build Coastguard Worker num_returned_buf_reqs, returned_buf_reqs);
356*4d7e907cSAndroid Build Coastguard Worker return CAMERA3_BUF_REQ_FAILED_ILLEGAL_ARGUMENTS;
357*4d7e907cSAndroid Build Coastguard Worker }
358*4d7e907cSAndroid Build Coastguard Worker
359*4d7e907cSAndroid Build Coastguard Worker return d->requestStreamBuffers(num_buffer_reqs, buffer_reqs,
360*4d7e907cSAndroid Build Coastguard Worker num_returned_buf_reqs, returned_buf_reqs);
361*4d7e907cSAndroid Build Coastguard Worker }
362*4d7e907cSAndroid Build Coastguard Worker
sReturnStreamBuffers(const struct camera3_callback_ops * cb,uint32_t num_buffers,const camera3_stream_buffer_t * const * buffers)363*4d7e907cSAndroid Build Coastguard Worker void CameraDeviceSession::sReturnStreamBuffers(
364*4d7e907cSAndroid Build Coastguard Worker const struct camera3_callback_ops *cb,
365*4d7e907cSAndroid Build Coastguard Worker uint32_t num_buffers,
366*4d7e907cSAndroid Build Coastguard Worker const camera3_stream_buffer_t* const* buffers) {
367*4d7e907cSAndroid Build Coastguard Worker CameraDeviceSession *d =
368*4d7e907cSAndroid Build Coastguard Worker const_cast<CameraDeviceSession*>(static_cast<const CameraDeviceSession*>(cb));
369*4d7e907cSAndroid Build Coastguard Worker
370*4d7e907cSAndroid Build Coastguard Worker d->returnStreamBuffers(num_buffers, buffers);
371*4d7e907cSAndroid Build Coastguard Worker }
372*4d7e907cSAndroid Build Coastguard Worker
isReconfigurationRequired(const V3_2::CameraMetadata & oldSessionParams,const V3_2::CameraMetadata & newSessionParams,ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb)373*4d7e907cSAndroid Build Coastguard Worker Return<void> CameraDeviceSession::isReconfigurationRequired(
374*4d7e907cSAndroid Build Coastguard Worker const V3_2::CameraMetadata& oldSessionParams, const V3_2::CameraMetadata& newSessionParams,
375*4d7e907cSAndroid Build Coastguard Worker ICameraDeviceSession::isReconfigurationRequired_cb _hidl_cb) {
376*4d7e907cSAndroid Build Coastguard Worker if (mDevice->ops->is_reconfiguration_required != nullptr) {
377*4d7e907cSAndroid Build Coastguard Worker const camera_metadata_t *oldParams, *newParams;
378*4d7e907cSAndroid Build Coastguard Worker V3_2::implementation::convertFromHidl(oldSessionParams, &oldParams);
379*4d7e907cSAndroid Build Coastguard Worker V3_2::implementation::convertFromHidl(newSessionParams, &newParams);
380*4d7e907cSAndroid Build Coastguard Worker auto ret = mDevice->ops->is_reconfiguration_required(mDevice, oldParams, newParams);
381*4d7e907cSAndroid Build Coastguard Worker switch (ret) {
382*4d7e907cSAndroid Build Coastguard Worker case 0:
383*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::OK, true);
384*4d7e907cSAndroid Build Coastguard Worker break;
385*4d7e907cSAndroid Build Coastguard Worker case -EINVAL:
386*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::OK, false);
387*4d7e907cSAndroid Build Coastguard Worker break;
388*4d7e907cSAndroid Build Coastguard Worker case -ENOSYS:
389*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::METHOD_NOT_SUPPORTED, true);
390*4d7e907cSAndroid Build Coastguard Worker break;
391*4d7e907cSAndroid Build Coastguard Worker default:
392*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::INTERNAL_ERROR, true);
393*4d7e907cSAndroid Build Coastguard Worker break;
394*4d7e907cSAndroid Build Coastguard Worker };
395*4d7e907cSAndroid Build Coastguard Worker } else {
396*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::METHOD_NOT_SUPPORTED, true);
397*4d7e907cSAndroid Build Coastguard Worker }
398*4d7e907cSAndroid Build Coastguard Worker
399*4d7e907cSAndroid Build Coastguard Worker return Void();
400*4d7e907cSAndroid Build Coastguard Worker }
401*4d7e907cSAndroid Build Coastguard Worker
402*4d7e907cSAndroid Build Coastguard Worker } // namespace implementation
403*4d7e907cSAndroid Build Coastguard Worker } // namespace V3_5
404*4d7e907cSAndroid Build Coastguard Worker } // namespace device
405*4d7e907cSAndroid Build Coastguard Worker } // namespace camera
406*4d7e907cSAndroid Build Coastguard Worker } // namespace hardware
407*4d7e907cSAndroid Build Coastguard Worker } // namespace android
408