Home | History | Annotate | Download | only in default
      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 (at) 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 
     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 
     62 CameraDeviceSession::~CameraDeviceSession() {
     63 }
     64 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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  */
    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 
    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 
    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