Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8e3c419 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Camera: Enable physical camera setting in camera ndk/vndk"

parents 28da31bb 6c17e210
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -78,7 +78,34 @@ camera_status_t ACameraDevice_createCaptureRequest(
            ALOGE("%s: unknown template ID %d", __FUNCTION__, templateId);
            return ACAMERA_ERROR_INVALID_PARAMETER;
    }
    return device->createCaptureRequest(templateId, request);
    return device->createCaptureRequest(templateId, nullptr /*physicalIdList*/, request);
}

EXPORT
camera_status_t ACameraDevice_createCaptureRequest_withPhysicalIds(
        const ACameraDevice* device,
        ACameraDevice_request_template templateId,
        const ACameraIdList* physicalCameraIdList,
        ACaptureRequest** request) {
    ATRACE_CALL();
    if (device == nullptr || request == nullptr || physicalCameraIdList == nullptr) {
        ALOGE("%s: invalid argument! device %p request %p, physicalCameraIdList %p",
                __FUNCTION__, device, request, physicalCameraIdList);
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }
    switch (templateId) {
        case TEMPLATE_PREVIEW:
        case TEMPLATE_STILL_CAPTURE:
        case TEMPLATE_RECORD:
        case TEMPLATE_VIDEO_SNAPSHOT:
        case TEMPLATE_ZERO_SHUTTER_LAG:
        case TEMPLATE_MANUAL:
            break;
        default:
            ALOGE("%s: unknown template ID %d", __FUNCTION__, templateId);
            return ACAMERA_ERROR_INVALID_PARAMETER;
    }
    return device->createCaptureRequest(templateId, physicalCameraIdList, request);
}

EXPORT
+53 −0
Original line number Diff line number Diff line
@@ -97,6 +97,27 @@ camera_status_t ACaptureRequest_getConstEntry(
    return req->settings->getConstEntry(tag, entry);
}

EXPORT
camera_status_t ACaptureRequest_getConstEntry_physicalCamera(
        const ACaptureRequest* req, const char* physicalId,
        uint32_t tag, ACameraMetadata_const_entry* entry) {
    ATRACE_CALL();
    if (req == nullptr || entry == nullptr || physicalId == nullptr) {
        ALOGE("%s: invalid argument! req %p, tag 0x%x, entry %p, physicalId %p",
               __FUNCTION__, req, tag, entry, physicalId);
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }

    const auto& physicalSettings = req->physicalSettings.find(physicalId);
    if (physicalSettings == req->physicalSettings.end()) {
        ALOGE("%s: Failed to find metadata for physical camera id  %s",
                __FUNCTION__, physicalId);
        return ACAMERA_ERROR_INVALID_PARAMETER;
    }

    return physicalSettings->second->getConstEntry(tag, entry);
}

EXPORT
camera_status_t ACaptureRequest_getAllTags(
        const ACaptureRequest* req, /*out*/int32_t* numTags, /*out*/const uint32_t** tags) {
@@ -131,6 +152,34 @@ SET_ENTRY(rational,ACameraMetadata_rational)

#undef SET_ENTRY

#define SET_PHYSICAL_ENTRY(NAME,NDK_TYPE)                                               \
EXPORT                                                                                  \
camera_status_t ACaptureRequest_setEntry_physicalCamera_##NAME(                         \
        ACaptureRequest* req, const char* physicalId, uint32_t tag,                     \
        uint32_t count, const NDK_TYPE* data) {                                         \
    ATRACE_CALL();                                                                      \
    if (req == nullptr || (count > 0 && data == nullptr) || physicalId == nullptr) {    \
        ALOGE("%s: invalid argument! req %p, tag 0x%x, count %d, data 0x%p, physicalId %p", \
               __FUNCTION__, req, tag, count, data, physicalId);                        \
        return ACAMERA_ERROR_INVALID_PARAMETER;                                         \
    }                                                                                   \
    if (req->physicalSettings.find(physicalId) == req->physicalSettings.end()) {        \
        ALOGE("%s: Failed to find metadata for physical camera id %s",                  \
            __FUNCTION__, physicalId);                                                  \
      return ACAMERA_ERROR_INVALID_PARAMETER;                                           \
    }                                                                                   \
    return req->physicalSettings[physicalId]->update(tag, count, data);                 \
}

SET_PHYSICAL_ENTRY(u8,uint8_t)
SET_PHYSICAL_ENTRY(i32,int32_t)
SET_PHYSICAL_ENTRY(float,float)
SET_PHYSICAL_ENTRY(double,double)
SET_PHYSICAL_ENTRY(i64,int64_t)
SET_PHYSICAL_ENTRY(rational,ACameraMetadata_rational)

#undef SET_PHYSICAL_ENTRY

