Merge "audio policy: create spatializer mixer only when needed" into tm-dev
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 74e3223..f7989bd 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -208,7 +208,11 @@
}
status_t DrmManager::loadPlugIns() {
+#if __LP64__
+ String8 pluginDirPath("/system/lib64/drm");
+#else
String8 pluginDirPath("/system/lib/drm");
+#endif
loadPlugIns(pluginDirPath);
return DRM_NO_ERROR;
}
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
index 02ac943..b82d996 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp
+++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp
@@ -144,7 +144,6 @@
"libclearkeydevicefiles-protos",
"libjsmn",
"libprotobuf-cpp-lite",
- "libutils",
],
shared_libs: [
"android.hidl.allocator@1.0",
@@ -157,6 +156,7 @@
"libhidlbase",
"libhidlmemory",
"liblog",
+ "libutils",
],
fuzz_config: {
cc: [
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index a73b493..c36ae94 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -67,6 +67,7 @@
"libstagefright_codecbase",
"libstagefright_foundation",
"libstagefright_omx",
+ "libstagefright_surface_utils",
"libstagefright_xmlparser",
"libui",
"libutils",
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index cb362c9..88fe1f3 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -871,6 +871,11 @@
}
config->mTunneled = true;
}
+
+ int32_t pushBlankBuffersOnStop = 0;
+ if (msg->findInt32(KEY_PUSH_BLANK_BUFFERS_ON_STOP, &pushBlankBuffersOnStop)) {
+ config->mPushBlankBuffersOnStop = pushBlankBuffersOnStop == 1;
+ }
}
}
setSurface(surface);
@@ -1841,7 +1846,13 @@
}
state->set(STOPPING);
}
-
+ {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ if (config->mPushBlankBuffersOnStop) {
+ mChannel->pushBlankBufferToOutputSurface();
+ }
+ }
mChannel->reset();
(new AMessage(kWhatStop, this))->post();
}
@@ -1929,6 +1940,13 @@
config->mInputSurfaceDataspace = HAL_DATASPACE_UNKNOWN;
}
}
+ {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ if (config->mPushBlankBuffersOnStop) {
+ mChannel->pushBlankBufferToOutputSurface();
+ }
+ }
mChannel->reset();
// thiz holds strong ref to this while the thread is running.
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 674714f..a086128 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -15,6 +15,7 @@
*/
//#define LOG_NDEBUG 0
+#include <utils/Errors.h>
#define LOG_TAG "CCodecBufferChannel"
#define ATRACE_TAG ATRACE_TAG_VIDEO
#include <utils/Log.h>
@@ -48,6 +49,7 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/SkipCutBuffer.h>
+#include <media/stagefright/SurfaceUtils.h>
#include <media/MediaCodecBuffer.h>
#include <mediadrm/ICrypto.h>
#include <system/window.h>
@@ -2180,4 +2182,13 @@
}
}
+status_t CCodecBufferChannel::pushBlankBufferToOutputSurface() {
+ Mutexed<OutputSurface>::Locked output(mOutputSurface);
+ sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(output->surface.get());
+ if (nativeWindow == nullptr) {
+ return INVALID_OPERATION;
+ }
+ return pushBlankBuffersToNativeWindow(nativeWindow.get());
+}
+
} // namespace android
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 26eef30..b3a5f4b 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -181,6 +181,11 @@
void setMetaMode(MetaMode mode);
+ /**
+ * Push a blank buffer to the configured native output surface.
+ */
+ status_t pushBlankBufferToOutputSurface();
+
private:
class QueueGuard;
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index c15b5ca..132902b 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -324,7 +324,8 @@
: mInputFormat(new AMessage),
mOutputFormat(new AMessage),
mUsingSurface(false),
- mTunneled(false) { }
+ mTunneled(false),
+ mPushBlankBuffersOnStop(false) { }
void CCodecConfig::initializeStandardParams() {
typedef Domain D;
@@ -963,8 +964,6 @@
.limitTo(D::ENCODER & D::VIDEO & D::READ));
/* still to do
- constexpr char KEY_PUSH_BLANK_BUFFERS_ON_STOP[] = "push-blank-buffers-on-shutdown";
-
not yet used by MediaCodec, but defined as MediaFormat
KEY_AUDIO_SESSION_ID // we use "audio-hw-sync"
KEY_OUTPUT_REORDER_DEPTH
diff --git a/media/codec2/sfplugin/CCodecConfig.h b/media/codec2/sfplugin/CCodecConfig.h
index 88e6239..2e7b866 100644
--- a/media/codec2/sfplugin/CCodecConfig.h
+++ b/media/codec2/sfplugin/CCodecConfig.h
@@ -148,6 +148,8 @@
bool mTunneled;
sp<NativeHandle> mSidebandHandle;
+ bool mPushBlankBuffersOnStop;
+
CCodecConfig();
/// initializes the members required to manage the format: descriptors, reflector,
@@ -396,4 +398,3 @@
} // namespace android
#endif // C_CODEC_H_
-
diff --git a/media/libaaudio/fuzzer/Android.bp b/media/libaaudio/fuzzer/Android.bp
index e2eec7a..2a12191 100644
--- a/media/libaaudio/fuzzer/Android.bp
+++ b/media/libaaudio/fuzzer/Android.bp
@@ -36,11 +36,11 @@
"libaudiomanager",
"libaudiopolicy",
"libaudioclient_aidl_conversion",
+ "libutils",
],
static_libs: [
"android.media.audio.common.types-V1-cpp",
"liblog",
- "libutils",
"libcutils",
"libaaudio",
"libjsoncpp",
diff --git a/media/libaaudio/scripts/measure_device_power.py b/media/libaaudio/scripts/measure_device_power.py
index fd7f85f..1f90933 100755
--- a/media/libaaudio/scripts/measure_device_power.py
+++ b/media/libaaudio/scripts/measure_device_power.py
@@ -79,28 +79,42 @@
SORTED_ENERGY_LIST = sorted(ENERGY_DICTIONARY, key=ENERGY_DICTIONARY.get)
-# Sometimes "adb unroot" returns 1!
+# Sometimes adb returns 1 for no apparent reason.
# So try several times.
# @return 0 on success
-def adbUnroot():
+def adbTryMultiple(command):
returnCode = 1
count = 0
limit = 5
while count < limit and returnCode != 0:
- print(('Try to adb unroot {} of {}'.format(count, limit)))
+ print(('Try to adb {} {} of {}'.format(command, count, limit)))
subprocess.call(["adb", "wait-for-device"])
time.sleep(PRE_DELAY_SECONDS)
- returnCode = subprocess.call(["adb", "unroot"])
+ returnCode = subprocess.call(["adb", command])
print(('returnCode = {}'.format(returnCode)))
count += 1
return returnCode
+# Sometimes "adb root" returns 1!
+# So try several times.
+# @return 0 on success
+def adbRoot():
+ return adbTryMultiple("root");
+
+# Sometimes "adb unroot" returns 1!
+# So try several times.
+# @return 0 on success
+def adbUnroot():
+ return adbTryMultiple("unroot");
+
# @param commandString String containing shell command
# @return Both the stdout and stderr of the commands run
def runCommand(commandString):
print(commandString)
if commandString == "adb unroot":
result = adbUnroot()
+ elif commandString == "adb root":
+ result = adbRoot()
else:
commandArray = commandString.split(' ')
result = subprocess.run(commandArray, check=True, capture_output=True).stdout
@@ -111,6 +125,8 @@
def adbCommand(commandString):
if commandString == "unroot":
result = adbUnroot()
+ elif commandString == "root":
+ result = adbRoot()
else:
print(("adb " + commandString))
commandArray = ["adb"] + commandString.split(' ')
@@ -230,7 +246,7 @@
print((command + "\n"))
comment = command[1:].strip() # remove leading '#'
elif command.endswith('\\'):
- command = command[:-1].strip() # remove \\
+ command = command[:-1].strip() # remove trailing '\'
runCommand(command)
elif command:
report = averageEnergyForCommand(command, DEFAULT_NUM_ITERATIONS)
diff --git a/media/libaaudio/scripts/synthmark_tests.txt b/media/libaaudio/scripts/synthmark_tests.txt
index 24e719d..8b6d47e 100644
--- a/media/libaaudio/scripts/synthmark_tests.txt
+++ b/media/libaaudio/scripts/synthmark_tests.txt
@@ -1,31 +1,36 @@
# Measure energy consumption with synthmark.
-# ADPF <400 RR
-adb root \
-adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 400 \
-adb shell synthmark -tj -n1 -N50 -B2 -z1
-adb shell synthmark -tj -n1 -N75 -B2 -z1
-adb shell synthmark -tj -n1 -N100 -B2 -z1
-
-# ADPF <500 RR
-adb root \
-adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 500 \
-adb shell synthmark -tj -n1 -N50 -B2 -z1
-adb shell synthmark -tj -n1 -N75 -B2 -z1
-adb shell synthmark -tj -n1 -N100 -B2 -z1
-
-# ADPF <600 RR
-adb root \
-adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 600 \
-adb shell synthmark -tj -n1 -N50 -B2 -z1
-adb shell synthmark -tj -n1 -N75 -B2 -z1
-adb shell synthmark -tj -n1 -N100 -B2 -z1
-
# None
adb shell synthmark -tj -n1 -N50 -B2 -z0
adb shell synthmark -tj -n1 -N75 -B2 -z0
adb shell synthmark -tj -n1 -N100 -B2 -z0
+# ADPF PID
+adb shell synthmark -tj -n1 -N50 -B2 -z1
+adb shell synthmark -tj -n1 -N75 -B2 -z1
+adb shell synthmark -tj -n1 -N100 -B2 -z1
+
+# ADPF <400 RR
+# adb root \
+# adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 400 \
+# adb shell synthmark -tj -n1 -N50 -B2 -z1
+# adb shell synthmark -tj -n1 -N75 -B2 -z1
+# adb shell synthmark -tj -n1 -N100 -B2 -z1
+
+# ADPF <500 RR
+# adb root \
+# adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 500 \
+# adb shell synthmark -tj -n1 -N50 -B2 -z1
+# adb shell synthmark -tj -n1 -N75 -B2 -z1
+# adb shell synthmark -tj -n1 -N100 -B2 -z1
+
+# ADPF <600 RR
+# adb root \
+# adb shell setprop vendor.powerhal.adpf.uclamp_min.high_limit 600 \
+# adb shell synthmark -tj -n1 -N50 -B2 -z1
+# adb shell synthmark -tj -n1 -N75 -B2 -z1
+# adb shell synthmark -tj -n1 -N100 -B2 -z1
+
# uclamp
# adb root \
# adb shell synthmark -tj -n1 -N75 -B2 -u1
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index e47e7ff..10baec4 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -253,6 +253,40 @@
],
},
}
+
+cc_library_shared {
+ name: "libstagefright_surface_utils",
+
+ srcs: [
+ "SurfaceUtils.cpp",
+ ],
+
+ shared_libs: [
+ "libgui",
+ "liblog",
+ "libui",
+ "libutils",
+ ],
+
+ export_include_dirs: [
+ "include",
+ ],
+
+ cflags: [
+ "-Wno-multichar",
+ "-Werror",
+ "-Wall",
+ ],
+
+ sanitize: {
+ cfi: true,
+ misc_undefined: [
+ "unsigned-integer-overflow",
+ "signed-integer-overflow",
+ ],
+ },
+}
+
cc_library {
name: "libstagefright",
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index 3b466d7..389233e 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -459,9 +459,7 @@
}
std::lock_guard lock(mLock);
mScreenSensor = sensorHandle;
- if (mPoseController != nullptr) {
- mPoseController->setScreenSensor(mScreenSensor);
- }
+ checkSensorsState_l();
return Status::ok();
}
@@ -569,9 +567,6 @@
sp<media::ISpatializerHeadTrackingCallback> callback;
{
std::lock_guard lock(mLock);
- if (mActualHeadTrackingMode == SpatializerHeadTrackingMode::DISABLED) {
- return;
- }
callback = mHeadTrackingCallback;
if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEAD_TO_STAGE, headToStage);
@@ -595,7 +590,6 @@
ALOGV("%s(%d)", __func__, (int) mode);
sp<media::ISpatializerHeadTrackingCallback> callback;
SpatializerHeadTrackingMode spatializerMode;
- bool modeChanged = false;
{
std::lock_guard lock(mLock);
if (!mSupportsHeadTracking) {
@@ -615,21 +609,19 @@
LOG_ALWAYS_FATAL("Unknown mode: %d", mode);
}
}
- modeChanged = mActualHeadTrackingMode != spatializerMode;
mActualHeadTrackingMode = spatializerMode;
- if (modeChanged && mEngine != nullptr) {
+ if (mEngine != nullptr) {
setEffectParameter_l(SPATIALIZER_PARAM_HEADTRACKING_MODE,
std::vector<SpatializerHeadTrackingMode>{spatializerMode});
}
callback = mHeadTrackingCallback;
}
- if (callback != nullptr && modeChanged) {
+ if (callback != nullptr) {
callback->onHeadTrackingModeChanged(spatializerMode);
}
}
status_t Spatializer::attachOutput(audio_io_handle_t output, size_t numActiveTracks) {
- std::shared_ptr<SpatializerPoseController> poseController;
bool outputChanged = false;
sp<media::INativeSpatializerCallback> callback;
@@ -663,14 +655,9 @@
if (mSupportsHeadTracking) {
checkPoseController_l();
checkSensorsState_l();
- poseController = mPoseController;
}
callback = mSpatializerCallback;
}
- if (poseController != nullptr) {
- poseController->calculateAsync();
- poseController->waitUntilCalculated();
- }
if (outputChanged && callback != nullptr) {
callback->onOutputChanged(output);
@@ -750,7 +737,7 @@
if (isControllerNeeded && mPoseController == nullptr) {
mPoseController = std::make_shared<SpatializerPoseController>(
static_cast<SpatializerPoseController::Listener*>(this),
- 10ms, std::chrono::microseconds::max());
+ 10ms, std::nullopt);
LOG_ALWAYS_FATAL_IF(mPoseController == nullptr,
"%s could not allocate pose controller", __func__);
mPoseController->setDisplayOrientation(mDisplayOrientation);
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 58a57ac..0a9f4d9 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -46,9 +46,8 @@
// high will result in high prediction errors whenever the head accelerates (changes velocity).
constexpr auto kPredictionDuration = 50ms;
-// After losing this many consecutive samples from either sensor, we would treat the measurement as
-// stale;
-constexpr auto kMaxLostSamples = 4;
+// After not getting a pose sample for this long, we would treat the measurement as stale.
+constexpr auto kFreshnessTimeout = 50ms;
// Auto-recenter kicks in after the head has been still for this long.
constexpr auto kAutoRecenterWindowDuration = 6s;
@@ -79,14 +78,14 @@
} // namespace
SpatializerPoseController::SpatializerPoseController(Listener* listener,
- std::chrono::microseconds sensorPeriod,
- std::chrono::microseconds maxUpdatePeriod)
+ std::chrono::microseconds sensorPeriod,
+ std::optional<std::chrono::microseconds> maxUpdatePeriod)
: mListener(listener),
mSensorPeriod(sensorPeriod),
mProcessor(createHeadTrackingProcessor(HeadTrackingProcessor::Options{
.maxTranslationalVelocity = kMaxTranslationalVelocity / kTicksPerSecond,
.maxRotationalVelocity = kMaxRotationalVelocity / kTicksPerSecond,
- .freshnessTimeout = Ticks(sensorPeriod * kMaxLostSamples).count(),
+ .freshnessTimeout = Ticks(kFreshnessTimeout).count(),
.predictionDuration = Ticks(kPredictionDuration).count(),
.autoRecenterWindowDuration = Ticks(kAutoRecenterWindowDuration).count(),
.autoRecenterTranslationalThreshold = kAutoRecenterTranslationThreshold,
@@ -102,8 +101,12 @@
std::optional<HeadTrackingMode> modeIfChanged;
{
std::unique_lock lock(mMutex);
- mCondVar.wait_for(lock, maxUpdatePeriod,
- [this] { return mShouldExit || mShouldCalculate; });
+ if (maxUpdatePeriod.has_value()) {
+ mCondVar.wait_for(lock, maxUpdatePeriod.value(),
+ [this] { return mShouldExit || mShouldCalculate; });
+ } else {
+ mCondVar.wait(lock, [this] { return mShouldExit || mShouldCalculate; });
+ }
if (mShouldExit) {
ALOGV("Exiting thread");
return;
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index 2b5c189..2c6d79a 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -60,10 +60,10 @@
* Ctor.
* sensorPeriod determines how often to receive updates from the sensors (input rate).
* maxUpdatePeriod determines how often to produce an output when calculateAsync() isn't
- * invoked.
+ * invoked; passing nullopt means an output is never produced.
*/
SpatializerPoseController(Listener* listener, std::chrono::microseconds sensorPeriod,
- std::chrono::microseconds maxUpdatePeriod);
+ std::optional<std::chrono::microseconds> maxUpdatePeriod);
/** Dtor. */
~SpatializerPoseController();
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index 6058429..5da77d6 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -441,6 +441,10 @@
newFormat->setInt32(KEY_TILE_HEIGHT, mGridHeight);
newFormat->setInt32(KEY_GRID_ROWS, mGridRows);
newFormat->setInt32(KEY_GRID_COLUMNS, mGridCols);
+ int32_t left, top, right, bottom;
+ if (newFormat->findRect("crop", &left, &top, &right, &bottom)) {
+ newFormat->setRect("crop", 0, 0, mOutputWidth - 1, mOutputHeight - 1);
+ }
}
}
newFormat->setInt32(KEY_IS_DEFAULT, 1 /*isPrimary*/);