blob: f55ca3bbc5cdd52849bfc61ebc683ce0608543c3 [file] [log] [blame]
/*
* 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 "absl/types/optional.h"
#include "test/gmock.h"
#include "test/gtest.h"
namespace webrtc {
namespace test {
namespace {
using ::testing::Return;
using ::testing::Values;
} // namespace
TEST(VideoCodecStatsImpl, AddFrame) {
VideoCodecStatsImpl stats;
VideoCodecStatsImpl::Frame* fs =
stats.AddFrame(/*frame_num=*/0, /*timestamp_rtp=*/0, /*spatial_idx=*/0);
EXPECT_NE(nullptr, fs);
fs = stats.GetFrame(/*timestamp_rtp=*/0, /*spatial_idx=*/0);
EXPECT_NE(nullptr, fs);
}
TEST(VideoCodecStatsImpl, GetFrame) {
VideoCodecStatsImpl stats;
stats.AddFrame(/*frame_num=*/0, /*timestamp_rtp=*/0, /*spatial_idx=*/0);
VideoCodecStatsImpl::Frame* fs =
stats.GetFrame(/*timestamp_rtp=*/0, /*spatial_idx=*/0);
EXPECT_NE(nullptr, fs);
}
struct VideoCodecStatsSlicingTestParams {
VideoCodecStats::Filter slicer;
std::vector<VideoCodecStats::Frame> expected;
};
class VideoCodecStatsSlicingTest
: public ::testing::TestWithParam<VideoCodecStatsSlicingTestParams> {
public:
void SetUp() {
// TODO(ssikin): Hard codec 2x2 table would be better.
for (int frame_num = 0; frame_num < 2; ++frame_num) {
for (int spatial_idx = 0; spatial_idx < 2; ++spatial_idx) {
uint32_t timestamp_rtp = 3000 * frame_num;
VideoCodecStats::Frame* f =
stats_.AddFrame(frame_num, timestamp_rtp, spatial_idx);
f->temporal_idx = frame_num;
}
}
}
protected:
VideoCodecStatsImpl stats_;
};
TEST_P(VideoCodecStatsSlicingTest, Slice) {
VideoCodecStatsSlicingTestParams test_params = GetParam();
std::vector<VideoCodecStats::Frame> frames = stats_.Slice(test_params.slicer);
EXPECT_EQ(frames.size(), test_params.expected.size());
}
INSTANTIATE_TEST_SUITE_P(All,
VideoCodecStatsSlicingTest,
::testing::ValuesIn({VideoCodecStatsSlicingTestParams(
{.slicer = {.first_frame = 0, .last_frame = 1},
.expected = {{.frame_num = 0},
{.frame_num = 1},
{.frame_num = 0},
{.frame_num = 1}}})}));
struct VideoCodecStatsAggregationTestParams {
VideoCodecStats::Filter slicer;
struct Expected {
double decode_time_us;
} expected;
};
class VideoCodecStatsAggregationTest
: public ::testing::TestWithParam<VideoCodecStatsAggregationTestParams> {
public:
void SetUp() {
// TODO(ssikin): Hard codec 2x2 table would be better. Share with
// VideoCodecStatsSlicingTest
for (int frame_num = 0; frame_num < 2; ++frame_num) {
for (int spatial_idx = 0; spatial_idx < 2; ++spatial_idx) {
uint32_t timestamp_rtp = 3000 * frame_num;
VideoCodecStats::Frame* f =
stats_.AddFrame(frame_num, timestamp_rtp, spatial_idx);
f->temporal_idx = frame_num;
f->decode_time = TimeDelta::Micros(spatial_idx * 10 + frame_num);
f->encoded = true;
f->decoded = true;
}
}
}
protected:
VideoCodecStatsImpl stats_;
};
TEST_P(VideoCodecStatsAggregationTest, Aggregate) {
VideoCodecStatsAggregationTestParams test_params = GetParam();
std::vector<VideoCodecStats::Frame> frames = stats_.Slice(test_params.slicer);
VideoCodecStats::Stream stream = stats_.Aggregate(frames);
EXPECT_EQ(stream.decode_time_us.GetAverage(),
test_params.expected.decode_time_us);
}
INSTANTIATE_TEST_SUITE_P(
All,
VideoCodecStatsAggregationTest,
::testing::ValuesIn(
{VideoCodecStatsAggregationTestParams(
{.slicer = {},
.expected = {.decode_time_us = (0.0 + 1.0 + 10.0 + 11.0) / 2}}),
// Slicing on frame number
VideoCodecStatsAggregationTestParams(
{.slicer = {.first_frame = 1, .last_frame = 1},
.expected = {.decode_time_us = 1.0 + 11.0}}),
// Slice on spatial index
VideoCodecStatsAggregationTestParams(
{.slicer = {.spatial_idx = 1},
.expected = {.decode_time_us = (10.0 + 11.0) / 2}}),
// Slice on temporal index
VideoCodecStatsAggregationTestParams(
{.slicer = {.temporal_idx = 0},
.expected = {.decode_time_us = 0.0 + 10.0}})}));
} // namespace test
} // namespace webrtc