| /* |
| * Copyright (c) 2026 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 "video/timing/simulator/frame_base.h" |
| |
| #include <cstdint> |
| #include <vector> |
| |
| #include "api/units/time_delta.h" |
| #include "api/units/timestamp.h" |
| #include "test/gtest.h" |
| |
| namespace webrtc::video_timing_simulator { |
| namespace { |
| |
| constexpr int64_t kMicrosPerMillis = 1000; |
| constexpr int64_t kRtpVideoTicksPerMillis = 90; |
| |
| struct TestFrame : public FrameBase<TestFrame> { |
| int64_t unwrapped_rtp_timestamp = -1; |
| Timestamp assembled_timestamp = Timestamp::PlusInfinity(); |
| Timestamp ArrivalTimestampInternal() const { return assembled_timestamp; } |
| }; |
| |
| TEST(FrameBaseTest, DepartureTimestamp) { |
| TestFrame frame{.unwrapped_rtp_timestamp = 3000}; |
| EXPECT_EQ(frame.DepartureTimestamp(), Timestamp::Micros(33333)); |
| } |
| |
| TEST(FrameBaseTest, DepartureTimestampWithOffset) { |
| int64_t rtp_timestamp_offset = 123456789; |
| Timestamp departure_timestamp_offset = Timestamp::Micros( |
| (rtp_timestamp_offset * kMicrosPerMillis) / kRtpVideoTicksPerMillis); |
| TestFrame frame{.unwrapped_rtp_timestamp = rtp_timestamp_offset + 3000}; |
| EXPECT_EQ(frame.DepartureTimestamp(departure_timestamp_offset), |
| Timestamp::Micros(33333)); |
| } |
| |
| TEST(FrameBaseTest, ArrivalTimestampIsInfiniteForUnsetRtpTimestamp) { |
| TestFrame frame; |
| EXPECT_FALSE(frame.ArrivalTimestamp().IsFinite()); |
| } |
| |
| TEST(FrameBaseTest, ArrivalTimestamp) { |
| TestFrame frame{.assembled_timestamp = Timestamp::Micros(33333)}; |
| EXPECT_EQ(frame.ArrivalTimestamp(), Timestamp::Micros(33333)); |
| } |
| |
| TEST(FrameBaseTest, ArrivalTimestampWithOffset) { |
| Timestamp arrival_timestamp_offset = Timestamp::Seconds(123456789); |
| TestFrame frame{.assembled_timestamp = |
| Timestamp::Micros(arrival_timestamp_offset.us() + 33333)}; |
| EXPECT_EQ(frame.ArrivalTimestamp(arrival_timestamp_offset), |
| Timestamp::Micros(33333)); |
| } |
| |
| TEST(FrameBaseTest, OneWayDelayWithZeroOffsets) { |
| TestFrame frame1{.unwrapped_rtp_timestamp = 3000, |
| .assembled_timestamp = Timestamp::Micros(33333)}; |
| EXPECT_EQ(frame1.OneWayDelay( |
| /*arrival_offset=*/Timestamp::Zero(), |
| /*departure_offset=*/Timestamp::Zero()), |
| TimeDelta::Zero()); |
| |
| // Delayed 1000us relative to its nominal arrival time. |
| TestFrame frame2{.unwrapped_rtp_timestamp = 6000, |
| .assembled_timestamp = Timestamp::Micros(67666)}; |
| EXPECT_EQ(frame2.OneWayDelay( |
| /*arrival_offset=*/Timestamp::Zero(), |
| /*departure_offset=*/Timestamp::Zero()), |
| TimeDelta::Micros(1000)); |
| } |
| |
| TEST(FrameBaseTest, OneWayDelayWithOffsets) { |
| int64_t rtp_timestamp_offset = 123456789; |
| Timestamp departure_timestamp_offset = Timestamp::Micros( |
| (rtp_timestamp_offset * kMicrosPerMillis) / kRtpVideoTicksPerMillis); |
| Timestamp arrival_timestamp_offset = Timestamp::Seconds(123456789); |
| |
| TestFrame frame1{.unwrapped_rtp_timestamp = rtp_timestamp_offset + 3000, |
| .assembled_timestamp = Timestamp::Micros( |
| arrival_timestamp_offset.us() + 33333)}; |
| EXPECT_EQ( |
| frame1.OneWayDelay(arrival_timestamp_offset, departure_timestamp_offset), |
| TimeDelta::Zero()); |
| |
| // Delayed 1000us relative to its nominal arrival time. |
| TestFrame frame2{.unwrapped_rtp_timestamp = rtp_timestamp_offset + 6000, |
| .assembled_timestamp = Timestamp::Micros( |
| arrival_timestamp_offset.us() + 67666)}; |
| EXPECT_EQ( |
| frame2.OneWayDelay(arrival_timestamp_offset, departure_timestamp_offset), |
| TimeDelta::Micros(1000)); |
| } |
| |
| TEST(FrameBaseTest, SortingTemplatesCompile) { |
| std::vector<TestFrame> test_frames = { |
| TestFrame{.unwrapped_rtp_timestamp = 3000}}; |
| SortByDepartureOrder(test_frames); |
| SortByArrivalOrder(test_frames); |
| SortByAssembledOrder(test_frames); |
| } |
| |
| } // namespace |
| } // namespace webrtc::video_timing_simulator |