Add options to dumpsys media.log and dump visualizations
Other Changes:
- added thread_params_t type to NBLog
- rearranged ordering of macros in TypedLogger.h
Test: dumpsys media.log with --json, --pa, and --plots options
Bug: 68148948
Change-Id: If97714271a085a99bba0ab3ae0c268a9f407f053
diff --git a/media/libnblog/ReportPerformance.cpp b/media/libnblog/ReportPerformance.cpp
index bf8a1dc..7e40947 100644
--- a/media/libnblog/ReportPerformance.cpp
+++ b/media/libnblog/ReportPerformance.cpp
@@ -40,13 +40,14 @@
namespace android {
namespace ReportPerformance {
-std::unique_ptr<Json::Value> dumpToJson(const PerformanceData& data)
+static std::unique_ptr<Json::Value> dumpToJson(const PerformanceData& data)
{
std::unique_ptr<Json::Value> rootPtr = std::make_unique<Json::Value>(Json::objectValue);
Json::Value& root = *rootPtr;
- root["type"] = (Json::Value::Int)data.threadInfo.type;
- root["frameCount"] = (Json::Value::Int)data.threadInfo.frameCount;
- root["sampleRate"] = (Json::Value::Int)data.threadInfo.sampleRate;
+ root["ioHandle"] = data.threadInfo.id;
+ root["type"] = NBLog::threadTypeToString(data.threadInfo.type);
+ root["frameCount"] = (Json::Value::Int)data.threadParams.frameCount;
+ root["sampleRate"] = (Json::Value::Int)data.threadParams.sampleRate;
root["workMsHist"] = data.workHist.toString();
root["latencyMsHist"] = data.latencyHist.toString();
root["warmupMsHist"] = data.warmupHist.toString();
@@ -57,6 +58,61 @@
return rootPtr;
}
+static std::string dumpHistogramsToString(const PerformanceData& data)
+{
+ std::stringstream ss;
+ ss << "==========================================\n";
+ ss << "Thread type=" << NBLog::threadTypeToString(data.threadInfo.type)
+ << " handle=" << data.threadInfo.id
+ << " sampleRate=" << data.threadParams.sampleRate
+ << " frameCount=" << data.threadParams.frameCount << "\n";
+ ss << " Thread work times in ms:\n" << data.workHist.asciiArtString(4 /*indent*/);
+ ss << " Thread latencies in ms:\n" << data.latencyHist.asciiArtString(4 /*indent*/);
+ ss << " Thread warmup times in ms:\n" << data.warmupHist.asciiArtString(4 /*indent*/);
+ return ss.str();
+}
+
+void dumpJson(int fd, const std::map<int, PerformanceData>& threadDataMap)
+{
+ if (fd < 0) {
+ return;
+ }
+
+ Json::Value root(Json::arrayValue);
+ for (const auto& item : threadDataMap) {
+ const ReportPerformance::PerformanceData& data = item.second;
+ // Skip threads that do not have performance data recorded yet.
+ if (data.empty()) {
+ continue;
+ }
+ std::unique_ptr<Json::Value> dataJson = ReportPerformance::dumpToJson(data);
+ if (dataJson == nullptr) {
+ continue;
+ }
+ (*dataJson)["threadNum"] = item.first;
+ root.append(*dataJson);
+ }
+ Json::StyledWriter writer;
+ std::string rootStr = writer.write(root);
+ write(fd, rootStr.c_str(), rootStr.size());
+}
+
+void dumpPlots(int fd, const std::map<int, PerformanceData>& threadDataMap)
+{
+ if (fd < 0) {
+ return;
+ }
+
+ for (const auto &item : threadDataMap) {
+ const ReportPerformance::PerformanceData& data = item.second;
+ if (data.empty()) {
+ continue;
+ }
+ std::string hists = ReportPerformance::dumpHistogramsToString(data);
+ write(fd, hists.c_str(), hists.size());
+ }
+}
+
bool sendToMediaMetrics(const PerformanceData& data)
{
// See documentation for these metrics here:
@@ -72,6 +128,11 @@
static constexpr char kThreadActive[] = "android.media.audiothread.activeMs";
static constexpr char kThreadDuration[] = "android.media.audiothread.durationMs";
+ // Currently, we only allow FastMixer thread data to be sent to Media Metrics.
+ if (data.threadInfo.type != NBLog::FASTMIXER) {
+ return false;
+ }
+
std::unique_ptr<MediaAnalyticsItem> item(new MediaAnalyticsItem("audiothread"));
const Histogram &workHist = data.workHist;
@@ -104,8 +165,8 @@
// Add thread info fields.
const char * const typeString = NBLog::threadTypeToString(data.threadInfo.type);
item->setCString(kThreadType, typeString);
- item->setInt32(kThreadFrameCount, data.threadInfo.frameCount);
- item->setInt32(kThreadSampleRate, data.threadInfo.sampleRate);
+ item->setInt32(kThreadFrameCount, data.threadParams.frameCount);
+ item->setInt32(kThreadSampleRate, data.threadParams.sampleRate);
// Add time info fields.
item->setInt64(kThreadActive, data.active / 1000000);
item->setInt64(kThreadDuration, (systemTime() - data.start) / 1000000);