EXPORT
void ACaptureRequest_free(ACaptureRequest* request) {
    ATRACE_CALL();
@@ -138,6 +187,7 @@ void ACaptureRequest_free(ACaptureRequest* request) {
        return;
    }
    request->settings.clear();
    request->physicalSettings.clear();
    delete request->targets;
    delete request;
    return;
@@ -174,6 +224,9 @@ ACaptureRequest* ACaptureRequest_copy(const ACaptureRequest* src) {

    ACaptureRequest* pRequest = new ACaptureRequest();
    pRequest->settings = new ACameraMetadata(*(src->settings));
    for (const auto& entry : src->physicalSettings) {
        pRequest->physicalSettings[entry.first] = new ACameraMetadata(*(entry.second));
    }
    pRequest->targets  = new ACameraOutputTargets();
    *(pRequest->targets)  = *(src->targets);
    pRequest->context = src->context;
+60 −10
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ CameraDevice::CameraDevice(
                __FUNCTION__, strerror(-err), err);
        setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
    }
    mHandler = new CallbackHandler();
    mHandler = new CallbackHandler(id);
    mCbLooper->registerHandler(mHandler);

    const CameraMetadata& metadata = mChars->getInternalData();
@@ -97,6 +97,14 @@ CameraDevice::CameraDevice(
        mShadingMapSize[0] = entry.data.i32[0];
        mShadingMapSize[1] = entry.data.i32[1];
    }

    size_t physicalIdCnt = 0;
    const char*const* physicalCameraIds;
    if (mChars->isLogicalMultiCamera(&physicalIdCnt, &physicalCameraIds)) {
        for (size_t i = 0; i < physicalIdCnt; i++) {
            mPhysicalIds.push_back(physicalCameraIds[i]);
        }
    }
}

