123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602 |
- // Copyright 2022 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <map>
- #include <memory>
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/callback_helpers.h"
- #include "base/check.h"
- #include "base/files/file_path.h"
- #include "base/memory/ptr_util.h"
- #include "base/memory/raw_ptr.h"
- #include "base/run_loop.h"
- #include "base/strings/string_number_conversions.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/simple_test_clock.h"
- #include "base/test/task_environment.h"
- #include "components/leveldb_proto/testing/fake_db.h"
- #include "media/base/media_switches.h"
- #include "media/base/test_data_util.h"
- #include "media/base/video_codecs.h"
- #include "media/capabilities/webrtc_video_stats.pb.h"
- #include "media/capabilities/webrtc_video_stats_db_impl.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "ui/gfx/geometry/size.h"
- using leveldb_proto::test::FakeDB;
- using testing::_;
- using testing::Eq;
- using testing::Pointee;
- namespace media {
- class WebrtcVideoStatsDBImplTest : public ::testing::Test {
- public:
- using VideoDescKey = WebrtcVideoStatsDB::VideoDescKey;
- using VideoStats = WebrtcVideoStatsDB::VideoStats;
- using VideoStatsEntry = WebrtcVideoStatsDB::VideoStatsEntry;
- WebrtcVideoStatsDBImplTest()
- : kDecodeStatsKeyVp9(
- VideoDescKey::MakeBucketedKey(/*is_decode_stats=*/true,
- VP9PROFILE_PROFILE3,
- /*hardware_accelerated=*/false,
- 1280 * 720)),
- kDecodeStatsKeyVp9Hw(
- VideoDescKey::MakeBucketedKey(/*is_decode_stats=*/true,
- VP9PROFILE_PROFILE3,
- /*hardware_accelerated=*/true,
- 1280 * 720)),
- kDecodeStatsKeyVp9FullHd(
- VideoDescKey::MakeBucketedKey(/*is_decode_stats=*/true,
- VP9PROFILE_PROFILE3,
- /*hardware_accelerated=*/false,
- 1920 * 1080)),
- kDecodeStatsKeyVp94K(
- VideoDescKey::MakeBucketedKey(/*is_decode_stats=*/true,
- VP9PROFILE_PROFILE3,
- /*hardware_accelerated=*/false,
- 3840 * 2160)),
- kDecodeStatsKeyH264(
- VideoDescKey::MakeBucketedKey(/*is_decode_stats=*/true,
- H264PROFILE_MIN,
- /*hardware_accelerated=*/false,
- 1920 * 1080)),
- kEncodeStatsKeyVp9(
- VideoDescKey::MakeBucketedKey(/*is_decode_stats=*/false,
- VP9PROFILE_PROFILE3,
- /*hardware_accelerated=*/false,
- 1280 * 720)) {
- // Fake DB simply wraps a std::map with the LevelDB interface. We own the
- // map and will delete it in TearDown().
- fake_db_map_ =
- std::make_unique<FakeDB<WebrtcVideoStatsEntryProto>::EntryMap>();
- // `stats_db_` will own this pointer, but we hold a reference to control
- // its behavior.
- fake_db_ = new FakeDB<WebrtcVideoStatsEntryProto>(fake_db_map_.get());
- // Wrap the fake proto DB with our interface.
- stats_db_ = base::WrapUnique(new WebrtcVideoStatsDBImpl(
- std::unique_ptr<FakeDB<WebrtcVideoStatsEntryProto>>(fake_db_)));
- }
- WebrtcVideoStatsDBImplTest(const WebrtcVideoStatsDBImplTest&) = delete;
- WebrtcVideoStatsDBImplTest& operator=(const WebrtcVideoStatsDBImplTest&) =
- delete;
- ~WebrtcVideoStatsDBImplTest() override {
- // Tests should always complete any pending operations
- VerifyNoPendingOps();
- }
- void VerifyOnePendingOp(std::string op_name) {
- EXPECT_EQ(stats_db_->pending_operations_.get_pending_ops_for_test().size(),
- 1u);
- PendingOperations::PendingOperation* pending_op =
- stats_db_->pending_operations_.get_pending_ops_for_test()
- .begin()
- ->second.get();
- EXPECT_EQ(pending_op->uma_str_, op_name);
- }
- void VerifyNoPendingOps() {
- EXPECT_TRUE(
- stats_db_->pending_operations_.get_pending_ops_for_test().empty());
- }
- base::TimeDelta GetMaxTimeToKeepStats() {
- return WebrtcVideoStatsDBImpl::GetMaxTimeToKeepStats();
- }
- int GetMaxEntriesPerConfig() {
- return WebrtcVideoStatsDBImpl::GetMaxEntriesPerConfig();
- }
- void SetDBClock(base::Clock* clock) {
- stats_db_->set_wall_clock_for_test(clock);
- }
- void InitializeDB() {
- stats_db_->Initialize(base::BindOnce(
- &WebrtcVideoStatsDBImplTest::OnInitialize, base::Unretained(this)));
- EXPECT_CALL(*this, OnInitialize(true));
- fake_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK);
- testing::Mock::VerifyAndClearExpectations(this);
- }
- void AppendStats(const VideoDescKey& key, const VideoStats& entry) {
- EXPECT_CALL(*this, MockAppendVideoStatsCb(true));
- stats_db_->AppendVideoStats(
- key, entry,
- base::BindOnce(&WebrtcVideoStatsDBImplTest::MockAppendVideoStatsCb,
- base::Unretained(this)));
- VerifyOnePendingOp("Read");
- fake_db_->GetCallback(true);
- VerifyOnePendingOp("Write");
- fake_db_->UpdateCallback(true);
- testing::Mock::VerifyAndClearExpectations(this);
- }
- void VerifyReadStats(const VideoDescKey& key,
- const VideoStatsEntry& expected) {
- EXPECT_CALL(*this,
- MockGetVideoStatsCb(true, absl::make_optional(expected)));
- stats_db_->GetVideoStats(
- key, base::BindOnce(&WebrtcVideoStatsDBImplTest::MockGetVideoStatsCb,
- base::Unretained(this)));
- VerifyOnePendingOp("Read");
- fake_db_->GetCallback(true);
- testing::Mock::VerifyAndClearExpectations(this);
- }
- void VerifyReadStatsCollection(
- const VideoDescKey& key,
- const WebrtcVideoStatsDB::VideoStatsCollection& expected) {
- EXPECT_CALL(*this, MockGetVideoStatsCollectionCb(
- true, absl::make_optional(expected)));
- stats_db_->GetVideoStatsCollection(
- key, base::BindOnce(
- &WebrtcVideoStatsDBImplTest::MockGetVideoStatsCollectionCb,
- base::Unretained(this)));
- VerifyOnePendingOp("Read");
- fake_db_->LoadCallback(true);
- testing::Mock::VerifyAndClearExpectations(this);
- }
- void VerifyEmptyStats(const VideoDescKey& key) {
- EXPECT_CALL(*this,
- MockGetVideoStatsCb(true, absl::optional<VideoStatsEntry>()));
- stats_db_->GetVideoStats(
- key, base::BindOnce(&WebrtcVideoStatsDBImplTest::MockGetVideoStatsCb,
- base::Unretained(this)));
- VerifyOnePendingOp("Read");
- fake_db_->GetCallback(true);
- testing::Mock::VerifyAndClearExpectations(this);
- }
- void AppendToProtoDB(const VideoDescKey& key,
- const WebrtcVideoStatsEntryProto* const proto) {
- base::RunLoop run_loop;
- base::OnceCallback<void(bool)> update_done_cb = base::BindOnce(
- [](base::RunLoop* run_loop, bool success) {
- ASSERT_TRUE(success);
- run_loop->Quit();
- },
- Unretained(&run_loop));
- using DBType = leveldb_proto::ProtoDatabase<WebrtcVideoStatsEntryProto>;
- std::unique_ptr<DBType::KeyEntryVector> entries =
- std::make_unique<DBType::KeyEntryVector>();
- entries->emplace_back(key.Serialize(), *proto);
- fake_db_->UpdateEntries(std::move(entries),
- std::make_unique<leveldb_proto::KeyVector>(),
- std::move(update_done_cb));
- fake_db_->UpdateCallback(true);
- run_loop.Run();
- }
- MOCK_METHOD1(OnInitialize, void(bool success));
- MOCK_METHOD2(MockGetVideoStatsCb,
- void(bool success, absl::optional<VideoStatsEntry> entry));
- MOCK_METHOD2(MockGetVideoStatsCollectionCb,
- void(bool success,
- absl::optional<WebrtcVideoStatsDB::VideoStatsCollection>
- collection));
- MOCK_METHOD1(MockAppendVideoStatsCb, void(bool success));
- MOCK_METHOD0(MockClearStatsCb, void());
- protected:
- base::test::TaskEnvironment task_environment_{
- base::test::TaskEnvironment::TimeSource::MOCK_TIME};
- const VideoDescKey kDecodeStatsKeyVp9;
- const VideoDescKey kDecodeStatsKeyVp9Hw;
- const VideoDescKey kDecodeStatsKeyVp9FullHd;
- const VideoDescKey kDecodeStatsKeyVp94K;
- const VideoDescKey kDecodeStatsKeyH264;
- const VideoDescKey kEncodeStatsKeyVp9;
- // See documentation in SetUp()
- std::unique_ptr<FakeDB<WebrtcVideoStatsEntryProto>::EntryMap> fake_db_map_;
- raw_ptr<FakeDB<WebrtcVideoStatsEntryProto>> fake_db_;
- std::unique_ptr<WebrtcVideoStatsDBImpl> stats_db_;
- };
- TEST_F(WebrtcVideoStatsDBImplTest, InitializeFailed) {
- stats_db_->Initialize(base::BindOnce(
- &WebrtcVideoStatsDBImplTest::OnInitialize, base::Unretained(this)));
- EXPECT_CALL(*this, OnInitialize(false));
- fake_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kError);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, InitializeTimedOut) {
- // Queue up an Initialize.
- stats_db_->Initialize(base::BindOnce(
- &WebrtcVideoStatsDBImplTest::OnInitialize, base::Unretained(this)));
- VerifyOnePendingOp("Initialize");
- // Move time forward enough to trigger timeout.
- EXPECT_CALL(*this, OnInitialize(_)).Times(0);
- task_environment_.FastForwardBy(base::Seconds(100));
- task_environment_.RunUntilIdle();
- // Verify we didn't get an init callback and task is no longer considered
- // pending (because it timed out).
- testing::Mock::VerifyAndClearExpectations(this);
- VerifyNoPendingOps();
- // Verify callback still works if init completes very late.
- EXPECT_CALL(*this, OnInitialize(false));
- fake_db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kError);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, ReadExpectingNothing) {
- InitializeDB();
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, WriteReadAndClear) {
- InitializeDB();
- // Set test clock.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Append and read back some VP9 stats.
- VideoStats stats1(clock.Now().ToJsTimeIgnoringNull(), 240, 6, 7.2);
- VideoStatsEntry entry{stats1};
- AppendStats(kDecodeStatsKeyVp9, stats1);
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- // Reading with the wrong key (different codec) should still return nothing.
- VerifyEmptyStats(kDecodeStatsKeyH264);
- VerifyEmptyStats(kEncodeStatsKeyVp9);
- // Appending new VP9 stats.
- clock.Advance(base::Hours(1));
- VideoStats stats2(clock.Now().ToJsTimeIgnoringNull(), 1000, 14, 6.8);
- AppendStats(kDecodeStatsKeyVp9, stats2);
- VideoStatsEntry aggregate_entry{stats2, stats1};
- VerifyReadStats(kDecodeStatsKeyVp9, aggregate_entry);
- // Clear all stats from the DB.
- EXPECT_CALL(*this, MockClearStatsCb);
- stats_db_->ClearStats(base::BindOnce(
- &WebrtcVideoStatsDBImplTest::MockClearStatsCb, base::Unretained(this)));
- VerifyOnePendingOp("Clear");
- fake_db_->UpdateCallback(true);
- // Database is now empty. Expect null entry.
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, ExpiredStatsAreNotReturned) {
- InitializeDB();
- // Set test clock.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Append and read back some VP9 stats.
- VideoStats stats1(clock.Now().ToJsTimeIgnoringNull(), 240, 6, 7.2);
- VideoStatsEntry entry{stats1};
- AppendStats(kDecodeStatsKeyVp9, stats1);
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- // Appending new VP9 stats.
- clock.Advance(base::Days(2));
- VideoStats stats2(clock.Now().ToJsTimeIgnoringNull(), 1000, 14, 6.8);
- clock.SetNow(base::Time::FromJsTime(stats2.timestamp));
- AppendStats(kDecodeStatsKeyVp9, stats2);
- VideoStatsEntry aggregate_entry{stats2, stats1};
- VerifyReadStats(kDecodeStatsKeyVp9, aggregate_entry);
- // Set the clock to a date so that the first entry is expired.
- clock.SetNow(base::Time::FromJsTime(stats1.timestamp) + base::Days(1) +
- GetMaxTimeToKeepStats());
- VideoStatsEntry nonexpired_entry{stats2};
- VerifyReadStats(kDecodeStatsKeyVp9, nonexpired_entry);
- // Set the clock so that all data have expired.
- clock.SetNow(base::Time::FromJsTime(stats2.timestamp) + base::Days(1) +
- GetMaxTimeToKeepStats());
- // All stats are expired. Expect null entry.
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, ConfigureExpireDays) {
- base::test::ScopedFeatureList scoped_feature_list;
- std::unique_ptr<base::FieldTrialList> field_trial_list;
- base::TimeDelta previous_max_days_to_keep_stats = GetMaxTimeToKeepStats();
- constexpr int kNewMaxDaysToKeepStats = 4;
- ASSERT_LT(base::Days(kNewMaxDaysToKeepStats),
- previous_max_days_to_keep_stats);
- // Override field trial.
- base::FieldTrialParams params;
- params["db_days_to_keep_stats"] =
- base::NumberToString(kNewMaxDaysToKeepStats);
- scoped_feature_list.InitAndEnableFeatureWithParameters(
- media::kWebrtcMediaCapabilitiesParameters, params);
- EXPECT_EQ(base::Days(kNewMaxDaysToKeepStats), GetMaxTimeToKeepStats());
- InitializeDB();
- // Inject a test clock and initialize with the current time.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Append and verify read-back.
- VideoStats stats1(clock.Now().ToJsTimeIgnoringNull(), 240, 6, 7.2);
- VideoStatsEntry entry{stats1};
- AppendStats(kDecodeStatsKeyVp9, stats1);
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- // Some simple math to avoid troubles of integer division.
- int half_days_to_keep_stats = kNewMaxDaysToKeepStats / 2;
- int remaining_days_to_keep_stats =
- kNewMaxDaysToKeepStats - half_days_to_keep_stats;
- // Advance time half way through grace period. Verify stats not expired.
- clock.Advance(base::Days(half_days_to_keep_stats));
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- // Advance time 1 day beyond grace period, verify stats are expired.
- clock.Advance(base::Days(remaining_days_to_keep_stats + 1));
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- // Advance the clock 100 extra days. Verify stats still expired.
- clock.Advance(base::Days(100));
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, NewStatsReplaceOldStats) {
- InitializeDB();
- // Inject a test clock and initialize with the current time.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Append and verify read-back.
- constexpr int kNumberOfStatsToAdd = 30;
- EXPECT_GT(kNumberOfStatsToAdd, GetMaxEntriesPerConfig());
- VideoStatsEntry entry;
- for (int i = 0; i < kNumberOfStatsToAdd; ++i) {
- VideoStats stats(clock.Now().ToJsTimeIgnoringNull(), 240 + i, 6,
- 7.2 + i % 3);
- AppendStats(kDecodeStatsKeyVp9, stats);
- // Start popping the last stats entry if the number of entries has reached
- // the limit.
- if (i >= GetMaxEntriesPerConfig()) {
- entry.pop_back();
- }
- entry.insert(entry.begin(), stats);
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- clock.Advance(base::Days(1));
- }
- }
- TEST_F(WebrtcVideoStatsDBImplTest, ConfigureMaxEntriesPerConfig) {
- base::test::ScopedFeatureList scoped_feature_list;
- std::unique_ptr<base::FieldTrialList> field_trial_list;
- int previous_max_entries_per_config = GetMaxEntriesPerConfig();
- constexpr int kNewMaxEntriesPerConfig = 3;
- ASSERT_LT(kNewMaxEntriesPerConfig, previous_max_entries_per_config);
- // Override field trial.
- base::FieldTrialParams params;
- params["db_max_entries_per_cpnfig"] =
- base::NumberToString(kNewMaxEntriesPerConfig);
- scoped_feature_list.InitAndEnableFeatureWithParameters(
- media::kWebrtcMediaCapabilitiesParameters, params);
- EXPECT_EQ(kNewMaxEntriesPerConfig, GetMaxEntriesPerConfig());
- InitializeDB();
- // Inject a test clock and initialize with the current time.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Append and verify read-back.
- constexpr int kNumberOfStatsToAdd = 30;
- EXPECT_GT(kNumberOfStatsToAdd, GetMaxEntriesPerConfig());
- VideoStatsEntry entry;
- for (int i = 0; i < kNumberOfStatsToAdd; ++i) {
- VideoStats stats(clock.Now().ToJsTimeIgnoringNull(), 240 + i, 6,
- 7.2 + i % 3);
- AppendStats(kDecodeStatsKeyVp9, stats);
- // Start popping the last stats entry if the number of entries has reached
- // the limit.
- if (i >= GetMaxEntriesPerConfig()) {
- entry.pop_back();
- }
- entry.insert(entry.begin(), stats);
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- clock.Advance(base::Days(1));
- }
- }
- TEST_F(WebrtcVideoStatsDBImplTest, OutOfOrderTimestampClearsOldStats) {
- InitializeDB();
- // Inject a test clock and initialize with the current time.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Append and verify read-back.
- constexpr int kNumberOfStatsToAdd = 5;
- VideoStatsEntry entry;
- for (int i = 0; i < kNumberOfStatsToAdd; ++i) {
- VideoStats stats(clock.Now().ToJsTimeIgnoringNull(), 240 + i, 6,
- 7.2 + i % 3);
- AppendStats(kDecodeStatsKeyVp9, stats);
- entry.insert(entry.begin(), stats);
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- clock.Advance(base::Days(1));
- }
- // Go back in time and add a new stats entry.
- clock.Advance(-base::Days(20));
- VideoStats stats(clock.Now().ToJsTimeIgnoringNull(), 123, 5, 11.2);
- AppendStats(kDecodeStatsKeyVp9, stats);
- // Only the last appended stats should be in the database now.
- entry = {stats};
- VerifyReadStats(kDecodeStatsKeyVp9, entry);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, FailedWrite) {
- InitializeDB();
- // Expect the callback to indicate success = false when the write fails.
- EXPECT_CALL(*this, MockAppendVideoStatsCb(false));
- // Append stats, but fail the internal DB update.
- stats_db_->AppendVideoStats(
- kDecodeStatsKeyVp9, VideoStats(1234, 240, 6, 7.2),
- base::BindOnce(&WebrtcVideoStatsDBImplTest::MockAppendVideoStatsCb,
- base::Unretained(this)));
- fake_db_->GetCallback(true);
- fake_db_->UpdateCallback(false);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, DiscardCorruptedDBData) {
- InitializeDB();
- // Inject a test clock and initialize with the current time.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Start with a proto that represents a valid uncorrupted and unexpired entry.
- WebrtcVideoStatsEntryProto valid_proto;
- WebrtcVideoStatsProto* valid_entry = valid_proto.add_stats();
- valid_entry->set_timestamp(clock.Now().ToJsTimeIgnoringNull());
- valid_entry->set_frames_processed(300);
- valid_entry->set_key_frames_processed(8);
- valid_entry->set_p99_processing_time_ms(11.3);
- // Append it and read it back without issue.
- AppendToProtoDB(kEncodeStatsKeyVp9, &valid_proto);
- VerifyReadStats(
- kEncodeStatsKeyVp9,
- {VideoStats{valid_entry->timestamp(), valid_entry->frames_processed(),
- valid_entry->key_frames_processed(),
- valid_entry->p99_processing_time_ms()}});
- WebrtcVideoStatsEntryProto invalid_proto;
- WebrtcVideoStatsProto* invalid_entry = invalid_proto.add_stats();
- // Invalid because number of frames processed is too low Verify
- // you can't read it back (filtered for corruption).
- *invalid_entry = *valid_entry;
- invalid_entry->set_frames_processed(30);
- AppendToProtoDB(kDecodeStatsKeyVp9, &invalid_proto);
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- // Invalid because number of frames processed is too high. Verify
- // you can't read it back (filtered for corruption).
- *invalid_entry = *valid_entry;
- invalid_entry->set_frames_processed(1000000);
- AppendToProtoDB(kDecodeStatsKeyVp9, &invalid_proto);
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- // Invalid because number of key frames is higher than number of frames
- // processed. Verify you can't read it back (filtered for corruption).
- *invalid_entry = *valid_entry;
- invalid_entry->set_key_frames_processed(valid_entry->frames_processed() + 1);
- AppendToProtoDB(kDecodeStatsKeyVp9, &invalid_proto);
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- // Invalid processing time. Verify
- // you can't read it back (filtered for corruption).
- *invalid_entry = *valid_entry;
- invalid_entry->set_p99_processing_time_ms(-1.0);
- AppendToProtoDB(kDecodeStatsKeyVp9, &invalid_proto);
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- *invalid_entry = *valid_entry;
- invalid_entry->set_p99_processing_time_ms(20000.0);
- AppendToProtoDB(kDecodeStatsKeyVp9, &invalid_proto);
- VerifyEmptyStats(kDecodeStatsKeyVp9);
- }
- TEST_F(WebrtcVideoStatsDBImplTest, WriteAndReadCollection) {
- InitializeDB();
- // Set test clock.
- base::SimpleTestClock clock;
- SetDBClock(&clock);
- clock.SetNow(base::Time::Now());
- // Append stats for multiple resolutions.
- VideoStats stats1(clock.Now().ToJsTimeIgnoringNull(), 240, 6, 7.2);
- VideoStatsEntry entry1{stats1};
- AppendStats(kDecodeStatsKeyVp9, stats1);
- VideoStats stats2(clock.Now().ToJsTimeIgnoringNull(), 360, 7, 9.2);
- VideoStatsEntry entry2{stats2};
- AppendStats(kDecodeStatsKeyVp9FullHd, stats2);
- VideoStats stats3(clock.Now().ToJsTimeIgnoringNull(), 480, 11, 13.3);
- VideoStatsEntry entry3{stats3};
- AppendStats(kDecodeStatsKeyVp94K, stats3);
- // Add elements that should not be returned.
- VideoStats stats4(clock.Now().ToJsTimeIgnoringNull(), 490, 13, 15.3);
- AppendStats(kEncodeStatsKeyVp9, stats4);
- AppendStats(kDecodeStatsKeyVp9Hw, stats4);
- // Created the expected collection that should be returned.
- WebrtcVideoStatsDB::VideoStatsCollection expected;
- expected.insert({kDecodeStatsKeyVp9.pixels, entry1});
- expected.insert({kDecodeStatsKeyVp9FullHd.pixels, entry2});
- expected.insert({kDecodeStatsKeyVp94K.pixels, entry3});
- // The same collection is returned for all keys that are associated to the
- // collection.
- VerifyReadStatsCollection(kDecodeStatsKeyVp9, expected);
- VerifyReadStatsCollection(kDecodeStatsKeyVp9FullHd, expected);
- VerifyReadStatsCollection(kDecodeStatsKeyVp94K, expected);
- }
- } // namespace media
|