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