Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85ab4353 authored by Brian Lindahl's avatar Brian Lindahl Committed by Automerger Merge Worker
Browse files

Provide more flexible scoring algorithms am: d9e39c7a am: c0d4c124

parents 9714ffa4 c0d4c124
Loading
Loading
Loading
Loading
+4 −10
Original line number Original line Diff line number Diff line
@@ -323,11 +323,8 @@ const VideoRenderQualityMetrics &VideoRenderQualityTracker::getMetrics() {
    if (mConfiguration.freezeDurationMsHistogramToScore.size() ==
    if (mConfiguration.freezeDurationMsHistogramToScore.size() ==
        mMetrics.freezeDurationMsHistogram.size()) {
        mMetrics.freezeDurationMsHistogram.size()) {
        for (int i = 0; i < mMetrics.freezeDurationMsHistogram.size(); ++i) {
        for (int i = 0; i < mMetrics.freezeDurationMsHistogram.size(); ++i) {
            int32_t count = 0;
            mMetrics.freezeScore += mMetrics.freezeDurationMsHistogram[i] *
            for (int j = i; j < mMetrics.freezeDurationMsHistogram.size(); ++j) {
                    mConfiguration.freezeDurationMsHistogramToScore[i];
                count += mMetrics.freezeDurationMsHistogram[j];
            }
            mMetrics.freezeScore += count / mConfiguration.freezeDurationMsHistogramToScore[i];
        }
        }
    }
    }
    mMetrics.freezeRate = float(double(mMetrics.freezeDurationMsHistogram.getSum()) /
    mMetrics.freezeRate = float(double(mMetrics.freezeDurationMsHistogram.getSum()) /
@@ -336,11 +333,8 @@ const VideoRenderQualityMetrics &VideoRenderQualityTracker::getMetrics() {
    mMetrics.judderScore = 0;
    mMetrics.judderScore = 0;
    if (mConfiguration.judderScoreHistogramToScore.size() == mMetrics.judderScoreHistogram.size()) {
    if (mConfiguration.judderScoreHistogramToScore.size() == mMetrics.judderScoreHistogram.size()) {
        for (int i = 0; i < mMetrics.judderScoreHistogram.size(); ++i) {
        for (int i = 0; i < mMetrics.judderScoreHistogram.size(); ++i) {
            int32_t count = 0;
            mMetrics.judderScore += mMetrics.judderScoreHistogram[i] *
            for (int j = i; j < mMetrics.judderScoreHistogram.size(); ++j) {
                    mConfiguration.judderScoreHistogramToScore[i];
                count += mMetrics.judderScoreHistogram[j];
            }
            mMetrics.judderScore += count / mConfiguration.judderScoreHistogramToScore[i];
        }
        }
    }
    }
    mMetrics.judderRate = float(double(mMetrics.judderScoreHistogram.getCount()) /
    mMetrics.judderRate = float(double(mMetrics.judderScoreHistogram.getCount()) /
+32 −7
Original line number Original line Diff line number Diff line
@@ -62,7 +62,13 @@ struct VideoRenderQualityMetrics {


    // A histogram of the durations of freezes due to dropped/skipped frames.
    // A histogram of the durations of freezes due to dropped/skipped frames.
    MediaHistogram<int32_t> freezeDurationMsHistogram;
    MediaHistogram<int32_t> freezeDurationMsHistogram;
    // The computed overall freeze score using the above histogram and score conversion table.
    // The computed overall freeze score using the above histogram and score conversion table. The
    // score is based on counts in the histogram bucket, multiplied by the value in the score
    // conversion table for that bucket. For example, the impact of a short freeze may be minimal,
    // but the impact of long freeze may be disproportionally worse. Therefore, the score
    // multipliers for each bucket might increase exponentially instead of linearly. A score
    // multiplier of zero would reflect that small freeze durations have near-zero impact to the
    // user experience.
    int32_t freezeScore;
    int32_t freezeScore;
    // The computed percentage of total playback duration that was frozen.
    // The computed percentage of total playback duration that was frozen.
    float freezeRate;
    float freezeRate;
@@ -72,9 +78,16 @@ struct VideoRenderQualityMetrics {
    // A histogram of the durations between each freeze.
    // A histogram of the durations between each freeze.
    MediaHistogram<int32_t> freezeDistanceMsHistogram;
    MediaHistogram<int32_t> freezeDistanceMsHistogram;


    // A histogram of the judder scores.
    // A histogram of the judder scores - based on the error tolerance between actual render
    // duration of each frame and the ideal render duration.
    MediaHistogram<int32_t> judderScoreHistogram;
    MediaHistogram<int32_t> judderScoreHistogram;
    // The computed overall judder score using the above histogram and score conversion table.
    // The computed overall judder score using the above histogram and score conversion table. The
    // score is based on counts in the histogram bucket, multiplied by the value in the score
    // conversion table for that bucket. For example, the impact of minimal judder may be small,
    // but the impact of large judder may be disproportionally worse. Therefore, the score
    // multipliers for each bucket might increase exponentially instead of linearly. A score
    // multiplier of zero would reflect that small judder errors have near-zero impact to the user
    // experience.
    int32_t judderScore;
    int32_t judderScore;
    // The computed percentage of total frames that had judder.
    // The computed percentage of total frames that had judder.
    float judderRate;
    float judderRate;
@@ -143,15 +156,21 @@ public:
        //
        //
        // The values used to distribute freeze durations across a histogram.
        // The values used to distribute freeze durations across a histogram.
        std::vector<int32_t> freezeDurationMsHistogramBuckets;
        std::vector<int32_t> freezeDurationMsHistogramBuckets;
        // The values used to compare against freeze duration counts when determining an overall
        //
        // score.
        // The values used to multiply the counts in the histogram buckets above to compute an
        // overall score. This allows the score to reflect disproportionate impact as freeze
        // durations increase.
        std::vector<int64_t> freezeDurationMsHistogramToScore;
        std::vector<int64_t> freezeDurationMsHistogramToScore;
        //
        // The values used to distribute distances between freezes across a histogram.
        // The values used to distribute distances between freezes across a histogram.
        std::vector<int32_t> freezeDistanceMsHistogramBuckets;
        std::vector<int32_t> freezeDistanceMsHistogramBuckets;
        //
        // The maximum number of freeze events to send back to the caller.
        // The maximum number of freeze events to send back to the caller.
        int32_t freezeEventMax;
        int32_t freezeEventMax;
        //
        // The maximum number of detail entries tracked per freeze event.
        // The maximum number of detail entries tracked per freeze event.
        int32_t freezeEventDetailsMax;
        int32_t freezeEventDetailsMax;
        //
        // The maximum distance in time between two freeze occurrences such that both will be
        // The maximum distance in time between two freeze occurrences such that both will be
        // lumped into the same freeze event.
        // lumped into the same freeze event.
        int32_t freezeEventDistanceToleranceMs;
        int32_t freezeEventDistanceToleranceMs;
@@ -160,15 +179,21 @@ public:
        //
        //
        // A judder error lower than this value is not scored as judder.
        // A judder error lower than this value is not scored as judder.
        int32_t judderErrorToleranceUs;
        int32_t judderErrorToleranceUs;
        //
        // The values used to distribute judder scores across a histogram.
        // The values used to distribute judder scores across a histogram.
        std::vector<int32_t> judderScoreHistogramBuckets;
        std::vector<int32_t> judderScoreHistogramBuckets;
        // The values used to compare against judder score histogram counts when determining an
        //
        // overall score.
        // The values used to multiply the counts in the histogram buckets above to compute an
        // overall score. This allows the score to reflect disproportionate impact as judder scores
        // increase.
        std::vector<int64_t> judderScoreHistogramToScore;
        std::vector<int64_t> judderScoreHistogramToScore;
        //
        // The maximum number of judder events to send back to the caller.
        // The maximum number of judder events to send back to the caller.
        int32_t judderEventMax;
        int32_t judderEventMax;
        //
        // The maximum number of detail entries tracked per judder event.
        // The maximum number of detail entries tracked per judder event.
        int32_t judderEventDetailsMax;
        int32_t judderEventDetailsMax;
        //
        // The maximum distance in time between two judder occurrences such that both will be
        // The maximum distance in time between two judder occurrences such that both will be
        // lumped into the same judder event.
        // lumped into the same judder event.
        int32_t judderEventDistanceToleranceMs;
        int32_t judderEventDistanceToleranceMs;
+38 −0
Original line number Original line Diff line number Diff line
@@ -912,4 +912,42 @@ TEST_F(VideoRenderQualityTrackerTest, capturesJudderEvents) {
    EXPECT_EQ(h.getAndClearJudderEvent().valid, false); // max number of judder events exceeded
    EXPECT_EQ(h.getAndClearJudderEvent().valid, false); // max number of judder events exceeded
}
}


TEST_F(VideoRenderQualityTrackerTest, capturesOverallFreezeScore) {
    Configuration c;
    // # drops * 20ms + 20ms because current frame is frozen + 1 for bucket threshold
    c.freezeDurationMsHistogramBuckets = {1 * 20 + 21, 5 * 20 + 21, 10 * 20 + 21};
    c.freezeDurationMsHistogramToScore = {10, 100, 1000};
    Helper h(20, c);
    h.render(5);
    h.drop(2); // bucket = 0, bucket count = 1, bucket score = 10
    h.render(5);
    h.drop(11); // bucket = 2, bucket count = 1, bucket score = 1000
    h.render(5);
    h.drop(6); // bucket = 1, bucket count = 1, bucket score = 100
    h.render(5);
    h.drop(1); // bucket = null
    h.render(5);
    h.drop(3); // bucket = 0, bucket count = 2, bucket score = 20
    h.render(5);
    h.drop(10); // bucket = 1, bucket count = 2, bucket score = 200
    h.render(5);
    h.drop(7); // bucket = 1, bucket count = 3, bucket score = 300
    h.render(5);
    EXPECT_EQ(h.getMetrics().freezeScore, 20 + 300 + 1000);
}

TEST_F(VideoRenderQualityTrackerTest, capturesOverallJudderScore) {
    Configuration c;
    c.judderScoreHistogramBuckets = {0, 6, 10};
    c.judderScoreHistogramToScore = {10, 100, 1000};
    Helper h(20, c);
    h.render({20, 20, 15, 20, 20}); // bucket = 0, bucket count = 1, bucket score = 10
    h.render({20, 20, 11, 20, 20}); // bucket = 1, bucket count = 1, bucket score = 100
    h.render({20, 20, 13, 20, 20}); // bucket = 1, bucket count = 2, bucket score = 200
    h.render({20, 20,  5, 20, 20}); // bucket = 2, bucket count = 1, bucket score = 1000
    h.render({20, 20, 14, 20, 20}); // bucket = 1, bucket count = 3, bucket score = 300
    h.render({20, 20, 10, 20, 20}); // bucket = 2, bucket count = 2, bucket score = 2000
    EXPECT_EQ(h.getMetrics().judderScore, 10 + 300 + 2000);
}

} // android
} // android