Camera: Allow streaming requests with individual physical settings

Streaming capture requests which include individual physical
device settings should not be blocked.

Bug: 72524845
Test: Camera CTS

Change-Id: Idb3ad9d022d4e2b2ced2558d1746866dbd3842b4
gugelfrei
Emilian Peev 7 years ago
parent bd60b9556c
commit 00420d2aa4

@ -28,6 +28,8 @@
#include "common/CameraDeviceBase.h"
#include "api2/CameraDeviceClient.h"
#include <camera_metadata_hidden.h>
// Convenience methods for constructing binder::Status objects for error returns
#define STATUS_ERROR(errorCode, errorString) \
@ -106,6 +108,15 @@ status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {
/*listener*/this,
/*sendPartials*/true);
auto deviceInfo = mDevice->info();
camera_metadata_entry_t physicalKeysEntry = deviceInfo.find(
ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
if (physicalKeysEntry.count > 0) {
mSupportedPhysicalRequestKeys.insert(mSupportedPhysicalRequestKeys.begin(),
physicalKeysEntry.data.i32,
physicalKeysEntry.data.i32 + physicalKeysEntry.count);
}
return OK;
}
@ -291,6 +302,13 @@ binder::Status CameraDeviceClient::submitRequestList(
CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
for (const auto& it : request.mPhysicalCameraSettings) {
if (it.settings.isEmpty()) {
ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
__FUNCTION__, mCameraIdStr.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request settings are empty");
}
String8 physicalId(it.id.c_str());
if (physicalId != mDevice->getId()) {
auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(),
@ -301,24 +319,27 @@ binder::Status CameraDeviceClient::submitRequestList(
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Invalid physical camera id");
}
}
CameraMetadata metadata(it.settings);
if (metadata.isEmpty()) {
ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
__FUNCTION__, mCameraIdStr.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Request settings are empty");
if (!mSupportedPhysicalRequestKeys.empty()) {
// Filter out any unsupported physical request keys.
CameraMetadata filteredParams(mSupportedPhysicalRequestKeys.size());
camera_metadata_t *meta = const_cast<camera_metadata_t *>(
filteredParams.getAndLock());
set_camera_metadata_vendor_id(meta, mDevice->getVendorTagId());
filteredParams.unlock(meta);
for (const auto& keyIt : mSupportedPhysicalRequestKeys) {
camera_metadata_ro_entry entry = it.settings.find(keyIt);
if (entry.count > 0) {
filteredParams.update(entry);
}
}
physicalSettingsList.push_back({it.id, filteredParams});
}
} else {
physicalSettingsList.push_back({it.id, it.settings});
}
physicalSettingsList.push_back({it.id, metadata});
}
if (streaming && (physicalSettingsList.size() > 1)) {
ALOGE("%s: Camera %s: Individual physical camera settings are not supported in "
"streaming requests. Rejecting request.", __FUNCTION__, mCameraIdStr.string());
return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
"Streaming request contains individual physical requests");
}
if (!enforceRequestPermissions(physicalSettingsList.begin()->metadata)) {

@ -221,6 +221,8 @@ private:
static const int32_t FRAME_PROCESSOR_LISTENER_MIN_ID = 0;
static const int32_t FRAME_PROCESSOR_LISTENER_MAX_ID = 0x7fffffffL;
std::vector<int32_t> mSupportedPhysicalRequestKeys;
template<typename TProviderPtr>
status_t initializeImpl(TProviderPtr providerPtr);

@ -55,6 +55,11 @@ class CameraDeviceBase : public virtual RefBase {
*/
virtual const String8& getId() const = 0;
/**
* The device vendor tag ID
*/
virtual metadata_vendor_id_t getVendorTagId() const = 0;
virtual status_t initialize(sp<CameraProviderManager> manager) = 0;
virtual status_t disconnect() = 0;

@ -3864,21 +3864,27 @@ status_t Camera3Device::HalInterface::processBatchCaptureRequests(
if (hidlSession_3_4 != nullptr) {
captureRequests_3_4[i].physicalCameraSettings.resize(request->num_physcam_settings);
for (size_t j = 0; j < request->num_physcam_settings; j++) {
size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
settingsSize)) {
captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = settingsSize;
} else {
if (mRequestMetadataQueue != nullptr) {
ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
if (request->physcam_settings != nullptr) {
size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
settingsSize)) {
captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize =
settingsSize;
} else {
if (mRequestMetadataQueue != nullptr) {
ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
}
captureRequests_3_4[i].physicalCameraSettings[j].settings.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
request->physcam_settings[j])),
get_camera_metadata_size(request->physcam_settings[j]));
captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
}
captureRequests_3_4[i].physicalCameraSettings[j].settings.setToExternal(
reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
request->physcam_settings[j])),
get_camera_metadata_size(request->physcam_settings[j]));
} else {
captureRequests_3_4[i].physicalCameraSettings[j].fmqSettingsSize = 0u;
captureRequests_3_4[i].physicalCameraSettings[j].settings.resize(0);
}
captureRequests_3_4[i].physicalCameraSettings[j].physicalCameraId =
request->physcam_id[j];
@ -4716,7 +4722,8 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
mPrevTriggers = triggerCount;
// If the request is the same as last, or we had triggers last time
if (mPrevRequest != captureRequest || triggersMixedIn) {
bool newRequest = mPrevRequest != captureRequest || triggersMixedIn;
if (newRequest) {
/**
* HAL workaround:
* Insert a dummy trigger ID if a trigger is set but no trigger ID is
@ -4761,14 +4768,20 @@ status_t Camera3Device::RequestThread::prepareHalRequests() {
if (captureRequest->mSettingsList.size() > 1) {
halRequest->num_physcam_settings = captureRequest->mSettingsList.size() - 1;
halRequest->physcam_id = new const char* [halRequest->num_physcam_settings];
halRequest->physcam_settings =
new const camera_metadata* [halRequest->num_physcam_settings];
if (newRequest) {
halRequest->physcam_settings =
new const camera_metadata* [halRequest->num_physcam_settings];
} else {
halRequest->physcam_settings = nullptr;
}
auto it = ++captureRequest->mSettingsList.begin();
size_t i = 0;
for (; it != captureRequest->mSettingsList.end(); it++, i++) {
halRequest->physcam_id[i] = it->cameraId.c_str();
it->metadata.sort();
halRequest->physcam_settings[i] = it->metadata.getAndLock();
if (newRequest) {
it->metadata.sort();
halRequest->physcam_settings[i] = it->metadata.getAndLock();
}
}
}

@ -93,6 +93,8 @@ class Camera3Device :
const String8& getId() const override;
metadata_vendor_id_t getVendorTagId() const override { return mVendorTagId; }
// Transitions to idle state on success.
status_t initialize(sp<CameraProviderManager> manager) override;
status_t disconnect() override;

Loading…
Cancel
Save