// Device close implementaiton
@@ -129,8 +137,29 @@ CameraDevice::postSessionMsgAndCleanup(sp<AMessage>& msg) {
camera_status_t
CameraDevice::createCaptureRequest(
        ACameraDevice_request_template templateId,
        const ACameraIdList* physicalIdList,
        ACaptureRequest** request) const {
    Mutex::Autolock _l(mDeviceLock);

    if (physicalIdList != nullptr) {
        if (physicalIdList->numCameras > static_cast<int>(mPhysicalIds.size())) {
            ALOGE("%s: physicalIdList size %d exceeds number of available physical cameras %zu",
                    __FUNCTION__, physicalIdList->numCameras, mPhysicalIds.size());
            return ACAMERA_ERROR_INVALID_PARAMETER;
        }
        for (auto i = 0; i < physicalIdList->numCameras; i++) {
            if (physicalIdList->cameraIds[i] == nullptr) {
                ALOGE("%s: physicalId is null!", __FUNCTION__);
                return ACAMERA_ERROR_INVALID_PARAMETER;
            }
            if (mPhysicalIds.end() == std::find(
                    mPhysicalIds.begin(), mPhysicalIds.end(), physicalIdList->cameraIds[i])) {
                ALOGE("%s: Invalid physicalId %s!", __FUNCTION__, physicalIdList->cameraIds[i]);
                return ACAMERA_ERROR_INVALID_PARAMETER;
            }
        }
    }

    camera_status_t ret = checkCameraClosedOrErrorLocked();
    if (ret != ACAMERA_OK) {
        return ret;
@@ -151,6 +180,12 @@ CameraDevice::createCaptureRequest(
    }
    ACaptureRequest* outReq = new ACaptureRequest();
    outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
    if (physicalIdList != nullptr) {
        for (auto i = 0; i < physicalIdList->numCameras; i++) {
            outReq->physicalSettings.emplace(physicalIdList->cameraIds[i],
                    new ACameraMetadata(*(outReq->settings)));
        }
    }
    outReq->targets  = new ACameraOutputTargets();
    *request = outReq;
    return ACAMERA_OK;
@@ -275,8 +310,12 @@ CameraDevice::allocateCaptureRequest(
        const ACaptureRequest* request, /*out*/sp<CaptureRequest>& outReq) {
    camera_status_t ret;
    sp<CaptureRequest> req(new CaptureRequest());
    req->mPhysicalCameraSettings.push_back({std::string(mCameraId.string()),
    req->mPhysicalCameraSettings.push_back({getId(),
            request->settings->getInternalData()});
    for (auto& entry : request->physicalSettings) {
        req->mPhysicalCameraSettings.push_back({entry.first,
                entry.second->getInternalData()});
    }
    req->mIsReprocess = false; // NDK does not support reprocessing yet
    req->mContext = request->context;
    req->mSurfaceConverted = true; // set to true, and fill in stream/surface idx to speed up IPC
@@ -320,10 +359,17 @@ CameraDevice::allocateCaptureRequest(
}

ACaptureRequest*
CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req) {
CameraDevice::allocateACaptureRequest(sp<CaptureRequest>& req, const std::string& deviceId) {
    ACaptureRequest* pRequest = new ACaptureRequest();
    CameraMetadata clone = req->mPhysicalCameraSettings.begin()->settings;
    for (auto& entry : req->mPhysicalCameraSettings) {
        CameraMetadata clone = entry.settings;
        if (entry.id == deviceId) {
            pRequest->settings = new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST);
        } else {
            pRequest->physicalSettings.emplace(entry.id,
                    new ACameraMetadata(clone.release(), ACameraMetadata::ACM_REQUEST));
        }
    }
    pRequest->targets  = new ACameraOutputTargets();
    for (size_t i = 0; i < req->mSurfaceList.size(); i++) {
        ANativeWindow* anw = static_cast<ANativeWindow*>(req->mSurfaceList[i].get());
@@ -340,6 +386,7 @@ CameraDevice::freeACaptureRequest(ACaptureRequest* req) {
        return;
    }
    req->settings.clear();
    req->physicalSettings.clear();
    delete req->targets;
    delete req;
}
@@ -786,6 +833,9 @@ CameraDevice::onCaptureErrorLocked(
    return;
}

CameraDevice::CallbackHandler::CallbackHandler(const char* id) : mId(id) {
}

void CameraDevice::CallbackHandler::onMessageReceived(
        const sp<AMessage> &msg) {
    switch (msg->what()) {
@@ -927,7 +977,7 @@ void CameraDevice::CallbackHandler::onMessageReceived(
                        ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
                        return;
                    }
                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                    (*onStart)(context, session.get(), request, timestamp);
                    freeACaptureRequest(request);
                    break;
@@ -950,7 +1000,7 @@ void CameraDevice::CallbackHandler::onMessageReceived(
                        return;
                    }
                    sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                    (*onResult)(context, session.get(), request, result.get());
                    freeACaptureRequest(request);
                    break;
@@ -1006,7 +1056,7 @@ void CameraDevice::CallbackHandler::onMessageReceived(
                        physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
                    }

                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                    (*onResult)(context, session.get(), request, result.get(),
                            physicalResultInfo.size(), physicalCameraIdPtrs.data(),
                            physicalMetadataCopyPtrs.data());
@@ -1034,7 +1084,7 @@ void CameraDevice::CallbackHandler::onMessageReceived(
                            static_cast<CameraCaptureFailure*>(obj.get()));
                    ACameraCaptureFailure* failure =
                            static_cast<ACameraCaptureFailure*>(failureSp.get());
                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                    (*onFail)(context, session.get(), request, failure);
                    freeACaptureRequest(request);
                    break;
@@ -1111,7 +1161,7 @@ void CameraDevice::CallbackHandler::onMessageReceived(
                        return;
                    }

                    ACaptureRequest* request = allocateACaptureRequest(requestSp);
                    ACaptureRequest* request = allocateACaptureRequest(requestSp, mId);
                    (*onBufferLost)(context, session.get(), request, anw, frameNumber);
                    freeACaptureRequest(request);
                    break;
+8 −2
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ class CameraDevice final : public RefBase {

    camera_status_t createCaptureRequest(
            ACameraDevice_request_template templateId,
            const ACameraIdList* physicalIdList,
            ACaptureRequest** request) const;

    camera_status_t createCaptureSession(
@@ -145,7 +146,8 @@ class CameraDevice final : public RefBase {
    camera_status_t allocateCaptureRequest(
            const ACaptureRequest* request, sp<CaptureRequest>& outReq);

    static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req);
    static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req,
            const std::string& deviceId);
    static void freeACaptureRequest(ACaptureRequest*);

    // only For session to hold device lock
@@ -230,9 +232,11 @@ class CameraDevice final : public RefBase {

    class CallbackHandler : public AHandler {
      public:
        explicit CallbackHandler(const char* id);
        void onMessageReceived(const sp<AMessage> &msg) override;

      private:
        std::string mId;
        // This handler will cache all capture session sp until kWhatCleanUpSessions
        // is processed. This is used to guarantee the last session reference is always
        // being removed in callback thread without holding camera device lock
@@ -327,6 +331,7 @@ class CameraDevice final : public RefBase {
    // Misc variables
    int32_t mShadingMapSize[2];   // const after constructor
    int32_t mPartialResultCount;  // const after constructor
    std::vector<std::string> mPhysicalIds; // const after constructor

};

@@ -351,8 +356,9 @@ struct ACameraDevice {

    camera_status_t createCaptureRequest(
            ACameraDevice_request_template templateId,
            const ACameraIdList* physicalCameraIdList,
            ACaptureRequest** request) const {
        return mDevice->createCaptureRequest(templateId, request);
        return mDevice->createCaptureRequest(templateId, physicalCameraIdList, request);
    }

    camera_status_t createCaptureSession(
+3 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <camera/NdkCaptureRequest.h>
#include <set>
#include <unordered_map>

using namespace android;

@@ -60,6 +61,7 @@ struct ACaptureRequest {
    }

    sp<ACameraMetadata> settings;
    std::unordered_map<std::string, sp<ACameraMetadata>> physicalSettings;
    ACameraOutputTargets* targets;
    void*                 context;
};
Loading