summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl_unittest.cc')
-rw-r--r--third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl_unittest.cc148
1 files changed, 148 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl_unittest.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl_unittest.cc
new file mode 100644
index 0000000000..ce11d5abe6
--- /dev/null
+++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_stats_impl_unittest.cc
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "modules/video_coding/codecs/test/video_codec_stats_impl.h"
+
+#include <tuple>
+
+#include "absl/types/optional.h"
+#include "test/gmock.h"
+#include "test/gtest.h"
+
+namespace webrtc {
+namespace test {
+
+namespace {
+using ::testing::Return;
+using ::testing::Values;
+using Filter = VideoCodecStats::Filter;
+using Frame = VideoCodecStatsImpl::Frame;
+using Stream = VideoCodecStats::Stream;
+} // namespace
+
+TEST(VideoCodecStatsImpl, AddAndGetFrame) {
+ VideoCodecStatsImpl stats;
+ stats.AddFrame({.timestamp_rtp = 0, .spatial_idx = 0});
+ stats.AddFrame({.timestamp_rtp = 0, .spatial_idx = 1});
+ stats.AddFrame({.timestamp_rtp = 1, .spatial_idx = 0});
+
+ Frame* fs = stats.GetFrame(/*timestamp_rtp=*/0, /*spatial_idx=*/0);
+ ASSERT_NE(fs, nullptr);
+ EXPECT_EQ(fs->timestamp_rtp, 0u);
+ EXPECT_EQ(fs->spatial_idx, 0);
+
+ fs = stats.GetFrame(/*timestamp_rtp=*/0, /*spatial_idx=*/1);
+ ASSERT_NE(fs, nullptr);
+ EXPECT_EQ(fs->timestamp_rtp, 0u);
+ EXPECT_EQ(fs->spatial_idx, 1);
+
+ fs = stats.GetFrame(/*timestamp_rtp=*/1, /*spatial_idx=*/0);
+ ASSERT_NE(fs, nullptr);
+ EXPECT_EQ(fs->timestamp_rtp, 1u);
+ EXPECT_EQ(fs->spatial_idx, 0);
+
+ fs = stats.GetFrame(/*timestamp_rtp=*/1, /*spatial_idx=*/1);
+ EXPECT_EQ(fs, nullptr);
+}
+
+class VideoCodecStatsImplSlicingTest
+ : public ::testing::TestWithParam<std::tuple<Filter, std::vector<int>>> {};
+
+TEST_P(VideoCodecStatsImplSlicingTest, Slice) {
+ Filter filter = std::get<0>(GetParam());
+ std::vector<int> expected_frames = std::get<1>(GetParam());
+ std::vector<VideoCodecStats::Frame> frames = {
+ {.frame_num = 0, .timestamp_rtp = 0, .spatial_idx = 0, .temporal_idx = 0},
+ {.frame_num = 0, .timestamp_rtp = 0, .spatial_idx = 1, .temporal_idx = 0},
+ {.frame_num = 1, .timestamp_rtp = 1, .spatial_idx = 0, .temporal_idx = 1},
+ {.frame_num = 1,
+ .timestamp_rtp = 1,
+ .spatial_idx = 1,
+ .temporal_idx = 1}};
+
+ VideoCodecStatsImpl stats;
+ stats.AddFrame(frames[0]);
+ stats.AddFrame(frames[1]);
+ stats.AddFrame(frames[2]);
+ stats.AddFrame(frames[3]);
+
+ std::vector<VideoCodecStats::Frame> slice = stats.Slice(filter);
+ ASSERT_EQ(slice.size(), expected_frames.size());
+ for (size_t i = 0; i < expected_frames.size(); ++i) {
+ Frame& expected = frames[expected_frames[i]];
+ EXPECT_EQ(slice[i].frame_num, expected.frame_num);
+ EXPECT_EQ(slice[i].timestamp_rtp, expected.timestamp_rtp);
+ EXPECT_EQ(slice[i].spatial_idx, expected.spatial_idx);
+ EXPECT_EQ(slice[i].temporal_idx, expected.temporal_idx);
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ All,
+ VideoCodecStatsImplSlicingTest,
+ ::testing::Values(
+ std::make_tuple(Filter{}, std::vector<int>{0, 1, 2, 3}),
+ std::make_tuple(Filter{.first_frame = 1}, std::vector<int>{2, 3}),
+ std::make_tuple(Filter{.last_frame = 0}, std::vector<int>{0, 1}),
+ std::make_tuple(Filter{.spatial_idx = 0}, std::vector<int>{0, 2}),
+ std::make_tuple(Filter{.temporal_idx = 1},
+ std::vector<int>{0, 1, 2, 3})));
+
+TEST(VideoCodecStatsImpl, AggregateBitrate) {
+ std::vector<VideoCodecStats::Frame> frames = {
+ {.frame_num = 0,
+ .timestamp_rtp = 0,
+ .frame_size = DataSize::Bytes(1000),
+ .target_bitrate = DataRate::BytesPerSec(1000)},
+ {.frame_num = 1,
+ .timestamp_rtp = 90000,
+ .frame_size = DataSize::Bytes(2000),
+ .target_bitrate = DataRate::BytesPerSec(1000)}};
+
+ Stream stream = VideoCodecStatsImpl().Aggregate(frames);
+ EXPECT_EQ(stream.encoded_bitrate_kbps.GetAverage(), 12.0);
+ EXPECT_EQ(stream.bitrate_mismatch_pct.GetAverage(), 50.0);
+}
+
+TEST(VideoCodecStatsImpl, AggregateFramerate) {
+ std::vector<VideoCodecStats::Frame> frames = {
+ {.frame_num = 0,
+ .timestamp_rtp = 0,
+ .frame_size = DataSize::Bytes(1),
+ .target_framerate = Frequency::Hertz(1)},
+ {.frame_num = 1,
+ .timestamp_rtp = 90000,
+ .frame_size = DataSize::Zero(),
+ .target_framerate = Frequency::Hertz(1)}};
+
+ Stream stream = VideoCodecStatsImpl().Aggregate(frames);
+ EXPECT_EQ(stream.encoded_framerate_fps.GetAverage(), 0.5);
+ EXPECT_EQ(stream.framerate_mismatch_pct.GetAverage(), -50.0);
+}
+
+TEST(VideoCodecStatsImpl, AggregateTransmissionTime) {
+ std::vector<VideoCodecStats::Frame> frames = {
+ {.frame_num = 0,
+ .timestamp_rtp = 0,
+ .frame_size = DataSize::Bytes(2),
+ .target_bitrate = DataRate::BytesPerSec(1)},
+ {.frame_num = 1,
+ .timestamp_rtp = 90000,
+ .frame_size = DataSize::Bytes(3),
+ .target_bitrate = DataRate::BytesPerSec(1)}};
+
+ Stream stream = VideoCodecStatsImpl().Aggregate(frames);
+ ASSERT_EQ(stream.transmission_time_ms.NumSamples(), 2);
+ ASSERT_EQ(stream.transmission_time_ms.GetSamples()[0], 2000);
+ ASSERT_EQ(stream.transmission_time_ms.GetSamples()[1], 4000);
+}
+
+} // namespace test
+} // namespace webrtc