blob: 5f1614339266c0d3d597285a9b6084507ce9ea49 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <string>
#include "media/base/video_codecs.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/geometry/rect.h"
#include "media/capabilities/webrtc_video_stats_db.h"
namespace media {
const auto MakeKey = WebrtcVideoStatsDB::VideoDescKey::MakeBucketedKey;
const auto ParsePixelsFromKey =
WebrtcVideoStatsDB::VideoDescKey::ParsePixelsFromKey;
TEST(WebrtcVideoStatsDBTest, KeySerialization) {
// Serialized key with empty KeySystem string should not mention encryption
// fields.
auto keyA = MakeKey(/*is_decode_stats=*/true, H264PROFILE_BASELINE,
/*hardware_accelerated=*/true, 1280 * 720);
EXPECT_EQ("1|0|1|921600", keyA.Serialize());
// No hardware acceleration.
auto keyB = MakeKey(/*is_decode_stats=*/true, H264PROFILE_BASELINE,
/*hardware_accelerated=*/false, 1280 * 720);
EXPECT_EQ("1|0|0|921600", keyB.Serialize());
// VP9 Profile 2.
auto keyC = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/false, 1280 * 720);
EXPECT_EQ("1|14|0|921600", keyC.Serialize());
// Full HD.
auto keyD = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/false, 1920 * 1080);
EXPECT_EQ("1|14|0|2073600", keyD.Serialize());
// Encode.
auto keyE = MakeKey(/*is_decode_stats=*/false, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/false, 1920 * 1080);
EXPECT_EQ("0|14|0|2073600", keyE.Serialize());
// 4K.
auto keyF = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/false, 3840 * 2160);
EXPECT_EQ("1|14|0|8294400", keyF.Serialize());
}
TEST(WebrtcVideoStatsDBTest, OperatorEquals) {
auto keyA = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true, 1280 * 720);
EXPECT_EQ(keyA, keyA);
auto keyB = keyA;
EXPECT_EQ(keyA, keyB);
// Vary each of the fields in `keyA` and verify != `keyA`
EXPECT_NE(keyA, MakeKey(/*is_decode_stats=*/false, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true, 1280 * 720));
EXPECT_NE(keyA, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/true, 1280 * 720));
EXPECT_NE(keyA, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true, 1920 * 1080));
EXPECT_NE(keyA, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/false, 1280 * 720));
}
TEST(WebrtcVideoStatsDBTest, PixelSizeBucketting) {
auto keyA = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true, 1280 * 720);
// Verify that keys are equal even if the pixel size varies slightly.
for (int pixel_size_delta = -10000; pixel_size_delta <= 10000;
pixel_size_delta += 1000) {
EXPECT_EQ(keyA, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true,
1280 * 720 + pixel_size_delta));
}
// Even 0 and negative number of pixels are quantized to the first bucket.
EXPECT_EQ(keyA, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true,
/*pixels=*/0));
EXPECT_EQ(keyA, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true,
/*pixels=*/-10));
// A high number of pixels is quantized to the last bucket.
auto keyB = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true, 3840 * 2160);
EXPECT_EQ(keyB, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true,
/*pixels=*/1e9));
}
TEST(WebrtcVideoStatsDBTest, CodecProfileBucketting) {
// All H264 profiles are mapped to the same key.
auto keyA = MakeKey(/*is_decode_stats=*/true, H264PROFILE_BASELINE,
/*hardware_accelerated=*/true, 1280 * 720);
for (int i = H264PROFILE_MIN; i <= H264PROFILE_MAX; ++i) {
EXPECT_EQ(keyA, MakeKey(/*is_decode_stats=*/true,
static_cast<VideoCodecProfile>(i),
/*hardware_accelerated=*/true, 1280 * 720));
}
// VP9 is not mapped to the same key as H264.
EXPECT_NE(keyA, MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true, 1280 * 720));
// All AV1 profiles are mapped to the same key.
auto keyB = MakeKey(/*is_decode_stats=*/true, AV1PROFILE_PROFILE_MAIN,
/*hardware_accelerated=*/true, 1280 * 720);
for (int i = AV1PROFILE_MIN; i <= AV1PROFILE_MAX; ++i) {
EXPECT_EQ(keyB, MakeKey(/*is_decode_stats=*/true,
static_cast<VideoCodecProfile>(i),
/*hardware_accelerated=*/true, 1280 * 720));
}
// Verify that the standard profiles are correctly returned.
auto keyC = MakeKey(/*is_decode_stats=*/true, VP8PROFILE_MIN,
/*hardware_accelerated=*/true, 1280 * 720);
EXPECT_EQ(keyC.codec_profile, VP8PROFILE_MIN);
auto keyD = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE0,
/*hardware_accelerated=*/true, 1280 * 720);
EXPECT_EQ(keyD.codec_profile, VP9PROFILE_PROFILE0);
auto keyE = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/true, 1280 * 720);
EXPECT_EQ(keyE.codec_profile, VP9PROFILE_PROFILE2);
// Dolby vision is currently not supported by WebRTC and therefore not
// tracked.
auto keyF = MakeKey(/*is_decode_stats=*/true, DOLBYVISION_PROFILE8,
/*hardware_accelerated=*/true, 1280 * 720);
EXPECT_EQ(keyF.codec_profile, VIDEO_CODEC_PROFILE_UNKNOWN);
}
TEST(WebrtcVideoStatsDBTest, ParsePixelsFromKey) {
// Valid formats on the form: "0|XX|1|YYY"
// HD
auto keyA = MakeKey(/*is_decode_stats=*/true, H264PROFILE_BASELINE,
/*hardware_accelerated=*/true, 1280 * 720);
EXPECT_EQ(keyA.pixels, ParsePixelsFromKey(keyA.Serialize()));
// Full HD.
auto keyB = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/false, 1920 * 1080);
EXPECT_EQ(keyB.pixels, ParsePixelsFromKey(keyB.Serialize()));
// 4K.
auto keyC = MakeKey(/*is_decode_stats=*/true, VP9PROFILE_PROFILE2,
/*hardware_accelerated=*/false, 3840 * 2160);
EXPECT_EQ(keyC.pixels, ParsePixelsFromKey(keyC.Serialize()));
// Invalid key serializations.
EXPECT_FALSE(ParsePixelsFromKey(""));
EXPECT_FALSE(ParsePixelsFromKey("|||"));
EXPECT_FALSE(ParsePixelsFromKey("|||123"));
EXPECT_FALSE(ParsePixelsFromKey("0|1|0|"));
EXPECT_FALSE(ParsePixelsFromKey("0|12|0|"));
}
} // namespace media