additional codec-related media metrics
Audio: samplerate + channel count
Video: video encoding: bytes, duration, #frames
Bug: 181054340
Test: dumpsys media.metrics
Change-Id: I4e5ae07e07070ec355ed0dfbce42a9fa1d25b8ff
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 61a6ae9..d96b48b 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -118,6 +118,11 @@
static const char *kCodecNumLowLatencyModeOn = "android.media.mediacodec.low-latency.on"; /* 0..n */
static const char *kCodecNumLowLatencyModeOff = "android.media.mediacodec.low-latency.off"; /* 0..n */
static const char *kCodecFirstFrameIndexLowLatencyModeOn = "android.media.mediacodec.low-latency.first-frame"; /* 0..n */
+static const char *kCodecChannelCount = "android.media.mediacodec.channelCount";
+static const char *kCodecSampleRate = "android.media.mediacodec.sampleRate";
+static const char *kCodecVideoEncodedBytes = "android.media.mediacodec.vencode.bytes";
+static const char *kCodecVideoEncodedFrames = "android.media.mediacodec.vencode.frames";
+static const char *kCodecVideoEncodedDurationUs = "android.media.mediacodec.vencode.durationUs";
// the kCodecRecent* fields appear only in getMetrics() results
static const char *kCodecRecentLatencyMax = "android.media.mediacodec.recent.max"; /* in us */
@@ -695,6 +700,10 @@
mHavePendingInputBuffers(false),
mCpuBoostRequested(false),
mLatencyUnknown(0),
+ mBytesEncoded(0),
+ mEarliestEncodedPtsUs(INT64_MAX),
+ mLatestEncodedPtsUs(INT64_MIN),
+ mFramesEncoded(0),
mNumLowLatencyEnables(0),
mNumLowLatencyDisables(0),
mIsLowLatencyModeOn(false),
@@ -802,6 +811,18 @@
mediametrics_setInt64(mMetricsHandle, kCodecLifetimeMs, lifetime);
}
+ if (mBytesEncoded) {
+ Mutex::Autolock al(mOutputStatsLock);
+
+ mediametrics_setInt64(mMetricsHandle, kCodecVideoEncodedBytes, mBytesEncoded);
+ int64_t duration = 0;
+ if (mLatestEncodedPtsUs > mEarliestEncodedPtsUs) {
+ duration = mLatestEncodedPtsUs - mEarliestEncodedPtsUs;
+ }
+ mediametrics_setInt64(mMetricsHandle, kCodecVideoEncodedDurationUs, duration);
+ mediametrics_setInt64(mMetricsHandle, kCodecVideoEncodedFrames, mFramesEncoded);
+ }
+
{
Mutex::Autolock al(mLatencyLock);
mediametrics_setInt64(mMetricsHandle, kCodecNumLowLatencyModeOn, mNumLowLatencyEnables);
@@ -1005,10 +1026,34 @@
}
// when we get a buffer back from the codec
-void MediaCodec::statsBufferReceived(int64_t presentationUs) {
+void MediaCodec::statsBufferReceived(int64_t presentationUs, const sp<MediaCodecBuffer> &buffer) {
CHECK_NE(mState, UNINITIALIZED);
+ if (mIsVideo && (mFlags & kFlagIsEncoder)) {
+ int32_t flags = 0;
+ (void) buffer->meta()->findInt32("flags", &flags);
+
+ // some of these frames, we don't want to count
+ // standalone EOS.... has an invalid timestamp
+ if ((flags & (BUFFER_FLAG_CODECCONFIG|BUFFER_FLAG_EOS)) == 0) {
+ mBytesEncoded += buffer->size();
+ mFramesEncoded++;
+
+ Mutex::Autolock al(mOutputStatsLock);
+ int64_t timeUs = 0;
+ if (buffer->meta()->findInt64("timeUs", &timeUs)) {
+ if (timeUs > mLatestEncodedPtsUs) {
+ mLatestEncodedPtsUs = timeUs;
+ }
+ // can't chain as an else-if or this never triggers
+ if (timeUs < mEarliestEncodedPtsUs) {
+ mEarliestEncodedPtsUs = timeUs;
+ }
+ }
+ }
+ }
+
// mutex access to mBuffersInFlight and other stats
Mutex::Autolock al(mLatencyLock);
@@ -1064,7 +1109,7 @@
return;
}
- // nowNs start our calculations
+ // now start our calculations
const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
int64_t latencyUs = (nowNs - startdata.startedNs + 500) / 1000;
@@ -1337,6 +1382,17 @@
ALOGE("Invalid size(s), width=%d, height=%d", mVideoWidth, mVideoHeight);
return BAD_VALUE;
}
+ } else {
+ if (mMetricsHandle != 0) {
+ int32_t channelCount;
+ if (format->findInt32(KEY_CHANNEL_COUNT, &channelCount)) {
+ mediametrics_setInt32(mMetricsHandle, kCodecChannelCount, channelCount);
+ }
+ int32_t sampleRate;
+ if (format->findInt32(KEY_SAMPLE_RATE, &sampleRate)) {
+ mediametrics_setInt32(mMetricsHandle, kCodecSampleRate, sampleRate);
+ }
+ }
}
updateLowLatency(format);
@@ -2183,14 +2239,15 @@
int64_t timeUs;
CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
- statsBufferReceived(timeUs);
-
response->setInt64("timeUs", timeUs);
int32_t flags;
CHECK(buffer->meta()->findInt32("flags", &flags));
response->setInt32("flags", flags);
+
+ statsBufferReceived(timeUs, buffer);
+
response->postReply(replyID);
}
@@ -4332,13 +4389,13 @@
msg->setInt64("timeUs", timeUs);
- statsBufferReceived(timeUs);
-
int32_t flags;
CHECK(buffer->meta()->findInt32("flags", &flags));
msg->setInt32("flags", flags);
+ statsBufferReceived(timeUs, buffer);
+
msg->post();
}
}
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index a28d479..5f64686 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -528,6 +528,14 @@
std::deque<BufferFlightTiming_t> mBuffersInFlight;
Mutex mLatencyLock;
int64_t mLatencyUnknown; // buffers for which we couldn't calculate latency
+
+ Mutex mOutputStatsLock;
+ int64_t mBytesEncoded = 0;
+ int64_t mEarliestEncodedPtsUs = INT64_MAX;
+ int64_t mLatestEncodedPtsUs = INT64_MIN;
+ int32_t mFramesEncoded = 0;
+
+
int64_t mNumLowLatencyEnables; // how many times low latency mode is enabled
int64_t mNumLowLatencyDisables; // how many times low latency mode is disabled
bool mIsLowLatencyModeOn; // is low latency mode on currently
@@ -544,7 +552,7 @@
sp<BatteryChecker> mBatteryChecker;
void statsBufferSent(int64_t presentationUs);
- void statsBufferReceived(int64_t presentationUs);
+ void statsBufferReceived(int64_t presentationUs, const sp<MediaCodecBuffer> &buffer);
enum {
// the default shape of our latency histogram buckets
diff --git a/services/mediametrics/statsd_codec.cpp b/services/mediametrics/statsd_codec.cpp
index d502b30..1c5ab77 100644
--- a/services/mediametrics/statsd_codec.cpp
+++ b/services/mediametrics/statsd_codec.cpp
@@ -186,6 +186,16 @@
metrics_proto.set_lifetime_millis(lifetimeMs);
}
+ // new for S; need to plumb through to westworld
+ // android.media.mediacodec.channelCount int32
+ // android.media.mediacodec.sampleRate int32
+
+ // new for S; need to plumb through to westworld
+ // TODO PWG may want these fuzzed up a bit to obscure some precision
+ // android.media.mediacodec.vencode.bytes int64
+ // android.media.mediacodec.vencode.frames int64
+ // android.media.mediacodec.vencode.durationUs int64
+
std::string serialized;
if (!metrics_proto.SerializeToString(&serialized)) {
ALOGE("Failed to serialize codec metrics");