Spatializer dumpsys: Add mode selector and pose rate limiter in dumpsys
Bug: 233092747
Test: m and "adb shell dumpsys media.audio_policy"
Change-Id: I7ec026ed0e5005cd9f56f3a16d37cc547e1dcc99
diff --git a/media/libheadtracking/Android.bp b/media/libheadtracking/Android.bp
index 7e2c762..f64aedf 100644
--- a/media/libheadtracking/Android.bp
+++ b/media/libheadtracking/Android.bp
@@ -83,6 +83,7 @@
"Twist-test.cpp",
],
shared_libs: [
+ "libaudioutils",
"libheadtracking",
],
}
diff --git a/media/libheadtracking/HeadTrackingProcessor.cpp b/media/libheadtracking/HeadTrackingProcessor.cpp
index ccb75af..101b825 100644
--- a/media/libheadtracking/HeadTrackingProcessor.cpp
+++ b/media/libheadtracking/HeadTrackingProcessor.cpp
@@ -164,29 +164,30 @@
std::string toString_l(unsigned level) const override {
std::string prefixSpace(level, ' ');
std::string ss = prefixSpace + "HeadTrackingProcessor:\n";
- StringAppendF(&ss, "%smaxTranslationalVelocity: %f\n", prefixSpace.c_str(),
+ StringAppendF(&ss, "%s maxTranslationalVelocity: %f meter/second\n", prefixSpace.c_str(),
mOptions.maxTranslationalVelocity);
- StringAppendF(&ss, "%smaxRotationalVelocity: %f\n", prefixSpace.c_str(),
+ StringAppendF(&ss, "%s maxRotationalVelocity: %f rad/second\n", prefixSpace.c_str(),
mOptions.maxRotationalVelocity);
- StringAppendF(&ss, "%sfreshnessTimeout: %" PRId64 "\n", prefixSpace.c_str(),
- mOptions.freshnessTimeout);
- StringAppendF(&ss, "%spredictionDuration: %f\n", prefixSpace.c_str(),
- mOptions.predictionDuration);
- StringAppendF(&ss, "%sautoRecenterWindowDuration: %" PRId64 "\n", prefixSpace.c_str(),
- mOptions.autoRecenterWindowDuration);
- StringAppendF(&ss, "%sautoRecenterTranslationalThreshold: %f\n", prefixSpace.c_str(),
+ StringAppendF(&ss, "%s freshnessTimeout: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.freshnessTimeout));
+ StringAppendF(&ss, "%s predictionDuration: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.predictionDuration));
+ StringAppendF(&ss, "%s autoRecenterWindowDuration: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.autoRecenterWindowDuration));
+ StringAppendF(&ss, "%s autoRecenterTranslationalThreshold: %f meter\n", prefixSpace.c_str(),
mOptions.autoRecenterTranslationalThreshold);
- StringAppendF(&ss, "%sautoRecenterRotationalThreshold: %f\n", prefixSpace.c_str(),
+ StringAppendF(&ss, "%s autoRecenterRotationalThreshold: %f radians\n", prefixSpace.c_str(),
mOptions.autoRecenterRotationalThreshold);
- StringAppendF(&ss, "%sscreenStillnessWindowDuration: %" PRId64 "\n", prefixSpace.c_str(),
- mOptions.screenStillnessWindowDuration);
- StringAppendF(&ss, "%sscreenStillnessTranslationalThreshold: %f\n", prefixSpace.c_str(),
- mOptions.screenStillnessTranslationalThreshold);
- StringAppendF(&ss, "%sscreenStillnessRotationalThreshold: %f\n", prefixSpace.c_str(),
- mOptions.screenStillnessRotationalThreshold);
+ StringAppendF(&ss, "%s screenStillnessWindowDuration: %0.4f ms\n", prefixSpace.c_str(),
+ media::nsToFloatMs(mOptions.screenStillnessWindowDuration));
+ StringAppendF(&ss, "%s screenStillnessTranslationalThreshold: %f meter\n",
+ prefixSpace.c_str(), mOptions.screenStillnessTranslationalThreshold);
+ StringAppendF(&ss, "%s screenStillnessRotationalThreshold: %f radians\n",
+ prefixSpace.c_str(), mOptions.screenStillnessRotationalThreshold);
+ ss += mModeSelector.toString(level + 1);
+ ss += mRateLimiter.toString(level + 1);
ss.append(prefixSpace + "ReCenterHistory:\n");
ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), mMaxLocalLogLine);
- // TODO: 233092747 add string from PoseRateLimiter/PoseRateLimiter etc...
return ss;
}
@@ -217,5 +218,17 @@
return std::make_unique<HeadTrackingProcessorImpl>(options, initialMode);
}
+std::string toString(HeadTrackingMode mode) {
+ switch (mode) {
+ case HeadTrackingMode::STATIC:
+ return "STATIC";
+ case HeadTrackingMode::WORLD_RELATIVE:
+ return "WORLD_RELATIVE";
+ case HeadTrackingMode::SCREEN_RELATIVE:
+ return "SCREEN_RELATIVE";
+ }
+ return "EnumNotImplemented";
+};
+
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/ModeSelector.cpp b/media/libheadtracking/ModeSelector.cpp
index cb3a27f..6277090 100644
--- a/media/libheadtracking/ModeSelector.cpp
+++ b/media/libheadtracking/ModeSelector.cpp
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include "ModeSelector.h"
namespace android {
namespace media {
+using android::base::StringAppendF;
ModeSelector::ModeSelector(const Options& options, HeadTrackingMode initialMode)
: mOptions(options), mDesiredMode(initialMode), mActualMode(initialMode) {}
@@ -47,12 +49,15 @@
}
void ModeSelector::calculateActualMode(int64_t timestamp) {
- bool isValidScreenToHead = mScreenToHead.has_value() &&
- timestamp - mScreenToHeadTimestamp < mOptions.freshnessTimeout;
- bool isValidWorldToHead = mWorldToHead.has_value() &&
- timestamp - mWorldToHeadTimestamp < mOptions.freshnessTimeout;
- bool isValidScreenStable = mScreenStable.has_value() &&
- timestamp - mScreenStableTimestamp < mOptions.freshnessTimeout;
+ int64_t screenToHeadGap = timestamp - mScreenToHeadTimestamp;
+ int64_t worldToHeadGap = timestamp - mWorldToHeadTimestamp;
+ int64_t screenStableGap = timestamp - mScreenStableTimestamp;
+ bool isValidScreenToHead =
+ mScreenToHead.has_value() && screenToHeadGap < mOptions.freshnessTimeout;
+ bool isValidWorldToHead =
+ mWorldToHead.has_value() && worldToHeadGap < mOptions.freshnessTimeout;
+ bool isValidScreenStable =
+ mScreenStable.has_value() && screenStableGap < mOptions.freshnessTimeout;
HeadTrackingMode mode = mDesiredMode;
@@ -70,7 +75,17 @@
}
}
- mActualMode = mode;
+ if (mode != mActualMode) {
+ mLocalLog.log(
+ "HT mode change from %s to %s, this ts %0.4f ms, lastTs+gap [ScreenToHead %0.4f + "
+ "%0.4f, WorldToHead %0.4f + %0.4f, ScreenStable %0.4f + %0.4f] ms",
+ media::toString(mActualMode).c_str(), media::toString(mode).c_str(),
+ media::nsToFloatMs(timestamp), media::nsToFloatMs(mScreenToHeadTimestamp),
+ media::nsToFloatMs(screenToHeadGap), media::nsToFloatMs(mWorldToHeadTimestamp),
+ media::nsToFloatMs(worldToHeadGap), media::nsToFloatMs(mScreenStableTimestamp),
+ media::nsToFloatMs(screenStableGap));
+ mActualMode = mode;
+ }
}
void ModeSelector::calculate(int64_t timestamp) {
@@ -99,5 +114,15 @@
return mActualMode;
}
+std::string ModeSelector::toString(unsigned level) const {
+ std::string prefixSpace(level, ' ');
+ std::string ss(prefixSpace);
+ StringAppendF(&ss, "ModeSelector: ScreenToStage %s\n",
+ mScreenToStage.toString().c_str());
+ ss.append(prefixSpace + "Mode downgrade history:\n");
+ ss += mLocalLog.dumpToString((prefixSpace + " ").c_str(), sMaxLocalLogLine);
+ return ss;
+}
+
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/ModeSelector.h b/media/libheadtracking/ModeSelector.h
index e537040..2475a5b 100644
--- a/media/libheadtracking/ModeSelector.h
+++ b/media/libheadtracking/ModeSelector.h
@@ -16,6 +16,7 @@
#pragma once
#include <optional>
+#include <audio_utils/SimpleLog.h>
#include "media/HeadTrackingMode.h"
#include "media/Pose.h"
@@ -114,6 +115,8 @@
*/
HeadTrackingMode getActualMode() const;
+ std::string toString(unsigned level) const;
+
private:
const Options mOptions;
@@ -129,6 +132,9 @@
HeadTrackingMode mActualMode;
Pose3f mHeadToStage;
+ static constexpr std::size_t sMaxLocalLogLine = 10;
+ SimpleLog mLocalLog{sMaxLocalLogLine};
+
void calculateActualMode(int64_t timestamp);
};
diff --git a/media/libheadtracking/Pose.cpp b/media/libheadtracking/Pose.cpp
index ae39512..4a4b56a 100644
--- a/media/libheadtracking/Pose.cpp
+++ b/media/libheadtracking/Pose.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include "media/Pose.h"
#include "media/Twist.h"
@@ -21,6 +22,7 @@
namespace android {
namespace media {
+using android::base::StringAppendF;
using Eigen::Vector3f;
std::optional<Pose3f> Pose3f::fromVector(const std::vector<float>& vec) {
@@ -35,6 +37,19 @@
return {mTranslation[0], mTranslation[1], mTranslation[2], rot[0], rot[1], rot[2]};
}
+std::string Pose3f::toString() const {
+ const auto& vec = this->toVector();
+ std::string ss = "[";
+ for (auto f = vec.begin(); f != vec.end(); ++f) {
+ if (f != vec.begin()) {
+ ss.append(", ");
+ }
+ StringAppendF(&ss, "%0.2f", *f);
+ }
+ ss.append("]");
+ return ss;
+}
+
std::tuple<Pose3f, bool> moveWithRateLimit(const Pose3f& from, const Pose3f& to, float t,
float maxTranslationalVelocity,
float maxRotationalVelocity) {
diff --git a/media/libheadtracking/PoseRateLimiter.cpp b/media/libheadtracking/PoseRateLimiter.cpp
index 380e22b..060bb4b 100644
--- a/media/libheadtracking/PoseRateLimiter.cpp
+++ b/media/libheadtracking/PoseRateLimiter.cpp
@@ -13,11 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <android-base/stringprintf.h>
#include "PoseRateLimiter.h"
namespace android {
namespace media {
+using android::base::StringAppendF;
PoseRateLimiter::PoseRateLimiter(const Options& options) : mOptions(options), mLimiting(false) {}
@@ -48,5 +50,15 @@
return pose;
}
+std::string PoseRateLimiter::toString(unsigned level) const {
+ std::string ss(level, ' ');
+ if (mLimiting) {
+ StringAppendF(&ss, "PoseRateLimiter: enabled with target: %s\n",
+ mTargetPose.has_value() ? mTargetPose.value().toString().c_str() : "NULL");
+ } else {
+ StringAppendF(&ss, "PoseRateLimiter: disabled\n");
+ }
+ return ss;
+}
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/PoseRateLimiter.h b/media/libheadtracking/PoseRateLimiter.h
index aa2fe80..c673a33 100644
--- a/media/libheadtracking/PoseRateLimiter.h
+++ b/media/libheadtracking/PoseRateLimiter.h
@@ -77,6 +77,8 @@
Pose3f calculatePose(int64_t timestamp);
+ std::string toString(unsigned level) const;
+
private:
struct Point {
Pose3f pose;
diff --git a/media/libheadtracking/SensorPoseProvider.cpp b/media/libheadtracking/SensorPoseProvider.cpp
index 6c0a96d..bd8af04 100644
--- a/media/libheadtracking/SensorPoseProvider.cpp
+++ b/media/libheadtracking/SensorPoseProvider.cpp
@@ -18,9 +18,10 @@
#define LOG_TAG "SensorPoseProvider"
-#include <inttypes.h>
-
+#include <algorithm>
#include <future>
+#include <inttypes.h>
+#include <limits>
#include <map>
#include <thread>
@@ -135,7 +136,10 @@
{
std::lock_guard lock(mMutex);
- mEnabledSensorsExtra.emplace(sensor, SensorExtra{ .format = format });
+ mEnabledSensorsExtra.emplace(
+ sensor,
+ SensorExtra{.format = format,
+ .samplingPeriod = static_cast<int32_t>(samplingPeriod.count())});
}
// Enable the sensor.
@@ -173,8 +177,11 @@
StringAppendF(&ss, "%sSensors total number %zu:\n", prefixSpace.c_str(),
mEnabledSensorsExtra.size());
for (auto sensor : mEnabledSensorsExtra) {
- StringAppendF(&ss, "%s[Handle: 0x%08x, Format %s", prefixSpace.c_str(), sensor.first,
- toString(sensor.second.format).c_str());
+ StringAppendF(&ss,
+ "%s[Handle: 0x%08x, Format %s Period (set %d max %0.4f min %0.4f) ms",
+ prefixSpace.c_str(), sensor.first, toString(sensor.second.format).c_str(),
+ sensor.second.samplingPeriod, media::nsToFloatMs(sensor.second.maxPeriod),
+ media::nsToFloatMs(sensor.second.minPeriod));
if (sensor.second.discontinuityCount.has_value()) {
StringAppendF(&ss, ", DiscontinuityCount: %d",
sensor.second.discontinuityCount.value());
@@ -202,7 +209,11 @@
};
struct SensorExtra {
- DataFormat format;
+ DataFormat format = DataFormat::kUnknown;
+ int32_t samplingPeriod = 0;
+ int64_t latestTimestamp = 0;
+ int64_t maxPeriod = 0;
+ int64_t minPeriod = std::numeric_limits<int64_t>::max();
std::optional<int32_t> discontinuityCount;
};
@@ -296,6 +307,7 @@
return;
}
value = parseEvent(event, iter->second.format, &iter->second.discontinuityCount);
+ updateEventTimestamp(event, iter->second);
}
mListener->onPose(event.timestamp, event.sensor, value.pose, value.twist,
value.isNewReference);
@@ -351,6 +363,15 @@
return std::nullopt;
}
+ void updateEventTimestamp(const ASensorEvent& event, SensorExtra& extra) {
+ if (extra.latestTimestamp != 0) {
+ int64_t gap = event.timestamp - extra.latestTimestamp;
+ extra.maxPeriod = std::max(gap, extra.maxPeriod);
+ extra.minPeriod = std::min(gap, extra.minPeriod);
+ }
+ extra.latestTimestamp = event.timestamp;
+ }
+
static PoseEvent parseEvent(const ASensorEvent& event, DataFormat format,
std::optional<int32_t>* discontinutyCount) {
switch (format) {
@@ -381,7 +402,7 @@
}
}
- const std::string toString(DataFormat format) {
+ const static std::string toString(DataFormat format) {
switch (format) {
case DataFormat::kUnknown:
return "kUnknown";
diff --git a/media/libheadtracking/include/media/HeadTrackingMode.h b/media/libheadtracking/include/media/HeadTrackingMode.h
index 38496e8..92d1165 100644
--- a/media/libheadtracking/include/media/HeadTrackingMode.h
+++ b/media/libheadtracking/include/media/HeadTrackingMode.h
@@ -15,6 +15,8 @@
*/
#pragma once
+#include <string>
+
namespace android {
namespace media {
@@ -30,5 +32,7 @@
SCREEN_RELATIVE,
};
+std::string toString(HeadTrackingMode mode);
+
} // namespace media
} // namespace android
diff --git a/media/libheadtracking/include/media/Pose.h b/media/libheadtracking/include/media/Pose.h
index e660bb9..50294ed 100644
--- a/media/libheadtracking/include/media/Pose.h
+++ b/media/libheadtracking/include/media/Pose.h
@@ -16,6 +16,7 @@
#pragma once
#include <optional>
+#include <string>
#include <vector>
#include <Eigen/Geometry>
@@ -63,6 +64,9 @@
*/
std::vector<float> toVector() const;
+ // Convert instance to a string representation.
+ std::string toString() const;
+
Pose3f& operator=(const Pose3f& other) {
mTranslation = other.mTranslation;
mRotation = other.mRotation;
@@ -128,5 +132,10 @@
float maxTranslationalVelocity,
float maxRotationalVelocity);
+template <typename T>
+static float nsToFloatMs(T ns) {
+ return ns * 1e-6f;
+}
+
} // namespace media
} // namespace android
diff --git a/services/audiopolicy/service/Spatializer.cpp b/services/audiopolicy/service/Spatializer.cpp
index d411b8e..2d9c49d 100644
--- a/services/audiopolicy/service/Spatializer.cpp
+++ b/services/audiopolicy/service/Spatializer.cpp
@@ -748,11 +748,9 @@
}
void Spatializer::onActualModeChange(HeadTrackingMode mode) {
- std::string modeStr = SpatializerPoseController::toString(mode);
+ std::string modeStr = media::toString(mode);
ALOGV("%s(%s)", __func__, modeStr.c_str());
- mLocalLog.log("%s with %s", __func__, modeStr.c_str());
- sp<AMessage> msg =
- new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
+ sp<AMessage> msg = new AMessage(EngineCallbackHandler::kWhatOnActualModeChange, mHandler);
msg->setInt32(EngineCallbackHandler::kModeKey, static_cast<int>(mode));
msg->post();
}
@@ -786,8 +784,7 @@
std::vector<SpatializerHeadTrackingMode>{spatializerMode});
}
callback = mHeadTrackingCallback;
- mLocalLog.log("%s: %s, spatializerMode %s", __func__,
- SpatializerPoseController::toString(mode).c_str(),
+ mLocalLog.log("%s: %s, spatializerMode %s", __func__, media::toString(mode).c_str(),
media::toString(spatializerMode).c_str());
}
if (callback != nullptr) {
@@ -1009,7 +1006,7 @@
base::StringAppendF(&ss, " %s", media::toString(mode).c_str());
}
base::StringAppendF(&ss, "], Desired: %s, Actual %s\n",
- SpatializerPoseController::toString(mDesiredHeadTrackingMode).c_str(),
+ media::toString(mDesiredHeadTrackingMode).c_str(),
media::toString(mActualHeadTrackingMode).c_str());
base::StringAppendF(&ss, "%smSpatializationModes: [", prefixSpace.c_str());
@@ -1044,9 +1041,9 @@
ss.append(prefixSpace +
"Sensor data format - [rx, ry, rz, vx, vy, vz] (units-degree, "
"r-transform, v-angular velocity, x-pitch, y-roll, z-yaw):\n");
- ss.append(prefixSpace + "PerMinuteHistory:\n");
+ ss.append(prefixSpace + " PerMinuteHistory:\n");
ss += mPoseDurableRecorder.toString(level + 1);
- ss.append(prefixSpace + "PerSecondHistory:\n");
+ ss.append(prefixSpace + " PerSecondHistory:\n");
ss += mPoseRecorder.toString(level + 1);
} else {
ss.append(prefixSpace).append("SpatializerPoseController not exist\n");
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index 97ddd4e..53031f8 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -310,14 +310,14 @@
}
ss += prefixSpace;
- if (mHeadSensor == media::SensorPoseProvider::INVALID_HANDLE) {
- ss.append("HeadSensor: INVALID\n");
+ if (mHeadSensor == INVALID_SENSOR) {
+ ss += "HeadSensor: INVALID\n";
} else {
base::StringAppendF(&ss, "HeadSensor: 0x%08x\n", mHeadSensor);
}
ss += prefixSpace;
- if (mScreenSensor == media::SensorPoseProvider::INVALID_HANDLE) {
+ if (mScreenSensor == INVALID_SENSOR) {
ss += "ScreenSensor: INVALID\n";
} else {
base::StringAppendF(&ss, "ScreenSensor: 0x%08x\n", mScreenSensor);
@@ -325,7 +325,7 @@
ss += prefixSpace;
if (mActualMode.has_value()) {
- base::StringAppendF(&ss, "ActualMode: %s", toString(mActualMode.value()).c_str());
+ base::StringAppendF(&ss, "ActualMode: %s\n", media::toString(mActualMode.value()).c_str());
} else {
ss += "ActualMode NOTEXIST\n";
}
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index 546eba0..233f94c 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -116,18 +116,6 @@
// convert fields to a printable string
std::string toString(unsigned level) const;
- static std::string toString(media::HeadTrackingMode mode) {
- switch (mode) {
- case media::HeadTrackingMode::STATIC:
- return "STATIC";
- case media::HeadTrackingMode::WORLD_RELATIVE:
- return "WORLD_RELATIVE";
- case media::HeadTrackingMode::SCREEN_RELATIVE:
- return "SCREEN_RELATIVE";
- }
- return "EnumNotImplemented";
- };
-
private:
mutable std::timed_mutex mMutex;
Listener* const mListener;