Camera: Add isSessionConfigurationSupported in NDK/VNDK

Test: NativeCameraDeviceTest and AImageReaderVendorTest
Bug: 128933069
Change-Id: I26ca4c0ca12f7bd1b872c2f33e8fa63a056ae068
gugelfrei
Shuzhen Wang 5 years ago
parent 8f922e189d
commit 24810e7a67

@ -287,3 +287,16 @@ camera_status_t ACameraDevice_createCaptureSessionWithSessionParameters(
}
return device->createCaptureSession(outputs, sessionParameters, callbacks, session);
}
EXPORT
camera_status_t ACameraDevice_isSessionConfigurationSupported(
const ACameraDevice* device,
const ACaptureSessionOutputContainer* sessionOutputContainer) {
ATRACE_CALL();
if (device == nullptr || sessionOutputContainer == nullptr) {
ALOGE("%s: Error: invalid input: device %p, sessionOutputContainer %p",
__FUNCTION__, device, sessionOutputContainer);
return ACAMERA_ERROR_INVALID_PARAMETER;
}
return device->isSessionConfigurationSupported(sessionOutputContainer);
}

@ -227,6 +227,55 @@ CameraDevice::createCaptureSession(
return ACAMERA_OK;
}
camera_status_t CameraDevice::isSessionConfigurationSupported(
const ACaptureSessionOutputContainer* sessionOutputContainer) const {
Mutex::Autolock _l(mDeviceLock);
camera_status_t ret = checkCameraClosedOrErrorLocked();
if (ret != ACAMERA_OK) {
return ret;
}
SessionConfiguration sessionConfiguration(0 /*inputWidth*/, 0 /*inputHeight*/,
-1 /*inputFormat*/, CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE);
for (const auto& output : sessionOutputContainer->mOutputs) {
sp<IGraphicBufferProducer> iGBP(nullptr);
ret = getIGBPfromAnw(output.mWindow, iGBP);
if (ret != ACAMERA_OK) {
ALOGE("Camera device %s failed to extract graphic producer from native window",
getId());
return ret;
}
String16 physicalId16(output.mPhysicalCameraId.c_str());
OutputConfiguration outConfig(iGBP, output.mRotation, physicalId16,
OutputConfiguration::INVALID_SET_ID, true);
for (auto& anw : output.mSharedWindows) {
ret = getIGBPfromAnw(anw, iGBP);
if (ret != ACAMERA_OK) {
ALOGE("Camera device %s failed to extract graphic producer from native window",
getId());
return ret;
}
outConfig.addGraphicProducer(iGBP);
}
sessionConfiguration.addOutputConfiguration(outConfig);
}
bool supported = false;
binder::Status remoteRet = mRemote->isSessionConfigurationSupported(
sessionConfiguration, &supported);
if (remoteRet.serviceSpecificErrorCode() ==
hardware::ICameraService::ERROR_INVALID_OPERATION) {
return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
} else if (!remoteRet.isOk()) {
return ACAMERA_ERROR_UNKNOWN;
} else {
return supported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
}
}
camera_status_t CameraDevice::updateOutputConfigurationLocked(ACaptureSessionOutput *output) {
camera_status_t ret = checkCameraClosedOrErrorLocked();
if (ret != ACAMERA_OK) {

@ -35,6 +35,7 @@
#include <media/stagefright/foundation/AMessage.h>
#include <camera/CaptureResult.h>
#include <camera/camera2/OutputConfiguration.h>
#include <camera/camera2/SessionConfiguration.h>
#include <camera/camera2/CaptureRequest.h>
#include <camera/NdkCameraManager.h>
@ -77,6 +78,9 @@ class CameraDevice final : public RefBase {
const ACameraCaptureSession_stateCallbacks* callbacks,
/*out*/ACameraCaptureSession** session);
camera_status_t isSessionConfigurationSupported(
const ACaptureSessionOutputContainer* sessionOutputContainer) const;
// Callbacks from camera service
class ServiceCallback : public hardware::camera2::BnCameraDeviceCallbacks {
public:
@ -369,6 +373,11 @@ struct ACameraDevice {
return mDevice->createCaptureSession(outputs, sessionParameters, callbacks, session);
}
camera_status_t isSessionConfigurationSupported(
const ACaptureSessionOutputContainer* sessionOutputContainer) const {
return mDevice->isSessionConfigurationSupported(sessionOutputContainer);
}
/***********************
* Device interal APIs *
***********************/

@ -845,6 +845,43 @@ camera_status_t ACameraDevice_createCaptureRequest_withPhysicalIds(
const ACameraIdList* physicalIdList,
/*out*/ACaptureRequest** request) __INTRODUCED_IN(29);
/**
* Check whether a particular {@ACaptureSessionOutputContainer} is supported by
* the camera device.
*
* <p>This method performs a runtime check of a given {@link
* ACaptureSessionOutputContainer}. The result confirms whether or not the
* passed CaptureSession outputs can be successfully used to create a camera
* capture session using {@link ACameraDevice_createCaptureSession}.</p>
*
* <p>This method can be called at any point before, during and after active
* capture session. It must not impact normal camera behavior in any way and
* must complete significantly faster than creating a capture session.</p>
*
* <p>Although this method is faster than creating a new capture session, it is not intended
* to be used for exploring the entire space of supported stream combinations.</p>
*
* @param device the camera device of interest
* @param sessionOutputContainer the {@link ACaptureSessionOutputContainer} of
* interest.
*
* @return <ul>
* <li>{@link ACAMERA_OK} if the given {@link ACaptureSessionOutputContainer}
* is supported by the camera device.</li>
* <li>{@link ACAMERA_ERROR_INVALID_PARAMETER} if device, or sessionOutputContainer
* is NULL.</li>
* <li>{@link ACAMERA_ERROR_STREAM_CONFIGURE_FAIL} if the given
* {@link ACaptureSessionOutputContainer}
* is not supported by
* the camera
* device.</li>
* <li>{@link ACAMERA_ERROR_UNSUPPORTED_OPERATION} if the query operation is not
* supported by the camera device.</li>
*/
camera_status_t ACameraDevice_isSessionConfigurationSupported(
const ACameraDevice* device,
const ACaptureSessionOutputContainer* sessionOutputContainer) __INTRODUCED_IN(29);
#endif /* __ANDROID_API__ >= 29 */
__END_DECLS

@ -106,7 +106,8 @@ typedef enum {
/**
* Camera device does not support the stream configuration provided by application in
* {@link ACameraDevice_createCaptureSession}.
* {@link ACameraDevice_createCaptureSession} or {@link
* ACameraDevice_isSessionConfigurationSupported}.
*/
ACAMERA_ERROR_STREAM_CONFIGURE_FAIL = ACAMERA_ERROR_BASE - 9,
@ -130,6 +131,11 @@ typedef enum {
* The application does not have permission to open camera.
*/
ACAMERA_ERROR_PERMISSION_DENIED = ACAMERA_ERROR_BASE - 13,
/**
* The operation is not supported by the camera device.
*/
ACAMERA_ERROR_UNSUPPORTED_OPERATION = ACAMERA_ERROR_BASE - 14,
} camera_status_t;
#endif /* __ANDROID_API__ >= 24 */

@ -14,6 +14,7 @@ LIBCAMERA2NDK {
ACameraDevice_createCaptureRequest_withPhysicalIds; # introduced=29
ACameraDevice_createCaptureSession;
ACameraDevice_createCaptureSessionWithSessionParameters; # introduced=28
ACameraDevice_isSessionConfigurationSupported; # introduced=29
ACameraDevice_getId;
ACameraManager_create;
ACameraManager_delete;

@ -38,6 +38,7 @@ namespace acam {
using HCameraMetadata = frameworks::cameraservice::device::V2_0::CameraMetadata;
using OutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
using SessionConfiguration = frameworks::cameraservice::device::V2_0::SessionConfiguration;
using hardware::Void;
// Static member definitions
@ -216,6 +217,47 @@ CameraDevice::createCaptureSession(
return ACAMERA_OK;
}
camera_status_t CameraDevice::isSessionConfigurationSupported(
const ACaptureSessionOutputContainer* sessionOutputContainer) const {
Mutex::Autolock _l(mDeviceLock);
camera_status_t ret = checkCameraClosedOrErrorLocked();
if (ret != ACAMERA_OK) {
return ret;
}
SessionConfiguration sessionConfig;
sessionConfig.inputWidth = 0;
sessionConfig.inputHeight = 0;
sessionConfig.inputFormat = -1;
sessionConfig.operationMode = StreamConfigurationMode::NORMAL_MODE;
sessionConfig.outputStreams.resize(sessionOutputContainer->mOutputs.size());
size_t index = 0;
for (const auto& output : sessionOutputContainer->mOutputs) {
sessionConfig.outputStreams[index].rotation = utils::convertToHidl(output.mRotation);
sessionConfig.outputStreams[index].windowGroupId = -1;
sessionConfig.outputStreams[index].windowHandles.resize(output.mSharedWindows.size() + 1);
sessionConfig.outputStreams[index].windowHandles[0] = output.mWindow;
sessionConfig.outputStreams[index].physicalCameraId = output.mPhysicalCameraId;
index++;
}
bool configSupported = false;
Status status = Status::NO_ERROR;
auto remoteRet = mRemote->isSessionConfigurationSupported(sessionConfig,
[&status, &configSupported](auto s, auto supported) {
status = s;
configSupported = supported;
});
if (status == Status::INVALID_OPERATION) {
return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
} else if (!remoteRet.isOk()) {
return ACAMERA_ERROR_UNKNOWN;
} else {
return configSupported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
}
}
void CameraDevice::addRequestSettingsMetadata(ACaptureRequest *aCaptureRequest,
sp<CaptureRequest> &req) {
CameraMetadata metadataCopy = aCaptureRequest->settings->getInternalData();

@ -101,6 +101,9 @@ class CameraDevice final : public RefBase {
const ACameraCaptureSession_stateCallbacks* callbacks,
/*out*/ACameraCaptureSession** session);
camera_status_t isSessionConfigurationSupported(
const ACaptureSessionOutputContainer* sessionOutputContainer) const;
// Callbacks from camera service
class ServiceCallback : public ICameraDeviceCallback {
public:
@ -397,6 +400,11 @@ struct ACameraDevice {
return mDevice->createCaptureSession(outputs, sessionParameters, callbacks, session);
}
camera_status_t isSessionConfigurationSupported(
const ACaptureSessionOutputContainer* sessionOutputContainer) const {
return mDevice->isSessionConfigurationSupported(sessionOutputContainer);
}
/***********************
* Device interal APIs *
***********************/

@ -121,6 +121,12 @@ class CameraHelper {
cameraIdList.numCameras = idPointerList.size();
cameraIdList.cameraIds = idPointerList.data();
ret = ACameraDevice_isSessionConfigurationSupported(mDevice, mOutputs);
if (ret != ACAMERA_OK && ret != ACAMERA_ERROR_UNSUPPORTED_OPERATION) {
ALOGE("ACameraDevice_isSessionConfigurationSupported failed, ret=%d", ret);
return ret;
}
ret = ACameraDevice_createCaptureSession(mDevice, mOutputs, &mSessionCb, &mSession);
if (ret != AMEDIA_OK) {
ALOGE("ACameraDevice_createCaptureSession failed, ret=%d", ret);

@ -97,6 +97,21 @@ hardware::camera2::params::OutputConfiguration convertFromHidl(
return outputConfiguration;
}
hardware::camera2::params::SessionConfiguration convertFromHidl(
const HSessionConfiguration &hSessionConfiguration) {
hardware::camera2::params::SessionConfiguration sessionConfig(
hSessionConfiguration.inputWidth, hSessionConfiguration.inputHeight,
hSessionConfiguration.inputFormat,
static_cast<int>(hSessionConfiguration.operationMode));
for (const auto& hConfig : hSessionConfiguration.outputStreams) {
hardware::camera2::params::OutputConfiguration config = convertFromHidl(hConfig);
sessionConfig.addOutputConfiguration(config);
}
return sessionConfig;
}
// The camera metadata here is cloned. Since we're reading metadata over
// hwbinder we would need to clone it in order to avoid aligment issues.
bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst) {

@ -53,6 +53,7 @@ using HGraphicBufferProducer = hardware::graphics::bufferqueue::V1_0::IGraphicBu
using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
using HPhysicalCaptureResultInfo = frameworks::cameraservice::device::V2_0::PhysicalCaptureResultInfo;
using HSessionConfiguration = frameworks::cameraservice::device::V2_0::SessionConfiguration;
using HSubmitInfo = frameworks::cameraservice::device::V2_0::SubmitInfo;
using HStatus = frameworks::cameraservice::common::V2_0::Status;
using HStreamConfigurationMode = frameworks::cameraservice::device::V2_0::StreamConfigurationMode;
@ -70,6 +71,9 @@ bool convertFromHidl(const HCameraMetadata &src, CameraMetadata *dst);
hardware::camera2::params::OutputConfiguration convertFromHidl(
const HOutputConfiguration &hOutputConfiguration);
hardware::camera2::params::SessionConfiguration convertFromHidl(
const HSessionConfiguration &hSessionConfiguration);
HCameraDeviceStatus convertToHidlCameraDeviceStatus(int32_t status);
void convertToHidl(const std::vector<hardware::CameraStatus> &src,

@ -41,6 +41,7 @@ using hardware::Return;
using hardware::Void;
using HSubmitInfo = device::V2_0::SubmitInfo;
using hardware::camera2::params::OutputConfiguration;
using hardware::camera2::params::SessionConfiguration;
static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
@ -255,6 +256,18 @@ Return<HStatus> HidlCameraDeviceUser::updateOutputConfiguration(
return B2HStatus(ret);
}
Return<void> HidlCameraDeviceUser::isSessionConfigurationSupported(
const HSessionConfiguration& hSessionConfiguration,
isSessionConfigurationSupported_cb _hidl_cb) {
bool supported = false;
SessionConfiguration sessionConfiguration = convertFromHidl(hSessionConfiguration);
binder::Status ret = mDeviceRemote->isSessionConfigurationSupported(
sessionConfiguration, &supported);
HStatus status = B2HStatus(ret);
_hidl_cb(status, supported);
return Void();
}
} // implementation
} // V2_0
} // device

@ -53,6 +53,7 @@ using TemplateId = frameworks::cameraservice::device::V2_0::TemplateId;
using HCameraDeviceUser = device::V2_0::ICameraDeviceUser;
using HCameraMetadata = cameraservice::service::V2_0::CameraMetadata;
using HCaptureRequest = device::V2_0::CaptureRequest;
using HSessionConfiguration = frameworks::cameraservice::device::V2_0::SessionConfiguration;
using HOutputConfiguration = frameworks::cameraservice::device::V2_0::OutputConfiguration;
using HPhysicalCameraSettings = frameworks::cameraservice::device::V2_0::PhysicalCameraSettings;
using HStatus = frameworks::cameraservice::common::V2_0::Status;
@ -97,6 +98,10 @@ struct HidlCameraDeviceUser final : public HCameraDeviceUser {
virtual Return<HStatus> updateOutputConfiguration(
int32_t streamId, const HOutputConfiguration& outputConfiguration) override;
virtual Return<void> isSessionConfigurationSupported(
const HSessionConfiguration& sessionConfiguration,
isSessionConfigurationSupported_cb _hidl_cb) override;
bool initStatus() { return mInitSuccess; }
std::shared_ptr<CaptureResultMetadataQueue> getCaptureResultMetadataQueue() {

Loading…
Cancel
Save