Merge "AudioFlinger: synchronize OutputTracks start on duplicating threads" into udc-dev
diff --git a/media/codec2/components/avc/C2SoftAvcEnc.cpp b/media/codec2/components/avc/C2SoftAvcEnc.cpp
index 9c054f0..e424860 100644
--- a/media/codec2/components/avc/C2SoftAvcEnc.cpp
+++ b/media/codec2/components/avc/C2SoftAvcEnc.cpp
@@ -334,7 +334,10 @@
// By default needsUpdate = false in case the supplied level does meet
// the requirements. For Level 1b, we want to update the level anyway,
// so we set it to true in that case.
- bool needsUpdate = (me.v.level == LEVEL_AVC_1B);
+ bool needsUpdate = false;
+ if (me.v.level == LEVEL_AVC_1B || !me.F(me.v.level).supportsAtAll(me.v.level)) {
+ needsUpdate = true;
+ }
for (const LevelLimits &limit : kLimits) {
if (mbs <= limit.mbs && mbsPerSec <= limit.mbsPerSec &&
bitrate.v.value <= limit.bitrate) {
diff --git a/media/codec2/components/hevc/C2SoftHevcEnc.cpp b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
index 56e6e8a..ec1dd14 100644
--- a/media/codec2/components/hevc/C2SoftHevcEnc.cpp
+++ b/media/codec2/components/hevc/C2SoftHevcEnc.cpp
@@ -341,6 +341,9 @@
// By default needsUpdate = false in case the supplied level does meet
// the requirements.
bool needsUpdate = false;
+ if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+ needsUpdate = true;
+ }
for (const LevelLimits &limit : kLimits) {
if (samples <= limit.samples && samplesPerSec <= limit.samplesPerSec &&
bitrate.v.value <= limit.bitrate) {
diff --git a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
index 703033b..acc42e9 100644
--- a/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
+++ b/media/codec2/components/mpeg4_h263/C2SoftMpeg4Enc.cpp
@@ -243,6 +243,9 @@
needsUpdate = true;
}
#endif
+ if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+ needsUpdate = true;
+ }
for (const LevelLimits &limit : kLimits) {
if (sampleRate <= limit.sampleRate && size.v.width <= limit.width &&
vbvSize <= limit.vbvSize && size.v.height <= limit.height &&
diff --git a/media/codec2/components/vpx/C2SoftVpxEnc.cpp b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
index 5700e5d..e903069 100644
--- a/media/codec2/components/vpx/C2SoftVpxEnc.cpp
+++ b/media/codec2/components/vpx/C2SoftVpxEnc.cpp
@@ -263,6 +263,9 @@
// By default needsUpdate = false in case the supplied level does meet
// the requirements.
bool needsUpdate = false;
+ if (!me.F(me.v.level).supportsAtAll(me.v.level)) {
+ needsUpdate = true;
+ }
for (const LevelLimits& limit : kLimits) {
if (samples <= limit.samples && samplesPerSec <= limit.samplesPerSec &&
bitrate.v.value <= limit.bitrate && dimension <= limit.dimension) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 3b29c57..da33b0d 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -2096,7 +2096,10 @@
// csd cannot be re-ordered and will always arrive first.
if (initData != nullptr) {
Mutexed<Output>::Locked output(mOutput);
- if (output->buffers && outputFormat) {
+ if (!output->buffers) {
+ return false;
+ }
+ if (outputFormat) {
output->buffers->updateSkipCutBuffer(outputFormat);
output->buffers->setFormat(outputFormat);
}
@@ -2105,7 +2108,7 @@
}
size_t index;
sp<MediaCodecBuffer> outBuffer;
- if (output->buffers && output->buffers->registerCsd(initData, &index, &outBuffer) == OK) {
+ if (output->buffers->registerCsd(initData, &index, &outBuffer) == OK) {
outBuffer->meta()->setInt64("timeUs", timestamp.peek());
outBuffer->meta()->setInt32("flags", BUFFER_FLAG_CODEC_CONFIG);
ALOGV("[%s] onWorkDone: csd index = %zu [%p]", mName, index, outBuffer.get());
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index d8219a8..f01b653 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1616,13 +1616,16 @@
}
AutoMutex lock(mLock);
+ // IAudioTrack::stop() isn't synchronous; we don't know when presentation completes
+ if (mState == STATE_STOPPED || mState == STATE_FLUSHED) {
+ *position = 0;
+ return NO_ERROR;
+ }
// FIXME: offloaded and direct tracks call into the HAL for render positions
// for compressed/synced data; however, we use proxy position for pure linear pcm data
// as we do not know the capability of the HAL for pcm position support and standby.
// There may be some latency differences between the HAL position and the proxy position.
if (isOffloadedOrDirect_l() && !isPurePcmData_l()) {
- uint32_t dspFrames = 0;
-
if (isOffloaded_l() && ((mState == STATE_PAUSED) || (mState == STATE_PAUSED_STOPPING))) {
ALOGV("%s(%d): called in paused state, return cached position %u",
__func__, mPortId, mPausedPosition);
@@ -1630,13 +1633,15 @@
return NO_ERROR;
}
+ uint32_t dspFrames = 0;
if (mOutput != AUDIO_IO_HANDLE_NONE) {
uint32_t halFrames; // actually unused
- (void) AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);
// FIXME: on getRenderPosition() error, we return OK with frame position 0.
+ if (AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames) != NO_ERROR) {
+ *position = 0;
+ return NO_ERROR;
+ }
}
- // FIXME: dspFrames may not be zero in (mState == STATE_STOPPED || mState == STATE_FLUSHED)
- // due to hardware latency. We leave this behavior for now.
*position = dspFrames;
} else {
if (mCblk->mFlags & CBLK_INVALID) {
@@ -1644,11 +1649,9 @@
// FIXME: for compatibility with the Java API we ignore the restoreTrack_l()
// error here (e.g. DEAD_OBJECT) and return OK with the last recorded server position.
}
-
- // IAudioTrack::stop() isn't synchronous; we don't know when presentation completes
- *position = (mState == STATE_STOPPED || mState == STATE_FLUSHED) ?
- 0 : updateAndGetPosition_l().value();
+ *position = updateAndGetPosition_l().value();
}
+
return NO_ERROR;
}
diff --git a/media/libaudioprocessing/AudioMixer.cpp b/media/libaudioprocessing/AudioMixer.cpp
index 6a39108..57b860d 100644
--- a/media/libaudioprocessing/AudioMixer.cpp
+++ b/media/libaudioprocessing/AudioMixer.cpp
@@ -193,7 +193,7 @@
// See if we should use our built-in non-effect downmixer.
if (mMixerInFormat == AUDIO_FORMAT_PCM_FLOAT
- && mMixerChannelMask == AUDIO_CHANNEL_OUT_STEREO
+ && ChannelMixBufferProvider::isOutputChannelMaskSupported(mMixerChannelMask)
&& audio_channel_mask_get_representation(channelMask)
== AUDIO_CHANNEL_REPRESENTATION_POSITION) {
mDownmixerBufferProvider.reset(new ChannelMixBufferProvider(channelMask,
diff --git a/media/libaudioprocessing/BufferProviders.cpp b/media/libaudioprocessing/BufferProviders.cpp
index a9944fb..9f19f7b 100644
--- a/media/libaudioprocessing/BufferProviders.cpp
+++ b/media/libaudioprocessing/BufferProviders.cpp
@@ -373,18 +373,23 @@
audio_bytes_per_sample(format)
* audio_channel_count_from_out_mask(outputChannelMask),
bufferFrameCount)
+ , mChannelMix{format == AUDIO_FORMAT_PCM_FLOAT
+ ? audio_utils::channels::IChannelMix::create(outputChannelMask) : nullptr}
+ , mIsValid{mChannelMix && mChannelMix->setInputChannelMask(inputChannelMask)}
{
ALOGV("ChannelMixBufferProvider(%p)(%#x, %#x, %#x)",
this, format, inputChannelMask, outputChannelMask);
- if (outputChannelMask == AUDIO_CHANNEL_OUT_STEREO && format == AUDIO_FORMAT_PCM_FLOAT) {
- mIsValid = mChannelMix.setInputChannelMask(inputChannelMask);
- }
}
void ChannelMixBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
{
- mChannelMix.process(static_cast<const float *>(src), static_cast<float *>(dst),
- frames, false /* accumulate */);
+ if (mIsValid) {
+ mChannelMix->process(static_cast<const float *>(src), static_cast<float *>(dst),
+ frames, false /* accumulate */);
+ } else {
+ // Should fall back to a different BufferProvider if not valid.
+ ALOGE("%s: Use without being valid!", __func__);
+ }
}
ReformatBufferProvider::ReformatBufferProvider(int32_t channelCount,
diff --git a/media/libaudioprocessing/include/media/BufferProviders.h b/media/libaudioprocessing/include/media/BufferProviders.h
index a0b025f..8d18010 100644
--- a/media/libaudioprocessing/include/media/BufferProviders.h
+++ b/media/libaudioprocessing/include/media/BufferProviders.h
@@ -142,9 +142,14 @@
bool isValid() const { return mIsValid; }
+ static bool isOutputChannelMaskSupported(audio_channel_mask_t outputChannelMask) {
+ return audio_utils::channels::IChannelMix::isOutputChannelMaskSupported(
+ outputChannelMask);
+ }
+
protected:
- audio_utils::channels::ChannelMix<AUDIO_CHANNEL_OUT_STEREO> mChannelMix;
- bool mIsValid = false;
+ const std::shared_ptr<audio_utils::channels::IChannelMix> mChannelMix;
+ const bool mIsValid;
};
// RemixBufferProvider derives from CopyBufferProvider to perform an
diff --git a/media/libeffects/downmix/EffectDownmix.cpp b/media/libeffects/downmix/EffectDownmix.cpp
index 7f8455a..b921537 100644
--- a/media/libeffects/downmix/EffectDownmix.cpp
+++ b/media/libeffects/downmix/EffectDownmix.cpp
@@ -259,7 +259,7 @@
ret = Downmix_Init(module);
if (ret < 0) {
ALOGW("DownmixLib_Create() init failed");
- free(module);
+ delete module;
return ret;
}
@@ -582,7 +582,7 @@
ALOGV("Downmix_Init module %p", pDwmModule);
int ret = 0;
- memset(&pDwmModule->context, 0, sizeof(downmix_object_t));
+ pDwmModule->context = downmix_object_t{}; // zero initialize (contains class with vtable).
pDwmModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
pDwmModule->config.inputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 6a2d59c..2d33d3c 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6555,7 +6555,8 @@
mFlushPending = true;
}
} else /* mType == OFFLOAD */ {
- if (previousTrack->sessionId() != latestTrack->sessionId()) {
+ if (previousTrack->sessionId() != latestTrack->sessionId() ||
+ previousTrack->isFlushPending()) {
mFlushPending = true;
}
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 1564ff3..a2aafdf 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -2159,6 +2159,7 @@
client->setImageDumpMask(mImageDumpMask);
client->setStreamUseCaseOverrides(mStreamUseCaseOverrides);
+ client->setZoomOverride(mZoomOverrideValue);
} // lock is destroyed, allow further connect calls
// Important: release the mutex here so the client can call back into the service from its
@@ -5123,6 +5124,8 @@
} else if (args.size() >= 1 && args[0] == String16("clear-stream-use-case-override")) {
handleClearStreamUseCaseOverrides();
return OK;
+ } else if (args.size() >= 1 && args[0] == String16("set-zoom-override")) {
+ return handleSetZoomOverride(args);
} else if (args.size() >= 2 && args[0] == String16("watch")) {
return handleWatchCommand(args, in, out);
} else if (args.size() >= 2 && args[0] == String16("set-watchdog")) {
@@ -5366,6 +5369,34 @@
mStreamUseCaseOverrides.clear();
}
+status_t CameraService::handleSetZoomOverride(const Vector<String16>& args) {
+ char* end;
+ int zoomOverrideValue = strtol(String8(args[1]), &end, /*base=*/10);
+ if ((*end != '\0') ||
+ (zoomOverrideValue != -1 &&
+ zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF &&
+ zoomOverrideValue != ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM)) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mServiceLock);
+ mZoomOverrideValue = zoomOverrideValue;
+
+ const auto clients = mActiveClientManager.getAll();
+ for (auto& current : clients) {
+ if (current != nullptr) {
+ const auto basicClient = current->getValue();
+ if (basicClient.get() != nullptr) {
+ if (basicClient->supportsZoomOverride()) {
+ basicClient->setZoomOverride(mZoomOverrideValue);
+ }
+ }
+ }
+ }
+
+ return OK;
+}
+
status_t CameraService::handleWatchCommand(const Vector<String16>& args, int inFd, int outFd) {
if (args.size() >= 3 && args[1] == String16("start")) {
return startWatchingTags(args, outFd);
@@ -5732,6 +5763,8 @@
" Valid values are (case sensitive): DEFAULT, PREVIEW, STILL_CAPTURE, VIDEO_RECORD,\n"
" PREVIEW_VIDEO_STILL, VIDEO_CALL, CROPPED_RAW\n"
" clear-stream-use-case-override clear the stream use case override\n"
+ " set-zoom-override <-1/0/1> enable or disable zoom override\n"
+ " Valid values -1: do not override, 0: override to OFF, 1: override to ZOOM\n"
" watch <start|stop|dump|print|clear> manages tag monitoring in connected clients\n"
" help print this message\n");
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index d8b14d7..ecec15f 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -371,6 +371,12 @@
// Clear stream use case overrides
virtual void clearStreamUseCaseOverrides() = 0;
+ // Whether the client supports camera zoom override
+ virtual bool supportsZoomOverride() = 0;
+
+ // Set/reset zoom override
+ virtual status_t setZoomOverride(int32_t zoomOverride) = 0;
+
// The injection camera session to replace the internal camera
// session.
virtual status_t injectCamera(const String8& injectedCamId,
@@ -1306,6 +1312,9 @@
// Clear the stream use case overrides
void handleClearStreamUseCaseOverrides();
+ // Set or clear the zoom override flag
+ status_t handleSetZoomOverride(const Vector<String16>& args);
+
// Handle 'watch' command as passed through 'cmd'
status_t handleWatchCommand(const Vector<String16> &args, int inFd, int outFd);
@@ -1408,6 +1417,9 @@
// Current stream use case overrides
std::vector<int64_t> mStreamUseCaseOverrides;
+ // Current zoom override value
+ int32_t mZoomOverrideValue = -1;
+
/**
* A listener class that implements the IBinder::DeathRecipient interface
* for use to call back the error state injected by the external camera, and
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index d71462f..06ef88a 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -2391,6 +2391,14 @@
mDevice->clearStreamUseCaseOverrides();
}
+bool Camera2Client::supportsZoomOverride() {
+ return mDevice->supportsZoomOverride();
+}
+
+status_t Camera2Client::setZoomOverride(int zoomOverride) {
+ return mDevice->setZoomOverride(zoomOverride);
+}
+
status_t Camera2Client::waitUntilCurrentRequestIdLocked() {
int32_t activeRequestId = mStreamingProcessor->getActiveRequestId();
if (activeRequestId != 0) {
diff --git a/services/camera/libcameraservice/api1/Camera2Client.h b/services/camera/libcameraservice/api1/Camera2Client.h
index 6d7651f..6bdb644 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.h
+++ b/services/camera/libcameraservice/api1/Camera2Client.h
@@ -97,6 +97,9 @@
const std::vector<int64_t>& useCaseOverrides);
virtual void clearStreamUseCaseOverrides();
+ virtual bool supportsZoomOverride();
+ virtual status_t setZoomOverride(int32_t zoomOverride);
+
/**
* Interface used by CameraService
*/
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 55b0f03..fda6af3 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1789,6 +1789,14 @@
mDevice->clearStreamUseCaseOverrides();
}
+bool CameraDeviceClient::supportsZoomOverride() {
+ return mDevice->supportsZoomOverride();
+}
+
+status_t CameraDeviceClient::setZoomOverride(int32_t zoomOverride) {
+ return mDevice->setZoomOverride(zoomOverride);
+}
+
binder::Status CameraDeviceClient::switchToOffline(
const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
const std::vector<int>& offlineOutputIds,
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index c6688a5..1533cf5 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -204,6 +204,9 @@
virtual bool supportsCameraMute();
virtual status_t setCameraMute(bool enabled);
+ virtual bool supportsZoomOverride() override;
+ virtual status_t setZoomOverride(int32_t zoomOverride) override;
+
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t dumpClient(int fd, const Vector<String16>& args);
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
index 29d7e6f..66077c5 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.cpp
@@ -106,6 +106,14 @@
void CameraOfflineSessionClient::clearStreamUseCaseOverrides() {
}
+bool CameraOfflineSessionClient::supportsZoomOverride() {
+ return false;
+}
+
+status_t CameraOfflineSessionClient::setZoomOverride(int32_t /*zoomOverride*/) {
+ return INVALID_OPERATION;
+}
+
status_t CameraOfflineSessionClient::dump(int fd, const Vector<String16>& args) {
return BasicClient::dump(fd, args);
}
diff --git a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
index 906d454..ad763f9 100644
--- a/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
+++ b/services/camera/libcameraservice/api2/CameraOfflineSessionClient.h
@@ -94,6 +94,10 @@
void clearStreamUseCaseOverrides() override;
+ bool supportsZoomOverride() override;
+
+ status_t setZoomOverride(int32_t zoomOverride) override;
+
// permissions management
status_t startCameraOps() override;
status_t finishCameraOps() override;
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index fd80cc5..530b03e 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -128,6 +128,9 @@
int32_t mOriginalTestPatternMode = 0;
int32_t mOriginalTestPatternData[4] = {};
+ // Original value of SETTINGS_OVERRIDE so that they can be restored if
+ // camera service isn't overwriting the app value.
+ int32_t mOriginalSettingsOverride = ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF;
};
typedef List<PhysicalCameraSettings> PhysicalCameraSettingsList;
@@ -467,6 +470,14 @@
virtual status_t setCameraMute(bool enabled) = 0;
/**
+ * Whether the camera device supports zoom override.
+ */
+ virtual bool supportsZoomOverride() = 0;
+
+ // Set/reset zoom override
+ virtual status_t setZoomOverride(int32_t zoomOverride) = 0;
+
+ /**
* Enable/disable camera service watchdog
*/
virtual status_t setCameraServiceWatchdog(bool enabled) = 0;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 2ebb98a..b7c86c6 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -1110,7 +1110,7 @@
for (size_t i = 0; i < entry.count; i += 3) {
if (entry.data.i64[i] == profile) {
- if (entry.data.i64[i+1] & concurrentProfile) {
+ if ((entry.data.i64[i+1] == 0) || (entry.data.i64[i+1] & concurrentProfile)) {
return true;
}
}
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index a13b937..8ff5c3f 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -697,6 +697,11 @@
mTorchStrengthLevel = 0;
+ if (!kEnableLazyHal) {
+ // Save HAL reference indefinitely
+ mSavedInterface = interface;
+ }
+
queryPhysicalCameraIds();
// Get physical camera characteristics if applicable
@@ -757,13 +762,6 @@
}
}
}
-
- if (!kEnableLazyHal) {
- // Save HAL reference indefinitely
- mSavedInterface = interface;
- }
-
-
}
status_t HidlProviderInfo::HidlDeviceInfo3::setTorchMode(bool enabled) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 153e999..dcafd74 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -103,6 +103,7 @@
mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
mComposerOutput(false),
mAutoframingOverride(ANDROID_CONTROL_AUTOFRAMING_OFF),
+ mSettingsOverride(-1),
mActivePhysicalId("")
{
ATRACE_CALL();
@@ -172,10 +173,21 @@
}
}
+ camera_metadata_entry_t availableSettingsOverrides = mDeviceInfo.find(
+ ANDROID_CONTROL_AVAILABLE_SETTINGS_OVERRIDES);
+ for (size_t i = 0; i < availableSettingsOverrides.count; i++) {
+ if (availableSettingsOverrides.data.i32[i] ==
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_ZOOM) {
+ mSupportZoomOverride = true;
+ break;
+ }
+ }
+
/** Start up request queue thread */
mRequestThread = createNewRequestThread(
this, mStatusTracker, mInterface, sessionParamKeys,
- mUseHalBufManager, mSupportCameraMute, mOverrideToPortrait);
+ mUseHalBufManager, mSupportCameraMute, mOverrideToPortrait,
+ mSupportZoomOverride);
res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
if (res != OK) {
SET_ERR_L("Unable to start request queue thread: %s (%d)",
@@ -2232,6 +2244,16 @@
}
}
+ if (mSupportZoomOverride) {
+ for (auto& settings : newRequest->mSettingsList) {
+ auto settingsOverrideEntry =
+ settings.metadata.find(ANDROID_CONTROL_SETTINGS_OVERRIDE);
+ settings.mOriginalSettingsOverride = settingsOverrideEntry.count > 0 ?
+ settingsOverrideEntry.data.i32[0] :
+ ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF;
+ }
+ }
+
return newRequest;
}
@@ -2959,7 +2981,8 @@
sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait) :
+ bool overrideToPortrait,
+ bool supportSettingsOverride) :
Thread(/*canCallJava*/false),
mParent(parent),
mStatusTracker(statusTracker),
@@ -2981,6 +3004,7 @@
mComposerOutput(false),
mCameraMute(ANDROID_SENSOR_TEST_PATTERN_MODE_OFF),
mCameraMuteChanged(false),
+ mSettingsOverride(ANDROID_CONTROL_SETTINGS_OVERRIDE_OFF),
mRepeatingLastFrameNumber(
hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES),
mPrepareVideoStream(false),
@@ -2990,7 +3014,8 @@
mLatestSessionParams(sessionParamKeys.size()),
mUseHalBufManager(useHalBufManager),
mSupportCameraMute(supportCameraMute),
- mOverrideToPortrait(overrideToPortrait) {
+ mOverrideToPortrait(overrideToPortrait),
+ mSupportSettingsOverride(supportSettingsOverride) {
mStatusId = statusTracker->addComponent("RequestThread");
mVndkVersion = property_get_int32("ro.vndk.version", __ANDROID_API_FUTURE__);
}
@@ -3671,6 +3696,7 @@
mPrevTriggers = triggerCount;
bool testPatternChanged = overrideTestPattern(captureRequest);
+ bool settingsOverrideChanged = overrideSettingsOverride(captureRequest);
// If the request is the same as last, or we had triggers now or last time or
// changing overrides this time
@@ -3678,7 +3704,7 @@
(mPrevRequest != captureRequest || triggersMixedIn ||
captureRequest->mRotateAndCropChanged ||
captureRequest->mAutoframingChanged ||
- testPatternChanged) &&
+ testPatternChanged || settingsOverrideChanged) &&
// Request settings are all the same within one batch, so only treat the first
// request in a batch as new
!(batchedRequest && i > 0);
@@ -4182,6 +4208,13 @@
return OK;
}
+status_t Camera3Device::RequestThread::setZoomOverride(int32_t zoomOverride) {
+ ATRACE_CALL();
+ Mutex::Autolock l(mTriggerMutex);
+ mSettingsOverride = zoomOverride;
+ return OK;
+}
+
nsecs_t Camera3Device::getExpectedInFlightDuration() {
ATRACE_CALL();
std::lock_guard<std::mutex> l(mInFlightLock);
@@ -4883,6 +4916,33 @@
return changed;
}
+bool Camera3Device::RequestThread::overrideSettingsOverride(
+ const sp<CaptureRequest> &request) {
+ ATRACE_CALL();
+
+ if (!mSupportSettingsOverride) return false;
+
+ Mutex::Autolock l(mTriggerMutex);
+
+ // For a multi-camera, only override the logical camera's metadata.
+ CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
+ camera_metadata_entry entry = metadata.find(ANDROID_CONTROL_SETTINGS_OVERRIDE);
+ int32_t originalValue = request->mSettingsList.begin()->mOriginalSettingsOverride;
+ if (mSettingsOverride != -1 &&
+ (entry.count == 0 || entry.data.i32[0] != mSettingsOverride)) {
+ metadata.update(ANDROID_CONTROL_SETTINGS_OVERRIDE,
+ &mSettingsOverride, 1);
+ return true;
+ } else if (mSettingsOverride == -1 &&
+ (entry.count == 0 || entry.data.i32[0] != originalValue)) {
+ metadata.update(ANDROID_CONTROL_SETTINGS_OVERRIDE,
+ &originalValue, 1);
+ return true;
+ }
+
+ return false;
+}
+
status_t Camera3Device::RequestThread::setHalInterface(
sp<HalInterface> newHalInterface) {
if (newHalInterface.get() == nullptr) {
@@ -5349,6 +5409,25 @@
return mRequestThread->setCameraMute(muteMode);
}
+bool Camera3Device::supportsZoomOverride() {
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+
+ return mSupportZoomOverride;
+}
+
+status_t Camera3Device::setZoomOverride(int32_t zoomOverride) {
+ ATRACE_CALL();
+ Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock l(mLock);
+
+ if (mRequestThread == nullptr || !mSupportZoomOverride) {
+ return INVALID_OPERATION;
+ }
+
+ return mRequestThread->setZoomOverride(zoomOverride);
+}
+
status_t Camera3Device::injectCamera(const String8& injectedCamId,
sp<CameraProviderManager> manager) {
ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.string());
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index e045b98..abfd9aa 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -312,6 +312,14 @@
// Clear stream use case overrides
void clearStreamUseCaseOverrides();
+ /**
+ * Whether the camera device supports zoom override.
+ */
+ bool supportsZoomOverride();
+
+ // Set/reset zoom override
+ status_t setZoomOverride(int32_t zoomOverride);
+
// Get the status trackeer for the camera device
wp<camera3::StatusTracker> getStatusTracker() { return mStatusTracker; }
@@ -862,7 +870,8 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait);
+ bool overrideToPortrait,
+ bool supportSettingsOverride);
~RequestThread();
void setNotificationListener(wp<NotificationListener> listener);
@@ -969,6 +978,8 @@
status_t setCameraMute(int32_t muteMode);
+ status_t setZoomOverride(int32_t zoomOverride);
+
status_t setHalInterface(sp<HalInterface> newHalInterface);
protected:
@@ -998,6 +1009,10 @@
// if the current value was changed
bool overrideTestPattern(const sp<CaptureRequest> &request);
+ // Override settings override if needed for lower zoom latency; return
+ // true if the current value was changed
+ bool overrideSettingsOverride(const sp<CaptureRequest> &request);
+
static const nsecs_t kRequestTimeout = 50e6; // 50 ms
// TODO: does this need to be adjusted for long exposure requests?
@@ -1132,6 +1147,8 @@
bool mComposerOutput;
int32_t mCameraMute; // 0 = no mute, otherwise the TEST_PATTERN_MODE to use
bool mCameraMuteChanged;
+ int32_t mSettingsOverride; // -1 = use original, otherwise
+ // the settings override to use.
int64_t mRepeatingLastFrameNumber;
@@ -1151,6 +1168,7 @@
const bool mUseHalBufManager;
const bool mSupportCameraMute;
const bool mOverrideToPortrait;
+ const bool mSupportSettingsOverride;
int32_t mVndkVersion = -1;
};
@@ -1160,7 +1178,8 @@
const Vector<int32_t>& /*sessionParamKeys*/,
bool /*useHalBufManager*/,
bool /*supportCameraMute*/,
- bool /*overrideToPortrait*/) = 0;
+ bool /*overrideToPortrait*/,
+ bool /*supportSettingsOverride*/) = 0;
sp<RequestThread> mRequestThread;
@@ -1425,6 +1444,8 @@
bool mSupportCameraMute = false;
// Whether the HAL supports SOLID_COLOR or BLACK if mSupportCameraMute is true
bool mSupportTestPatternSolidColor = false;
+ // Whether the HAL supports zoom settings override
+ bool mSupportZoomOverride = false;
// Whether the camera framework overrides the device characteristics for
// performance class.
@@ -1439,6 +1460,10 @@
// Auto framing override value
camera_metadata_enum_android_control_autoframing mAutoframingOverride;
+ // Settings override value
+ int32_t mSettingsOverride; // -1 = use original, otherwise
+ // the settings override to use.
+
// Current active physical id of the logical multi-camera, if any
std::string mActivePhysicalId;
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index 3b1eba3..e186f13 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -1419,9 +1419,10 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait) :
+ bool overrideToPortrait,
+ bool supportSettingsOverride) :
RequestThread(parent, statusTracker, interface, sessionParamKeys, useHalBufManager,
- supportCameraMute, overrideToPortrait) {}
+ supportCameraMute, overrideToPortrait, supportSettingsOverride) {}
status_t AidlCamera3Device::AidlRequestThread::switchToOffline(
const std::vector<int32_t>& streamsToKeep,
@@ -1591,9 +1592,10 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait) {
+ bool overrideToPortrait,
+ bool supportSettingsOverride) {
return new AidlRequestThread(parent, statusTracker, interface, sessionParamKeys,
- useHalBufManager, supportCameraMute, overrideToPortrait);
+ useHalBufManager, supportCameraMute, overrideToPortrait, supportSettingsOverride);
};
sp<Camera3Device::Camera3DeviceInjectionMethods>
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
index 8ee5c63..99a308b 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.h
@@ -179,7 +179,8 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait);
+ bool overrideToPortrait,
+ bool supportSettingsOverride);
status_t switchToOffline(
const std::vector<int32_t>& streamsToKeep,
@@ -265,7 +266,8 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait) override;
+ bool overrideToPortrait,
+ bool supportSettingsOverride) override;
virtual sp<Camera3DeviceInjectionMethods>
createCamera3DeviceInjectionMethods(wp<Camera3Device>) override;
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
index b367019..0d44dd5 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.cpp
@@ -704,9 +704,10 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait) {
+ bool overrideToPortrait,
+ bool supportSettingsOverride) {
return new HidlRequestThread(parent, statusTracker, interface, sessionParamKeys,
- useHalBufManager, supportCameraMute, overrideToPortrait);
+ useHalBufManager, supportCameraMute, overrideToPortrait, supportSettingsOverride);
};
sp<Camera3Device::Camera3DeviceInjectionMethods>
@@ -1701,9 +1702,10 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait) :
+ bool overrideToPortrait,
+ bool supportSettingsOverride) :
RequestThread(parent, statusTracker, interface, sessionParamKeys, useHalBufManager,
- supportCameraMute, overrideToPortrait) {}
+ supportCameraMute, overrideToPortrait, supportSettingsOverride) {}
status_t HidlCamera3Device::HidlRequestThread::switchToOffline(
const std::vector<int32_t>& streamsToKeep,
diff --git a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
index 7b216b2..1e50844 100644
--- a/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
+++ b/services/camera/libcameraservice/device3/hidl/HidlCamera3Device.h
@@ -177,7 +177,8 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait);
+ bool overrideToPortrait,
+ bool supportSettingsOverride);
status_t switchToOffline(
const std::vector<int32_t>& streamsToKeep,
@@ -225,7 +226,8 @@
const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
bool supportCameraMute,
- bool overrideToPortrait) override;
+ bool overrideToPortrait,
+ bool supportSettingsOverride) override;
virtual sp<Camera3DeviceInjectionMethods>
createCamera3DeviceInjectionMethods(wp<Camera3Device>) override;