Add API usage and reliability metrics.
Test: manual
Bug: 254050429
Change-Id: I733658923b2c38996df4009972447a07cb717502
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 09c5d64..080c3d0 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -118,15 +118,6 @@
static const char *kCodecCaptureRate = "android.media.mediacodec.capture-rate";
static const char *kCodecOperatingRate = "android.media.mediacodec.operating-rate";
static const char *kCodecPriority = "android.media.mediacodec.priority";
-static const char *kCodecConfigColorStandard = "android.media.mediacodec.config-color-standard";
-static const char *kCodecConfigColorRange = "android.media.mediacodec.config-color-range";
-static const char *kCodecConfigColorTransfer = "android.media.mediacodec.config-color-transfer";
-static const char *kCodecParsedColorStandard = "android.media.mediacodec.parsed-color-standard";
-static const char *kCodecParsedColorRange = "android.media.mediacodec.parsed-color-range";
-static const char *kCodecParsedColorTransfer = "android.media.mediacodec.parsed-color-transfer";
-static const char *kCodecHDRStaticInfo = "android.media.mediacodec.hdr-static-info";
-static const char *kCodecHDR10PlusInfo = "android.media.mediacodec.hdr10-plus-info";
-static const char *kCodecHDRFormat = "android.media.mediacodec.hdr-format";
// Min/Max QP before shaping
static const char *kCodecOriginalVideoQPIMin = "android.media.mediacodec.original-video-qp-i-min";
@@ -175,6 +166,29 @@
static const char *kCodecVideoInputBytes = "android.media.mediacodec.video.input.bytes";
static const char *kCodecVideoInputFrames = "android.media.mediacodec.video.input.frames";
static const char *kCodecVideoEncodedDurationUs = "android.media.mediacodec.vencode.durationUs";
+// HDR metrics
+static const char *kCodecConfigColorStandard = "android.media.mediacodec.config-color-standard";
+static const char *kCodecConfigColorRange = "android.media.mediacodec.config-color-range";
+static const char *kCodecConfigColorTransfer = "android.media.mediacodec.config-color-transfer";
+static const char *kCodecParsedColorStandard = "android.media.mediacodec.parsed-color-standard";
+static const char *kCodecParsedColorRange = "android.media.mediacodec.parsed-color-range";
+static const char *kCodecParsedColorTransfer = "android.media.mediacodec.parsed-color-transfer";
+static const char *kCodecHDRStaticInfo = "android.media.mediacodec.hdr-static-info";
+static const char *kCodecHDR10PlusInfo = "android.media.mediacodec.hdr10-plus-info";
+static const char *kCodecHDRFormat = "android.media.mediacodec.hdr-format";
+// array/sync/async/block modes
+static const char *kCodecArrayMode = "android.media.mediacodec.array-mode";
+static const char *kCodecOperationMode = "android.media.mediacodec.operation-mode";
+static const char *kCodecOutputSurface = "android.media.mediacodec.output-surface";
+// max size configured by the app
+static const char *kCodecAppMaxInputSize = "android.media.mediacodec.app-max-input-size";
+// max size actually used
+static const char *kCodecUsedMaxInputSize = "android.media.mediacodec.used-max-input-size";
+// max size suggested by the codec
+static const char *kCodecCodecMaxInputSize = "android.media.mediacodec.codec-max-input-size";
+static const char *kCodecFlushCount = "android.media.mediacodec.flush-count";
+static const char *kCodecSetSurfaceCount = "android.media.mediacodec.set-surface-count";
+static const char *kCodecResolutionChangeCount = "android.media.mediacodec.resolution-change-count";
// the kCodecRecent* fields appear only in getMetrics() results
static const char *kCodecRecentLatencyMax = "android.media.mediacodec.recent.max"; /* in us */
@@ -935,7 +949,6 @@
mWidth(0),
mHeight(0),
mRotationDegrees(0),
- mHdrInfoFlags(0),
mDequeueInputTimeoutGeneration(0),
mDequeueInputReplyID(0),
mDequeueOutputTimeoutGeneration(0),
@@ -1043,6 +1056,14 @@
}
mLifetimeStartNs = systemTime(SYSTEM_TIME_MONOTONIC);
+ resetMetricsFields();
+}
+
+void MediaCodec::resetMetricsFields() {
+ mHdrInfoFlags = 0;
+
+ mApiUsageMetrics = ApiUsageMetrics();
+ mReliabilityContextMetrics = ReliabilityContextMetrics();
}
void MediaCodec::updateMediametrics() {
@@ -1053,6 +1074,28 @@
Mutex::Autolock _lock(mMetricsLock);
+ mediametrics_setInt32(mMetricsHandle, kCodecArrayMode, mApiUsageMetrics.isArrayMode ? 1 : 0);
+ mApiUsageMetrics.operationMode = (mFlags & kFlagIsAsync) ?
+ ((mFlags & kFlagUseBlockModel) ? ApiUsageMetrics::kBlockMode
+ : ApiUsageMetrics::kAsynchronousMode)
+ : ApiUsageMetrics::kSynchronousMode;
+ mediametrics_setInt32(mMetricsHandle, kCodecOperationMode, mApiUsageMetrics.operationMode);
+ mediametrics_setInt32(mMetricsHandle, kCodecOutputSurface,
+ mApiUsageMetrics.isUsingOutputSurface ? 1 : 0);
+
+ mediametrics_setInt32(mMetricsHandle, kCodecAppMaxInputSize,
+ mApiUsageMetrics.inputBufferSize.appMax);
+ mediametrics_setInt32(mMetricsHandle, kCodecUsedMaxInputSize,
+ mApiUsageMetrics.inputBufferSize.usedMax);
+ mediametrics_setInt32(mMetricsHandle, kCodecCodecMaxInputSize,
+ mApiUsageMetrics.inputBufferSize.codecMax);
+
+ mediametrics_setInt32(mMetricsHandle, kCodecFlushCount, mReliabilityContextMetrics.flushCount);
+ mediametrics_setInt32(mMetricsHandle, kCodecSetSurfaceCount,
+ mReliabilityContextMetrics.setOutputSurfaceCount);
+ mediametrics_setInt32(mMetricsHandle, kCodecResolutionChangeCount,
+ mReliabilityContextMetrics.resolutionChangeCount);
+
if (mLatencyHist.getCount() != 0 ) {
mediametrics_setInt64(mMetricsHandle, kCodecLatencyMax, mLatencyHist.getMax());
mediametrics_setInt64(mMetricsHandle, kCodecLatencyMin, mLatencyHist.getMin());
@@ -1295,7 +1338,7 @@
// update does its own mutex locking
updateMediametrics();
- mHdrInfoFlags = 0;
+ resetMetricsFields();
// ensure mutex while we do our own work
Mutex::Autolock _lock(mMetricsLock);
@@ -1967,6 +2010,10 @@
if (format->findInt32("color-format", &colorFormat)) {
mediametrics_setInt32(nextMetricsHandle, kCodecColorFormat, colorFormat);
}
+ int32_t appMaxInputSize = -1;
+ if (format->findInt32(KEY_MAX_INPUT_SIZE, &appMaxInputSize)) {
+ mApiUsageMetrics.inputBufferSize.appMax = appMaxInputSize;
+ }
if (mDomain == DOMAIN_VIDEO) {
float frameRate = -1.0;
if (format->findFloat("frame-rate", &frameRate)) {
@@ -3768,6 +3815,10 @@
mediametrics_setInt32(mMetricsHandle, kCodecLevel, level);
}
updateHdrMetrics(true /* isConfig */);
+ int32_t codecMaxInputSize = -1;
+ if (mInputFormat->findInt32(KEY_MAX_INPUT_SIZE, &codecMaxInputSize)) {
+ mApiUsageMetrics.inputBufferSize.codecMax = codecMaxInputSize;
+ }
// bitrate and bitrate mode, encoder only
if (mFlags & kFlagIsEncoder) {
// encoder specific values
@@ -4168,6 +4219,7 @@
setState(STARTED);
mCodec->signalResume();
}
+ mReliabilityContextMetrics.flushCount++;
postPendingRepliesAndDeferredMessages("kWhatFlushCompleted");
break;
@@ -4328,6 +4380,8 @@
handleSetSurface(NULL);
}
+ mApiUsageMetrics.isUsingOutputSurface = true;
+
uint32_t flags;
CHECK(msg->findInt32("flags", (int32_t *)&flags));
if (flags & CONFIGURE_FLAG_USE_BLOCK_MODEL ||
@@ -4468,6 +4522,7 @@
(void)disconnectFromSurface();
mSurface = surface;
}
+ mReliabilityContextMetrics.setOutputSurfaceCount++;
}
}
break;
@@ -5005,6 +5060,8 @@
}
}
+ mApiUsageMetrics.isArrayMode = true;
+
(new AMessage)->postReply(replyID);
break;
}
@@ -5273,6 +5330,7 @@
ClientConfigParcel clientConfig;
initClientConfigParcel(clientConfig);
mResourceManagerProxy->notifyClientConfigChanged(clientConfig);
+ mReliabilityContextMetrics.resolutionChangeCount++;
}
updateHdrMetrics(false /* isConfig */);
@@ -5708,6 +5766,10 @@
if (err != OK) {
return -EINVAL;
}
+
+ int32_t usedMaxInputSize = mApiUsageMetrics.inputBufferSize.usedMax;
+ mApiUsageMetrics.inputBufferSize.usedMax = size > usedMaxInputSize ? size : usedMaxInputSize;
+
if (hasCryptoOrDescrambler() && !c2Buffer && !memory) {
AString *errorDetailMsg;
CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 1cc281b..3d4b6f8 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -453,6 +453,7 @@
void initMediametrics();
void updateMediametrics();
void flushMediametrics();
+ void resetMetricsFields();
void updateEphemeralMediametrics(mediametrics_handle_t item);
void updateLowLatency(const sp<AMessage> &msg);
void onGetMetrics(const sp<AMessage>& msg);
@@ -492,6 +493,28 @@
const int32_t colorTransfer);
bool profileSupport10Bits(const AString &mime, const int32_t profile);
+ struct ApiUsageMetrics {
+ bool isArrayMode;
+ enum OperationMode {
+ kUnknownMode = 0,
+ kSynchronousMode = 1,
+ kAsynchronousMode = 2,
+ kBlockMode = 3,
+ };
+ OperationMode operationMode;
+ bool isUsingOutputSurface;
+ struct InputBufferSize {
+ int32_t appMax; // max size configured by the app
+ int32_t usedMax; // max size actually used
+ int32_t codecMax; // max size suggested by the codec
+ } inputBufferSize;
+ } mApiUsageMetrics;
+ struct ReliabilityContextMetrics {
+ int32_t flushCount;
+ int32_t setOutputSurfaceCount;
+ int32_t resolutionChangeCount;
+ } mReliabilityContextMetrics;
+
// initial create parameters
AString mInitName;
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index cb5e783..158914a 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -438,7 +438,7 @@
}
AStatsEvent_writeInt32(event, hdr10PlusInfo);
- int32_t hdrFormat= -1;
+ int32_t hdrFormat = -1;
if (item->getInt32("android.media.mediacodec.hdr-format", &hdrFormat)) {
metrics_proto.set_hdr_format(hdrFormat);
}
@@ -450,6 +450,61 @@
}
AStatsEvent_writeInt64(event, codecId);
+ int32_t arrayMode = -1;
+ if (item->getInt32("android.media.mediacodec.array-mode", &arrayMode)) {
+ metrics_proto.set_array_mode(arrayMode);
+ }
+ AStatsEvent_writeInt32(event, arrayMode);
+
+ int32_t operationMode = -1;
+ if (item->getInt32("android.media.mediacodec.operation-mode", &operationMode)) {
+ metrics_proto.set_operation_mode(operationMode);
+ }
+ AStatsEvent_writeInt32(event, operationMode);
+
+ int32_t outputSurface = -1;
+ if (item->getInt32("android.media.mediacodec.output-surface", &outputSurface)) {
+ metrics_proto.set_output_surface(outputSurface);
+ }
+ AStatsEvent_writeInt32(event, outputSurface);
+
+ int32_t appMaxInputSize = -1;
+ if (item->getInt32("android.media.mediacodec.app-max-input-size", &appMaxInputSize)) {
+ metrics_proto.set_app_max_input_size(appMaxInputSize);
+ }
+ AStatsEvent_writeInt32(event, appMaxInputSize);
+
+ int32_t usedMaxInputSize = -1;
+ if (item->getInt32("android.media.mediacodec.used-max-input-size", &usedMaxInputSize)) {
+ metrics_proto.set_used_max_input_size(usedMaxInputSize);
+ }
+ AStatsEvent_writeInt32(event, usedMaxInputSize);
+
+ int32_t codecMaxInputSize = -1;
+ if (item->getInt32("android.media.mediacodec.codec-max-input-size", &codecMaxInputSize)) {
+ metrics_proto.set_codec_max_input_size(codecMaxInputSize);
+ }
+ AStatsEvent_writeInt32(event, codecMaxInputSize);
+
+ int32_t flushCount = -1;
+ if (item->getInt32("android.media.mediacodec.flush-count", &flushCount)) {
+ metrics_proto.set_flush_count(flushCount);
+ }
+ AStatsEvent_writeInt32(event, flushCount);
+
+ int32_t setSurfaceCount = -1;
+ if (item->getInt32("android.media.mediacodec.set-surface-count", &setSurfaceCount)) {
+ metrics_proto.set_set_surface_count(setSurfaceCount);
+ }
+ AStatsEvent_writeInt32(event, setSurfaceCount);
+
+ int32_t resolutionChangeCount = -1;
+ if (item->getInt32("android.media.mediacodec.resolution-change-count",
+ &resolutionChangeCount)) {
+ metrics_proto.set_resolution_change_count(resolutionChangeCount);
+ }
+ AStatsEvent_writeInt32(event, resolutionChangeCount);
+
int err = AStatsEvent_write(event);
if (err < 0) {
ALOGE("Failed to write codec metrics to statsd (%d)", err);