From a0ee64c57e8bcb17a34f40a4f78524c7f9b17743 Mon Sep 17 00:00:00 2001 From: Evan Shrubsole Date: Tue, 26 Apr 2022 10:09:04 +0200 Subject: [PATCH] Add test::FakeEncodedFrame for testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1c8fabe5caf2c723487ec1cd71a379e922026a9d Bug: webrtc:13996 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260001 Reviewed-by: Erik Språng Commit-Queue: Evan Shrubsole Cr-Commit-Position: refs/heads/main@{#36654} --- modules/video_coding/BUILD.gn | 1 + .../video_coding/frame_buffer3_unittest.cc | 220 +++++----- test/BUILD.gn | 15 + test/fake_encoded_frame.cc | 135 ++++++ test/fake_encoded_frame.h | 84 ++++ video/BUILD.gn | 2 +- video/frame_buffer_proxy_unittest.cc | 412 +++++++++--------- video/video_receive_stream2_unittest.cc | 93 ++-- video/video_stream_decoder_impl_unittest.cc | 54 +-- 9 files changed, 602 insertions(+), 414 deletions(-) create mode 100644 test/fake_encoded_frame.cc create mode 100644 test/fake_encoded_frame.h diff --git a/modules/video_coding/BUILD.gn b/modules/video_coding/BUILD.gn index 96d170418d..1d14022c08 100644 --- a/modules/video_coding/BUILD.gn +++ b/modules/video_coding/BUILD.gn @@ -1279,6 +1279,7 @@ if (rtc_include_tests) { "../../system_wrappers", "../../system_wrappers:field_trial", "../../system_wrappers:metrics", + "../../test:fake_encoded_frame", "../../test:fake_video_codecs", "../../test:field_trial", "../../test:fileutils", diff --git a/modules/video_coding/frame_buffer3_unittest.cc b/modules/video_coding/frame_buffer3_unittest.cc index 27a25f2309..39fab888aa 100644 --- a/modules/video_coding/frame_buffer3_unittest.cc +++ b/modules/video_coding/frame_buffer3_unittest.cc @@ -12,6 +12,7 @@ #include #include "api/video/encoded_frame.h" +#include "test/fake_encoded_frame.h" #include "test/field_trial.h" #include "test/gmock.h" #include "test/gtest.h" @@ -29,67 +30,19 @@ MATCHER_P(FrameWithId, id, "") { return Matches(Eq(id))(arg->Id()); } -class FakeEncodedFrame : public EncodedFrame { - public: - int64_t ReceivedTime() const override { return 0; } - int64_t RenderTime() const override { return 0; } -}; - -class Builder { - public: - Builder& Time(uint32_t rtp_timestamp) { - rtp_timestamp_ = rtp_timestamp; - return *this; - } - Builder& Id(int64_t frame_id) { - frame_id_ = frame_id; - return *this; - } - Builder& AsLast() { - last_spatial_layer_ = true; - return *this; - } - Builder& Refs(const std::vector& references) { - references_ = references; - return *this; - } - - std::unique_ptr Build() { - RTC_CHECK_LE(references_.size(), EncodedFrame::kMaxFrameReferences); - RTC_CHECK(rtp_timestamp_.has_value()); - RTC_CHECK(frame_id_.has_value()); - - auto frame = std::make_unique(); - frame->SetTimestamp(*rtp_timestamp_); - frame->SetId(*frame_id_); - frame->is_last_spatial_layer = last_spatial_layer_; - - for (int64_t ref : references_) { - frame->references[frame->num_references] = ref; - frame->num_references++; - } - - return frame; - } - - private: - absl::optional rtp_timestamp_; - absl::optional frame_id_; - bool last_spatial_layer_ = false; - std::vector references_; -}; - TEST(FrameBuffer3Test, RejectInvalidRefs) { test::ScopedKeyValueConfig field_trials; FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); // Ref must be less than the id of this frame. - buffer.InsertFrame(Builder().Time(0).Id(0).Refs({0}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(0).Id(0).Refs({0}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt)); // Duplicate ids are also invalid. - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1, 1}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1, 1}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1)); } @@ -100,11 +53,12 @@ TEST(FrameBuffer3Test, LastContinuousUpdatesOnInsertedFrames) { EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt)); EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt)); - buffer.InsertFrame(Builder().Time(10).Id(1).Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1)); EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt)); - buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(2)); EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2)); } @@ -114,11 +68,13 @@ TEST(FrameBuffer3Test, LastContinuousFrameReordering) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1)); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(3)); } @@ -127,9 +83,10 @@ TEST(FrameBuffer3Test, LastContinuousTemporalUnit) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()); EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt)); - buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2)); } @@ -138,12 +95,14 @@ TEST(FrameBuffer3Test, LastContinuousTemporalUnitReordering) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).Build()); - buffer.InsertFrame(Builder().Time(20).Id(3).Refs({1}).Build()); - buffer.InsertFrame(Builder().Time(20).Id(4).Refs({2, 3}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(20).Id(3).Refs({1}).Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(4).Refs({2, 3}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt)); - buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(4)); } @@ -154,7 +113,7 @@ TEST(FrameBuffer3Test, NextDecodable) { EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(absl::nullopt)); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U)); } @@ -163,9 +122,10 @@ TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build()); - buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()); EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U)); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), @@ -183,9 +143,11 @@ TEST(FrameBuffer3Test, AdvanceLastDecodableOnExtraction) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()); EXPECT_THAT(buffer.LastDecodableTemporalUnitRtpTimestamp(), Eq(10U)); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), @@ -198,10 +160,10 @@ TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(20).Id(2).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build()); EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(20U)); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); EXPECT_THAT(buffer.NextDecodableTemporalUnitRtpTimestamp(), Eq(10U)); } @@ -209,18 +171,23 @@ TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) { test::ScopedKeyValueConfig field_trials; FrameBuffer buffer(/*max_frame_slots=*/5, /*max_decode_history=*/10, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(30).Id(3).Refs({2}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(40).Id(4).Refs({3}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(50).Id(5).Refs({4}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(40).Id(4).Refs({3}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(50).Id(5).Refs({4}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5)); // Frame buffer is full - buffer.InsertFrame(Builder().Time(60).Id(6).Refs({5}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(60).Id(6).Refs({5}).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5)); - buffer.InsertFrame(Builder().Time(70).Id(7).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(70).Id(7).AsLast().Build()); EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(7)); } @@ -228,9 +195,11 @@ TEST(FrameBuffer3Test, DropNextDecodableTemporalUnit) { test::ScopedKeyValueConfig field_trials; FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()); buffer.ExtractNextDecodableTemporalUnit(); buffer.DropNextDecodableTemporalUnit(); @@ -242,15 +211,18 @@ TEST(FrameBuffer3Test, OldFramesAreIgnored) { test::ScopedKeyValueConfig field_trials; FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()); buffer.ExtractNextDecodableTemporalUnit(); buffer.ExtractNextDecodableTemporalUnit(); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(3))); @@ -260,13 +232,15 @@ TEST(FrameBuffer3Test, ReturnFullTemporalUnitKSVC) { test::ScopedKeyValueConfig field_trials; FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).Build()); - buffer.InsertFrame(Builder().Time(10).Id(2).Refs({1}).Build()); - buffer.InsertFrame(Builder().Time(10).Id(3).Refs({2}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(10).Id(3).Refs({2}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(1), FrameWithId(2), FrameWithId(3))); - buffer.InsertFrame(Builder().Time(20).Id(4).Refs({3}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(4).Refs({3}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(4))); } @@ -275,11 +249,15 @@ TEST(FrameBuffer3Test, InterleavedStream) { test::ScopedKeyValueConfig field_trials; FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(30).Id(3).Refs({1}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(40).Id(4).Refs({2}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(50).Id(5).Refs({3}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(40).Id(4).Refs({2}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(50).Id(5).Refs({3}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(1))); @@ -292,12 +270,15 @@ TEST(FrameBuffer3Test, InterleavedStream) { EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(5))); - buffer.InsertFrame(Builder().Time(70).Id(7).Refs({5}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(70).Id(7).Refs({5}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(7))); - buffer.InsertFrame(Builder().Time(60).Id(6).Refs({4}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(60).Id(6).Refs({4}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty()); - buffer.InsertFrame(Builder().Time(90).Id(9).Refs({7}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(90).Id(9).Refs({7}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(9))); } @@ -309,10 +290,12 @@ TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(3).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(3))); - buffer.InsertFrame(Builder().Time(30).Id(2).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(2).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty()); } @@ -322,12 +305,15 @@ TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) { FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100, field_trials); - buffer.InsertFrame(Builder().Time(20).Id(3).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(3).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(3))); - buffer.InsertFrame(Builder().Time(30).Id(2).Refs({1}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(30).Id(2).Refs({1}).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty()); - buffer.InsertFrame(Builder().Time(40).Id(1).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(40).Id(1).AsLast().Build()); EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), ElementsAre(FrameWithId(1))); } @@ -339,18 +325,20 @@ TEST(FrameBuffer3Test, TotalNumberOfContinuousTemporalUnits) { field_trials); EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(0)); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1)); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).Build()); EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1)); - buffer.InsertFrame(Builder().Time(40).Id(4).Refs({2}).Build()); - buffer.InsertFrame(Builder().Time(40).Id(5).Refs({3, 4}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(40).Id(4).Refs({2}).Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(40).Id(5).Refs({3, 4}).AsLast().Build()); EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1)); // Reordered - buffer.InsertFrame(Builder().Time(20).Id(3).Refs({2}).AsLast().Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(3).Refs({2}).AsLast().Build()); EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(3)); } @@ -360,11 +348,13 @@ TEST(FrameBuffer3Test, TotalNumberOfDroppedFrames) { field_trials); EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0)); - buffer.InsertFrame(Builder().Time(10).Id(1).AsLast().Build()); - buffer.InsertFrame(Builder().Time(20).Id(2).Refs({1}).Build()); - buffer.InsertFrame(Builder().Time(20).Id(3).Refs({2}).AsLast().Build()); - buffer.InsertFrame(Builder().Time(40).Id(4).Refs({1}).Build()); - buffer.InsertFrame(Builder().Time(40).Id(5).Refs({4}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(20).Id(3).Refs({2}).AsLast().Build()); + buffer.InsertFrame(test::FakeFrameBuilder().Time(40).Id(4).Refs({1}).Build()); + buffer.InsertFrame( + test::FakeFrameBuilder().Time(40).Id(5).Refs({4}).AsLast().Build()); buffer.ExtractNextDecodableTemporalUnit(); EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0)); diff --git a/test/BUILD.gn b/test/BUILD.gn index a958b128fd..9157a9e9ad 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -1120,3 +1120,18 @@ rtc_library("call_config_utils") { "../rtc_base:rtc_json", ] } + +rtc_library("fake_encoded_frame") { + testonly = true + sources = [ + "fake_encoded_frame.cc", + "fake_encoded_frame.h", + ] + deps = [ + ":test_support", + "../api:rtp_packet_info", + "../api/video:encoded_frame", + "../api/video:video_rtp_headers", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ] +} diff --git a/test/fake_encoded_frame.cc b/test/fake_encoded_frame.cc new file mode 100644 index 0000000000..7a1bd75b48 --- /dev/null +++ b/test/fake_encoded_frame.cc @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2022 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 "test/fake_encoded_frame.h" + +namespace webrtc::test { + +void PrintTo(const EncodedFrame& frame, + std::ostream* os) /* no-presubmit-check TODO(webrtc:8982) */ { + *os << "EncodedFrame with id=" << frame.Id() << " rtp=" << frame.Timestamp() + << " size=" << frame.size() << " refs=["; + for (size_t ref = 0; ref < frame.num_references; ++ref) { + *os << frame.references[ref] << ","; + } + *os << "]"; +} + +int64_t FakeEncodedFrame::ReceivedTime() const { + return received_time_; +} + +int64_t FakeEncodedFrame::RenderTime() const { + return _renderTimeMs; +} + +void FakeEncodedFrame::SetReceivedTime(int64_t received_time) { + received_time_ = received_time; +} + +void FakeEncodedFrame::SetPayloadType(int payload_type) { + _payloadType = payload_type; +} + +FakeFrameBuilder& FakeFrameBuilder::Time(uint32_t rtp_timestamp) { + rtp_timestamp_ = rtp_timestamp; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::Id(int64_t frame_id) { + frame_id_ = frame_id; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::AsLast() { + last_spatial_layer_ = true; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::Refs( + const std::vector& references) { + references_ = references; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::PlayoutDelay( + VideoPlayoutDelay playout_delay) { + playout_delay_ = playout_delay; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::SpatialLayer(int spatial_layer) { + spatial_layer_ = spatial_layer; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::ReceivedTime(Timestamp receive_time) { + received_time_ = receive_time; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::Size(size_t size) { + size_ = size; + return *this; +} + +std::unique_ptr FakeFrameBuilder::Build() { + RTC_CHECK_LE(references_.size(), EncodedFrame::kMaxFrameReferences); + + auto frame = std::make_unique(); + frame->is_last_spatial_layer = last_spatial_layer_; + frame->SetEncodedData(EncodedImageBuffer::Create(size_)); + + if (rtp_timestamp_) + frame->SetTimestamp(*rtp_timestamp_); + if (frame_id_) + frame->SetId(*frame_id_); + if (playout_delay_) + frame->SetPlayoutDelay(*playout_delay_); + for (int64_t ref : references_) { + frame->references[frame->num_references] = ref; + frame->num_references++; + } + if (spatial_layer_) + frame->SetSpatialIndex(spatial_layer_); + if (received_time_) + frame->SetReceivedTime(received_time_->ms()); + if (payload_type_) + frame->SetPayloadType(*payload_type_); + if (ntp_time_) + frame->ntp_time_ms_ = ntp_time_->ms(); + if (rotation_) + frame->rotation_ = *rotation_; + if (packet_infos_) + frame->SetPacketInfos(*packet_infos_); + return frame; +} + +FakeFrameBuilder& FakeFrameBuilder::PayloadType(int payload_type) { + payload_type_ = payload_type; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::NtpTime(Timestamp ntp_time) { + ntp_time_ = ntp_time; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::Rotation(VideoRotation rotation) { + rotation_ = rotation; + return *this; +} + +FakeFrameBuilder& FakeFrameBuilder::PacketInfos(RtpPacketInfos packet_infos) { + packet_infos_ = packet_infos; + return *this; +} + +} // namespace webrtc::test diff --git a/test/fake_encoded_frame.h b/test/fake_encoded_frame.h new file mode 100644 index 0000000000..6af9a40f38 --- /dev/null +++ b/test/fake_encoded_frame.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 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. + */ + +#ifndef TEST_FAKE_ENCODED_FRAME_H_ +#define TEST_FAKE_ENCODED_FRAME_H_ + +#include +#include // no-presubmit-check TODO(webrtc:8982) +#include + +#include "api/rtp_packet_infos.h" +#include "api/video/encoded_frame.h" +#include "api/video/video_rotation.h" +#include "test/gmock.h" + +namespace webrtc::test { + +// For test printing. +void PrintTo(const EncodedFrame& frame, + std::ostream* os); // no-presubmit-check TODO(webrtc:8982) + +class FakeEncodedFrame : public EncodedFrame { + public: + // Always 10ms delay and on time. + int64_t ReceivedTime() const override; + int64_t RenderTime() const override; + + // Setters for protected variables. + void SetReceivedTime(int64_t received_time); + void SetPayloadType(int payload_type); + + private: + int64_t received_time_; +}; + +MATCHER_P(WithId, id, "") { + return ::testing::Matches(::testing::Eq(id))(arg.Id()); +} + +MATCHER_P(FrameWithSize, id, "") { + return ::testing::Matches(::testing::Eq(id))(arg.size()); +} + +class FakeFrameBuilder { + public: + FakeFrameBuilder& Time(uint32_t rtp_timestamp); + FakeFrameBuilder& Id(int64_t frame_id); + FakeFrameBuilder& AsLast(); + FakeFrameBuilder& Refs(const std::vector& references); + FakeFrameBuilder& PlayoutDelay(VideoPlayoutDelay playout_delay); + FakeFrameBuilder& SpatialLayer(int spatial_layer); + FakeFrameBuilder& ReceivedTime(Timestamp receive_time); + FakeFrameBuilder& Size(size_t size); + FakeFrameBuilder& PayloadType(int payload_type); + FakeFrameBuilder& NtpTime(Timestamp ntp_time); + FakeFrameBuilder& Rotation(VideoRotation rotation); + FakeFrameBuilder& PacketInfos(RtpPacketInfos packet_infos); + std::unique_ptr Build(); + + private: + absl::optional rtp_timestamp_; + absl::optional frame_id_; + absl::optional playout_delay_; + absl::optional spatial_layer_; + absl::optional received_time_; + absl::optional payload_type_; + absl::optional ntp_time_; + absl::optional rotation_; + absl::optional packet_infos_; + std::vector references_; + bool last_spatial_layer_ = false; + size_t size_ = 10; +}; + +} // namespace webrtc::test + +#endif // TEST_FAKE_ENCODED_FRAME_H_ diff --git a/video/BUILD.gn b/video/BUILD.gn index 0c9c76d5e5..58484031df 100644 --- a/video/BUILD.gn +++ b/video/BUILD.gn @@ -950,6 +950,7 @@ if (rtc_include_tests) { "../system_wrappers:metrics", "../test:direct_transport", "../test:encoder_settings", + "../test:fake_encoded_frame", "../test:fake_video_codecs", "../test:field_trial", "../test:fileutils", @@ -965,7 +966,6 @@ if (rtc_include_tests) { "../test:video_test_common", "../test/time_controller", "adaptation:video_adaptation", - "//testing/gtest", ] absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container", diff --git a/video/frame_buffer_proxy_unittest.cc b/video/frame_buffer_proxy_unittest.cc index d6f97dbb85..6babcdada9 100644 --- a/video/frame_buffer_proxy_unittest.cc +++ b/video/frame_buffer_proxy_unittest.cc @@ -28,6 +28,7 @@ #include "api/video/video_timing.h" #include "rtc_base/checks.h" #include "rtc_base/event.h" +#include "test/fake_encoded_frame.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/run_loop.h" @@ -51,16 +52,6 @@ using ::testing::VariantWith; namespace webrtc { -// For test printing. -void PrintTo(const EncodedFrame& frame, std::ostream* os) { - *os << "EncodedFrame with id=" << frame.Id() << " rtp=" << frame.Timestamp() - << " size=" << frame.size() << " refs=["; - for (size_t ref = 0; ref < frame.num_references; ++ref) { - *os << frame.references[ref] << ","; - } - *os << "]"; -} - namespace { constexpr size_t kFrameSize = 10; @@ -69,28 +60,6 @@ constexpr TimeDelta kFps30Delay = 1 / Frequency::Hertz(30); const VideoPlayoutDelay kZeroPlayoutDelay = {0, 0}; constexpr Timestamp kClockStart = Timestamp::Millis(1000); -class FakeEncodedFrame : public EncodedFrame { - public: - // Always 10ms delay and on time. - int64_t ReceivedTime() const override { return received_time_; } - int64_t RenderTime() const override { return _renderTimeMs; } - - void SetReceivedTime(int64_t received_time) { - received_time_ = received_time; - } - - private: - int64_t received_time_; -}; - -MATCHER_P(WithId, id, "") { - return Matches(Eq(id))(arg.Id()); -} - -MATCHER_P(FrameWithSize, id, "") { - return Matches(Eq(id))(arg.size()); -} - auto TimedOut() { return Optional(VariantWith(_)); } @@ -99,80 +68,17 @@ auto Frame(testing::Matcher m) { return Optional(VariantWith>(Pointee(m))); } -class Builder { - public: - Builder& Time(uint32_t rtp_timestamp) { - rtp_timestamp_ = rtp_timestamp; - return *this; +std::unique_ptr WithReceiveTimeFromRtpTimestamp( + std::unique_ptr frame) { + if (frame->Timestamp() == 0) { + frame->SetReceivedTime(kClockStart.ms()); + } else { + frame->SetReceivedTime( + TimeDelta::Seconds(frame->Timestamp() / 90000.0).ms() + + kClockStart.ms()); } - Builder& Id(int64_t frame_id) { - frame_id_ = frame_id; - return *this; - } - Builder& AsLast() { - last_spatial_layer_ = true; - return *this; - } - Builder& Refs(const std::vector& references) { - references_ = references; - return *this; - } - Builder& PlayoutDelay(VideoPlayoutDelay playout_delay) { - playout_delay_ = playout_delay; - return *this; - } - Builder& SpatialLayer(int spatial_layer) { - spatial_layer_ = spatial_layer; - return *this; - } - Builder& ReceivedTime(Timestamp receive_time) { - received_time_ = receive_time; - return *this; - } - - std::unique_ptr Build() { - RTC_CHECK_LE(references_.size(), EncodedFrame::kMaxFrameReferences); - RTC_CHECK(rtp_timestamp_); - RTC_CHECK(frame_id_); - - auto frame = std::make_unique(); - frame->SetTimestamp(*rtp_timestamp_); - frame->SetId(*frame_id_); - frame->is_last_spatial_layer = last_spatial_layer_; - frame->SetEncodedData(EncodedImageBuffer::Create(kFrameSize)); - - if (playout_delay_) - frame->SetPlayoutDelay(*playout_delay_); - - for (int64_t ref : references_) { - frame->references[frame->num_references] = ref; - frame->num_references++; - } - if (spatial_layer_) { - frame->SetSpatialIndex(spatial_layer_); - } - if (received_time_) { - frame->SetReceivedTime(received_time_->ms()); - } else { - if (*rtp_timestamp_ == 0) - frame->SetReceivedTime(kClockStart.ms()); - frame->SetReceivedTime( - TimeDelta::Seconds(*rtp_timestamp_ / 90000.0).ms() + - kClockStart.ms()); - } - - return frame; - } - - private: - absl::optional rtp_timestamp_; - absl::optional frame_id_; - absl::optional playout_delay_; - absl::optional spatial_layer_; - absl::optional received_time_; - bool last_spatial_layer_ = false; - std::vector references_; -}; + return frame; +} class VCMReceiveStatisticsCallbackMock : public VCMReceiveStatisticsCallback { public: @@ -349,19 +255,20 @@ TEST_P(FrameBufferProxyTest, KeyFramesAreScheduled) { StartNextDecodeForceKeyframe(); time_controller_.AdvanceTime(TimeDelta::Millis(50)); - auto frame = Builder().Id(0).Time(0).AsLast().Build(); + auto frame = test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build(); proxy_->InsertFrame(std::move(frame)); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); } TEST_P(FrameBufferProxyTest, DeltaFrameTimeoutAfterKeyframeExtracted) { StartNextDecodeForceKeyframe(); time_controller_.AdvanceTime(TimeDelta::Millis(50)); - auto frame = Builder().Id(0).Time(0).AsLast().Build(); + auto frame = test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build(); proxy_->InsertFrame(std::move(frame)); - EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForKeyframe), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForKeyframe), + Frame(test::WithId(0))); StartNextDecode(); time_controller_.AdvanceTime(TimeDelta::Millis(50)); @@ -376,44 +283,64 @@ TEST_P(FrameBufferProxyTest, DeltaFrameTimeoutAfterKeyframeExtracted) { TEST_P(FrameBufferProxyTest, DependantFramesAreScheduled) { StartNextDecodeForceKeyframe(); - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); StartNextDecode(); time_controller_.AdvanceTime(kFps30Delay); - proxy_->InsertFrame( - Builder().Id(1).Time(kFps30Rtp).AsLast().Refs({0}).Build()); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(1))); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(1) + .Time(kFps30Rtp) + .AsLast() + .Refs({0}) + .Build()); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(1))); } TEST_P(FrameBufferProxyTest, SpatialLayersAreScheduled) { StartNextDecodeForceKeyframe(); - proxy_->InsertFrame(Builder().Id(0).SpatialLayer(0).Time(0).Build()); - proxy_->InsertFrame(Builder().Id(1).SpatialLayer(1).Time(0).Build()); - proxy_->InsertFrame(Builder().Id(2).SpatialLayer(2).Time(0).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), - Frame(AllOf(WithId(0), FrameWithSize(3 * kFrameSize)))); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(0).SpatialLayer(0).Time(0).Build())); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(1).SpatialLayer(1).Time(0).Build())); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(2).SpatialLayer(2).Time(0).AsLast().Build())); + EXPECT_THAT( + WaitForFrameOrTimeout(TimeDelta::Zero()), + Frame(AllOf(test::WithId(0), test::FrameWithSize(3 * kFrameSize)))); - proxy_->InsertFrame(Builder().Id(3).Time(kFps30Rtp).SpatialLayer(0).Build()); - proxy_->InsertFrame(Builder().Id(4).Time(kFps30Rtp).SpatialLayer(1).Build()); - proxy_->InsertFrame( - Builder().Id(5).Time(kFps30Rtp).SpatialLayer(2).AsLast().Build()); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(3).Time(kFps30Rtp).SpatialLayer(0).Build())); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(4).Time(kFps30Rtp).SpatialLayer(1).Build())); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp(test::FakeFrameBuilder() + .Id(5) + .Time(kFps30Rtp) + .SpatialLayer(2) + .AsLast() + .Build())); StartNextDecode(); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay * 10), - Frame(AllOf(WithId(3), FrameWithSize(3 * kFrameSize)))); + EXPECT_THAT( + WaitForFrameOrTimeout(kFps30Delay * 10), + Frame(AllOf(test::WithId(3), test::FrameWithSize(3 * kFrameSize)))); } TEST_P(FrameBufferProxyTest, OutstandingFrameTasksAreCancelledAfterDeletion) { StartNextDecodeForceKeyframe(); - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build())); // Get keyframe. Delta frame should now be scheduled. - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); StartNextDecode(); - proxy_->InsertFrame( - Builder().Id(1).Time(kFps30Rtp).AsLast().Refs({0}).Build()); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp(test::FakeFrameBuilder() + .Id(1) + .Time(kFps30Rtp) + .AsLast() + .Refs({0}) + .Build())); proxy_->StopOnWorker(); // Wait for 2x max wait time. Since we stopped, this should cause no timeouts // or frame-ready callbacks. @@ -424,20 +351,24 @@ TEST_P(FrameBufferProxyTest, FramesWaitForDecoderToComplete) { StartNextDecodeForceKeyframe(); // Start with a keyframe. - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); ResetLastResult(); // Insert a delta frame. - proxy_->InsertFrame( - Builder().Id(1).Time(kFps30Rtp).AsLast().Refs({0}).Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(1) + .Time(kFps30Rtp) + .AsLast() + .Refs({0}) + .Build()); // Advancing time should not result in a frame since the scheduler has not // been signalled that we are ready. EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Eq(absl::nullopt)); // Signal ready. StartNextDecode(); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(1))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(1))); } TEST_P(FrameBufferProxyTest, LateFrameDropped) { @@ -445,22 +376,30 @@ TEST_P(FrameBufferProxyTest, LateFrameDropped) { // F1 // / // F0 --> F2 - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); // Start with a keyframe. - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); StartNextDecode(); // Simulate late F1 which arrives after F2. time_controller_.AdvanceTime(kFps30Delay * 2); - proxy_->InsertFrame( - Builder().Id(2).Time(2 * kFps30Rtp).AsLast().Refs({0}).Build()); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(2))); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(2) + .Time(2 * kFps30Rtp) + .AsLast() + .Refs({0}) + .Build()); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2))); StartNextDecode(); - proxy_->InsertFrame( - Builder().Id(1).Time(1 * kFps30Rtp).AsLast().Refs({0}).Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(1) + .Time(1 * kFps30Rtp) + .AsLast() + .Refs({0}) + .Build()); // Confirm frame 1 is never scheduled by timing out. EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), TimedOut()); } @@ -470,40 +409,53 @@ TEST_P(FrameBufferProxyTest, FramesFastForwardOnSystemHalt) { // F1 // / // F0 --> F2 - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); // Start with a keyframe. - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); time_controller_.AdvanceTime(kFps30Delay); - proxy_->InsertFrame( - Builder().Id(1).Time(kFps30Rtp).AsLast().Refs({0}).Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(1) + .Time(kFps30Rtp) + .AsLast() + .Refs({0}) + .Build()); time_controller_.AdvanceTime(kFps30Delay); - proxy_->InsertFrame( - Builder().Id(2).Time(2 * kFps30Rtp).AsLast().Refs({0}).Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(2) + .Time(2 * kFps30Rtp) + .AsLast() + .Refs({0}) + .Build()); // Halting time should result in F1 being skipped. time_controller_.AdvanceTime(kFps30Delay * 2); StartNextDecode(); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(2))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2))); EXPECT_EQ(dropped_frames(), 1); } TEST_P(FrameBufferProxyTest, ForceKeyFrame) { StartNextDecodeForceKeyframe(); // Initial keyframe. - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); StartNextDecodeForceKeyframe(); // F2 is the next keyframe, and should be extracted since a keyframe was // forced. + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(1) + .Time(kFps30Rtp) + .AsLast() + .Refs({0}) + .Build()); proxy_->InsertFrame( - Builder().Id(1).Time(kFps30Rtp).AsLast().Refs({0}).Build()); - proxy_->InsertFrame(Builder().Id(2).Time(kFps30Rtp * 2).AsLast().Build()); + test::FakeFrameBuilder().Id(2).Time(kFps30Rtp * 2).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay * 3), Frame(WithId(2))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay * 3), Frame(test::WithId(2))); } TEST_P(FrameBufferProxyTest, SlowDecoderDropsTemporalLayers) { @@ -513,40 +465,60 @@ TEST_P(FrameBufferProxyTest, SlowDecoderDropsTemporalLayers) { // F1 --> F3 --> F5 // / / / // F0 --> F2 --> F4 - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); // Keyframe received. // Don't start next decode until slow delay. - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); time_controller_.AdvanceTime(kFps30Delay); - proxy_->InsertFrame( - Builder().Id(1).Time(1 * kFps30Rtp).Refs({0}).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(1) + .Time(1 * kFps30Rtp) + .Refs({0}) + .AsLast() + .Build()); time_controller_.AdvanceTime(kFps30Delay); - proxy_->InsertFrame( - Builder().Id(2).Time(2 * kFps30Rtp).Refs({0}).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(2) + .Time(2 * kFps30Rtp) + .Refs({0}) + .AsLast() + .Build()); // Simulate decode taking 3x FPS rate. time_controller_.AdvanceTime(kFps30Delay * 1.5); StartNextDecode(); // F2 is the best frame since decoding was so slow that F1 is too old. - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay * 2), Frame(WithId(2))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay * 2), Frame(test::WithId(2))); EXPECT_EQ(dropped_frames(), 1); time_controller_.AdvanceTime(kFps30Delay / 2); - proxy_->InsertFrame( - Builder().Id(3).Time(3 * kFps30Rtp).Refs({1, 2}).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(3) + .Time(3 * kFps30Rtp) + .Refs({1, 2}) + .AsLast() + .Build()); time_controller_.AdvanceTime(kFps30Delay / 2); - proxy_->InsertFrame( - Builder().Id(4).Time(4 * kFps30Rtp).Refs({2}).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(4) + .Time(4 * kFps30Rtp) + .Refs({2}) + .AsLast() + .Build()); time_controller_.AdvanceTime(kFps30Delay / 2); // F4 is the best frame since decoding was so slow that F1 is too old. time_controller_.AdvanceTime(kFps30Delay); StartNextDecode(); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(4))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(4))); - proxy_->InsertFrame( - Builder().Id(5).Time(5 * kFps30Rtp).Refs({3, 4}).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder() + .Id(5) + .Time(5 * kFps30Rtp) + .Refs({3, 4}) + .AsLast() + .Build()); time_controller_.AdvanceTime(kFps30Delay / 2); // F5 is not decodable since F4 was decoded, so a timeout is expected. @@ -563,20 +535,29 @@ TEST_P(FrameBufferProxyTest, SlowDecoderDropsTemporalLayers) { TEST_P(FrameBufferProxyTest, NewFrameInsertedWhileWaitingToReleaseFrame) { StartNextDecodeForceKeyframe(); // Initial keyframe. - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build())); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); time_controller_.AdvanceTime(kFps30Delay / 2); - proxy_->InsertFrame( - Builder().Id(1).Time(kFps30Rtp).Refs({0}).AsLast().Build()); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp(test::FakeFrameBuilder() + .Id(1) + .Time(kFps30Rtp) + .Refs({0}) + .AsLast() + .Build())); StartNextDecode(); EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Eq(absl::nullopt)); // Scheduler is waiting to deliver Frame 1 now. Insert Frame 2. Frame 1 should // be delivered still. - proxy_->InsertFrame( - Builder().Id(2).Time(kFps30Rtp * 2).Refs({0}).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(1))); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp(test::FakeFrameBuilder() + .Id(2) + .Time(kFps30Rtp * 2) + .Refs({0}) + .AsLast() + .Build())); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(1))); } TEST_P(FrameBufferProxyTest, SameFrameNotScheduledTwice) { @@ -592,34 +573,40 @@ TEST_P(FrameBufferProxyTest, SameFrameNotScheduledTwice) { StartNextDecodeForceKeyframe(); // First keyframe. - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Millis(15)), Frame(WithId(0))); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build())); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Millis(15)), + Frame(test::WithId(0))); StartNextDecode(); // Warmup VCMTiming for 30fps. for (int i = 1; i <= 30; ++i) { - proxy_->InsertFrame(Builder().Id(i).Time(i * kFps30Rtp).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(i))); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(i).Time(i * kFps30Rtp).AsLast().Build())); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(i))); StartNextDecode(); } // F2 arrives and is scheduled. - proxy_->InsertFrame(Builder().Id(32).Time(32 * kFps30Rtp).AsLast().Build()); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(32).Time(32 * kFps30Rtp).AsLast().Build())); // F3 arrives before F2 is extracted. time_controller_.AdvanceTime(kFps30Delay); - proxy_->InsertFrame(Builder().Id(33).Time(33 * kFps30Rtp).AsLast().Build()); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(33).Time(33 * kFps30Rtp).AsLast().Build())); // F1 arrives and is fast-forwarded since it is too late. // F2 is already scheduled and should not be rescheduled. time_controller_.AdvanceTime(kFps30Delay / 2); - proxy_->InsertFrame(Builder().Id(31).Time(31 * kFps30Rtp).AsLast().Build()); + proxy_->InsertFrame(WithReceiveTimeFromRtpTimestamp( + test::FakeFrameBuilder().Id(31).Time(31 * kFps30Rtp).AsLast().Build())); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(32))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(32))); StartNextDecode(); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(33))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(33))); StartNextDecode(); EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), TimedOut()); EXPECT_EQ(dropped_frames(), 1); @@ -633,8 +620,8 @@ TEST_P(FrameBufferProxyTest, TestStatsCallback) { // Fake timing having received decoded frame. timing_.StopDecodeTimer(TimeDelta::Millis(1), clock_->CurrentTime()); StartNextDecodeForceKeyframe(); - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); // Flush stats posted on the decode queue. time_controller_.AdvanceTime(TimeDelta::Zero()); @@ -646,8 +633,8 @@ TEST_P(FrameBufferProxyTest, FrameCompleteCalledOnceForDuplicateFrame) { .Times(1); StartNextDecodeForceKeyframe(); - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); - proxy_->InsertFrame(Builder().Id(0).Time(0).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build()); // Flush stats posted on the decode queue. time_controller_.AdvanceTime(TimeDelta::Zero()); } @@ -658,8 +645,8 @@ TEST_P(FrameBufferProxyTest, FrameCompleteCalledOnceForSingleTemporalUnit) { // `OnCompleteFrame` should not be called for the first two frames since they // do not complete the temporal layer. EXPECT_CALL(stats_callback_, OnCompleteFrame(_, _, _)).Times(0); - proxy_->InsertFrame(Builder().Id(0).Time(0).Build()); - proxy_->InsertFrame(Builder().Id(1).Time(0).Refs({0}).Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(1).Time(0).Refs({0}).Build()); time_controller_.AdvanceTime(TimeDelta::Zero()); // Flush stats posted on the decode queue. ::testing::Mock::VerifyAndClearExpectations(&stats_callback_); @@ -669,7 +656,8 @@ TEST_P(FrameBufferProxyTest, FrameCompleteCalledOnceForSingleTemporalUnit) { EXPECT_CALL(stats_callback_, OnCompleteFrame(false, kFrameSize, VideoContentType::UNSPECIFIED)) .Times(1); - proxy_->InsertFrame(Builder().Id(2).Time(0).Refs({0, 1}).AsLast().Build()); + proxy_->InsertFrame( + test::FakeFrameBuilder().Id(2).Time(0).Refs({0, 1}).AsLast().Build()); // Flush stats posted on the decode queue. time_controller_.AdvanceTime(TimeDelta::Zero()); } @@ -684,8 +672,9 @@ TEST_P(FrameBufferProxyTest, FrameCompleteCalledOnceForCompleteTemporalUnit) { // do not complete the temporal layer. Frame 1 arrives later, at which time // this frame can finally be considered complete. EXPECT_CALL(stats_callback_, OnCompleteFrame(_, _, _)).Times(0); - proxy_->InsertFrame(Builder().Id(0).Time(0).Build()); - proxy_->InsertFrame(Builder().Id(2).Time(0).Refs({0, 1}).AsLast().Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(0).Time(0).Build()); + proxy_->InsertFrame( + test::FakeFrameBuilder().Id(2).Time(0).Refs({0, 1}).AsLast().Build()); time_controller_.AdvanceTime(TimeDelta::Zero()); // Flush stats posted on the decode queue. ::testing::Mock::VerifyAndClearExpectations(&stats_callback_); @@ -693,7 +682,7 @@ TEST_P(FrameBufferProxyTest, FrameCompleteCalledOnceForCompleteTemporalUnit) { EXPECT_CALL(stats_callback_, OnCompleteFrame(false, kFrameSize, VideoContentType::UNSPECIFIED)) .Times(1); - proxy_->InsertFrame(Builder().Id(1).Time(0).Refs({0}).Build()); + proxy_->InsertFrame(test::FakeFrameBuilder().Id(1).Time(0).Refs({0}).Build()); // Flush stats posted on the decode queue. time_controller_.AdvanceTime(TimeDelta::Zero()); } @@ -711,23 +700,23 @@ TEST_P(FrameBufferProxyTest, NextFrameWithOldTimestamp) { // First keyframe. The receive time must be explicitly set in this test since // the RTP derived time used in all tests does not work when the long pause // happens later in the test. - proxy_->InsertFrame(Builder() + proxy_->InsertFrame(test::FakeFrameBuilder() .Id(0) .Time(kBaseRtp) .ReceivedTime(clock_->CurrentTime()) .AsLast() .Build()); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(0))); // 1 more frame to warmup VCMTiming for 30fps. StartNextDecode(); - proxy_->InsertFrame(Builder() + proxy_->InsertFrame(test::FakeFrameBuilder() .Id(1) .Time(kBaseRtp + kFps30Rtp) .ReceivedTime(clock_->CurrentTime()) .AsLast() .Build()); - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(1))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(1))); // Pause the stream for such a long time it incurs an RTP timestamp rollover // by over half. @@ -746,7 +735,7 @@ TEST_P(FrameBufferProxyTest, NextFrameWithOldTimestamp) { EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), Eq(absl::nullopt)); time_controller_.AdvanceTime(kRolloverDelay - kMaxWaitForFrame); StartNextDecode(); - proxy_->InsertFrame(Builder() + proxy_->InsertFrame(test::FakeFrameBuilder() .Id(2) .Time(kRolloverRtp) .ReceivedTime(clock_->CurrentTime()) @@ -754,7 +743,7 @@ TEST_P(FrameBufferProxyTest, NextFrameWithOldTimestamp) { .Build()); // FrameBuffer2 drops the frame, while FrameBuffer3 will continue the stream. if (!IsFrameBuffer2Enabled(field_trials_)) { - EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(WithId(2))); + EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2))); } else { EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), TimedOut()); } @@ -776,22 +765,22 @@ TEST_P(LowLatencyFrameBufferProxyTest, StartNextDecodeForceKeyframe(); timing_.set_min_playout_delay(TimeDelta::Zero()); timing_.set_max_playout_delay(TimeDelta::Millis(10)); - auto frame = Builder().Id(0).Time(0).AsLast().Build(); + auto frame = test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build(); // Playout delay of 0 implies low-latency rendering. frame->SetPlayoutDelay({0, 10}); proxy_->InsertFrame(std::move(frame)); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); // Delta frame would normally wait here, but should decode at the pacing rate // in low-latency mode. StartNextDecode(); - frame = Builder().Id(1).Time(kFps30Rtp).AsLast().Build(); + frame = test::FakeFrameBuilder().Id(1).Time(kFps30Rtp).AsLast().Build(); frame->SetPlayoutDelay({0, 10}); proxy_->InsertFrame(std::move(frame)); // Pacing is set to 16ms in the field trial so we should not decode yet. EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Eq(absl::nullopt)); time_controller_.AdvanceTime(TimeDelta::Millis(16)); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(1))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(1))); } TEST_P(LowLatencyFrameBufferProxyTest, ZeroPlayoutDelayFullQueue) { @@ -799,15 +788,16 @@ TEST_P(LowLatencyFrameBufferProxyTest, ZeroPlayoutDelayFullQueue) { StartNextDecodeForceKeyframe(); timing_.set_min_playout_delay(TimeDelta::Zero()); timing_.set_max_playout_delay(TimeDelta::Millis(10)); - auto frame = Builder().Id(0).Time(0).AsLast().Build(); + auto frame = test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build(); // Playout delay of 0 implies low-latency rendering. frame->SetPlayoutDelay({0, 10}); proxy_->InsertFrame(std::move(frame)); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); // Queue up 5 frames (configured max queue size for 0-playout delay pacing). for (int id = 1; id <= 6; ++id) { - frame = Builder().Id(id).Time(kFps30Rtp * id).AsLast().Build(); + frame = + test::FakeFrameBuilder().Id(id).Time(kFps30Rtp * id).AsLast().Build(); frame->SetPlayoutDelay({0, 10}); proxy_->InsertFrame(std::move(frame)); } @@ -815,7 +805,7 @@ TEST_P(LowLatencyFrameBufferProxyTest, ZeroPlayoutDelayFullQueue) { // The queue is at its max size for zero playout delay pacing, so the pacing // should be ignored and the next frame should be decoded instantly. StartNextDecode(); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(1))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(1))); } TEST_P(LowLatencyFrameBufferProxyTest, MinMaxDelayZeroLowLatencyMode) { @@ -823,21 +813,21 @@ TEST_P(LowLatencyFrameBufferProxyTest, MinMaxDelayZeroLowLatencyMode) { StartNextDecodeForceKeyframe(); timing_.set_min_playout_delay(TimeDelta::Zero()); timing_.set_max_playout_delay(TimeDelta::Zero()); - auto frame = Builder().Id(0).Time(0).AsLast().Build(); + auto frame = test::FakeFrameBuilder().Id(0).Time(0).AsLast().Build(); // Playout delay of 0 implies low-latency rendering. frame->SetPlayoutDelay({0, 0}); proxy_->InsertFrame(std::move(frame)); - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(0))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0))); // Delta frame would normally wait here, but should decode at the pacing rate // in low-latency mode. StartNextDecode(); - frame = Builder().Id(1).Time(kFps30Rtp).AsLast().Build(); + frame = test::FakeFrameBuilder().Id(1).Time(kFps30Rtp).AsLast().Build(); frame->SetPlayoutDelay({0, 0}); proxy_->InsertFrame(std::move(frame)); // The min/max=0 version of low-latency rendering will result in a large // negative decode wait time, so the frame should be ready right away. - EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(WithId(1))); + EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(1))); } INSTANTIATE_TEST_SUITE_P( diff --git a/video/video_receive_stream2_unittest.cc b/video/video_receive_stream2_unittest.cc index 4111e8eda6..317a322330 100644 --- a/video/video_receive_stream2_unittest.cc +++ b/video/video_receive_stream2_unittest.cc @@ -34,6 +34,7 @@ #include "rtc_base/event.h" #include "system_wrappers/include/clock.h" #include "test/fake_decoder.h" +#include "test/fake_encoded_frame.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/mock_transport.h" @@ -59,19 +60,6 @@ using ::testing::WithoutArgs; constexpr int kDefaultTimeOutMs = 50; -class FrameObjectFake : public EncodedFrame { - public: - void SetPayloadType(uint8_t payload_type) { _payloadType = payload_type; } - - void SetRotation(const VideoRotation& rotation) { rotation_ = rotation; } - - void SetNtpTime(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; } - - int64_t ReceivedTime() const override { return 0; } - - int64_t RenderTime() const override { return _renderTimeMs; } -}; - } // namespace class VideoReceiveStream2Test : public ::testing::Test { @@ -159,8 +147,8 @@ TEST_F(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) { TEST_F(VideoReceiveStream2Test, PlayoutDelay) { const VideoPlayoutDelay kPlayoutDelayMs = {123, 321}; - std::unique_ptr test_frame(new FrameObjectFake()); - test_frame->SetId(0); + std::unique_ptr test_frame = + test::FakeFrameBuilder().Id(0).AsLast().Build(); test_frame->SetPlayoutDelay(kPlayoutDelayMs); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); @@ -196,8 +184,8 @@ TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) { timing_->GetTimings().max_playout_delay; const VideoPlayoutDelay kPlayoutDelayMs = {123, -1}; - std::unique_ptr test_frame(new FrameObjectFake()); - test_frame->SetId(0); + std::unique_ptr test_frame = + test::FakeFrameBuilder().Id(0).AsLast().Build(); test_frame->SetPlayoutDelay(kPlayoutDelayMs); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); @@ -214,8 +202,8 @@ TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) { timing_->GetTimings().min_playout_delay; const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321}; - std::unique_ptr test_frame(new FrameObjectFake()); - test_frame->SetId(0); + std::unique_ptr test_frame = + test::FakeFrameBuilder().Id(0).AsLast().Build(); test_frame->SetPlayoutDelay(kPlayoutDelayMs); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); @@ -229,21 +217,21 @@ TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) { TEST_F(VideoReceiveStream2Test, MaxCompositionDelayNotSetByDefault) { // Default with no playout delay set. - std::unique_ptr test_frame0(new FrameObjectFake()); - test_frame0->SetId(0); + std::unique_ptr test_frame0 = + test::FakeFrameBuilder().Id(0).AsLast().Build(); video_receive_stream_->OnCompleteFrame(std::move(test_frame0)); EXPECT_FALSE(timing_->MaxCompositionDelayInFrames()); // Max composition delay not set for playout delay 0,0. - std::unique_ptr test_frame1(new FrameObjectFake()); - test_frame1->SetId(1); + std::unique_ptr test_frame1 = + test::FakeFrameBuilder().Id(1).AsLast().Build(); test_frame1->SetPlayoutDelay({0, 0}); video_receive_stream_->OnCompleteFrame(std::move(test_frame1)); EXPECT_FALSE(timing_->MaxCompositionDelayInFrames()); // Max composition delay not set for playout delay X,Y, where X,Y>0. - std::unique_ptr test_frame2(new FrameObjectFake()); - test_frame2->SetId(2); + std::unique_ptr test_frame2 = + test::FakeFrameBuilder().Id(2).AsLast().Build(); test_frame2->SetPlayoutDelay({10, 30}); video_receive_stream_->OnCompleteFrame(std::move(test_frame2)); EXPECT_FALSE(timing_->MaxCompositionDelayInFrames()); @@ -253,8 +241,8 @@ TEST_F(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) { // Max composition delay set if playout delay X,Y, where X=0,Y>0. const VideoPlayoutDelay kPlayoutDelayMs = {0, 50}; const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps. - std::unique_ptr test_frame(new FrameObjectFake()); - test_frame->SetId(0); + std::unique_ptr test_frame = + test::FakeFrameBuilder().Id(0).AsLast().Build(); test_frame->SetPlayoutDelay(kPlayoutDelayMs); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); EXPECT_EQ(kExpectedMaxCompositionDelayInFrames, @@ -321,24 +309,29 @@ class VideoReceiveStream2TestWithFakeDecoder : public ::testing::Test { }; TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesNtpTime) { - const int64_t kNtpTimestamp = 12345; - auto test_frame = std::make_unique(); - test_frame->SetPayloadType(99); - test_frame->SetId(0); - test_frame->SetNtpTime(kNtpTimestamp); + const Timestamp kNtpTimestamp = Timestamp::Millis(12345); + std::unique_ptr test_frame = + test::FakeFrameBuilder() + .Id(0) + .PayloadType(99) + .NtpTime(kNtpTimestamp) + .AsLast() + .Build(); video_receive_stream_->Start(); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs)); - EXPECT_EQ(kNtpTimestamp, fake_renderer_.ntp_time_ms()); + EXPECT_EQ(kNtpTimestamp.ms(), fake_renderer_.ntp_time_ms()); } TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesRotation) { const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180; - auto test_frame = std::make_unique(); - test_frame->SetPayloadType(99); - test_frame->SetId(0); - test_frame->SetRotation(kRotation); + std::unique_ptr test_frame = test::FakeFrameBuilder() + .Id(0) + .PayloadType(99) + .Rotation(kRotation) + .AsLast() + .Build(); video_receive_stream_->Start(); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); @@ -348,11 +341,13 @@ TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesRotation) { } TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesPacketInfos) { - auto test_frame = std::make_unique(); - test_frame->SetPayloadType(99); - test_frame->SetId(0); RtpPacketInfos packet_infos = CreatePacketInfos(3); - test_frame->SetPacketInfos(packet_infos); + auto test_frame = test::FakeFrameBuilder() + .Id(0) + .PayloadType(99) + .PacketInfos(packet_infos) + .AsLast() + .Build(); video_receive_stream_->Start(); video_receive_stream_->OnCompleteFrame(std::move(test_frame)); @@ -367,9 +362,8 @@ TEST_F(VideoReceiveStream2TestWithFakeDecoder, RenderedFrameUpdatesGetSources) { constexpr uint32_t kRtpTimestamp = 12345; // Prepare one video frame with per-packet information. - auto test_frame = std::make_unique(); - test_frame->SetPayloadType(99); - test_frame->SetId(0); + auto test_frame = + test::FakeFrameBuilder().Id(0).PayloadType(99).AsLast().Build(); RtpPacketInfos packet_infos; { RtpPacketInfos::vector_type infos; @@ -439,22 +433,21 @@ TEST_F(VideoReceiveStream2TestWithFakeDecoder, RenderedFrameUpdatesGetSources) { } } -std::unique_ptr MakeFrameWithResolution( +std::unique_ptr MakeFrameWithResolution( VideoFrameType frame_type, int picture_id, int width, int height) { - auto frame = std::make_unique(); - frame->SetPayloadType(99); - frame->SetId(picture_id); + auto frame = + test::FakeFrameBuilder().Id(picture_id).PayloadType(99).AsLast().Build(); frame->SetFrameType(frame_type); frame->_encodedWidth = width; frame->_encodedHeight = height; return frame; } -std::unique_ptr MakeFrame(VideoFrameType frame_type, - int picture_id) { +std::unique_ptr MakeFrame(VideoFrameType frame_type, + int picture_id) { return MakeFrameWithResolution(frame_type, picture_id, 320, 240); } diff --git a/video/video_stream_decoder_impl_unittest.cc b/video/video_stream_decoder_impl_unittest.cc index dd11e8c46d..d0cf9255c3 100644 --- a/video/video_stream_decoder_impl_unittest.cc +++ b/video/video_stream_decoder_impl_unittest.cc @@ -14,6 +14,7 @@ #include "api/video/i420_buffer.h" #include "api/video_codecs/video_decoder.h" +#include "test/fake_encoded_frame.h" #include "test/gmock.h" #include "test/gtest.h" #include "test/scoped_key_value_config.h" @@ -22,7 +23,6 @@ namespace webrtc { namespace { using ::testing::_; -using ::testing::ByMove; using ::testing::NiceMock; using ::testing::Return; @@ -127,35 +127,6 @@ class FakeVideoDecoderFactory : public VideoDecoderFactory { NiceMock av1_decoder_; }; -class FakeEncodedFrame : public EncodedFrame { - public: - int64_t ReceivedTime() const override { return 0; } - int64_t RenderTime() const override { return 0; } - - // Setters for protected variables. - void SetPayloadType(int payload_type) { _payloadType = payload_type; } -}; - -class FrameBuilder { - public: - FrameBuilder() : frame_(std::make_unique()) {} - - FrameBuilder& WithPayloadType(int payload_type) { - frame_->SetPayloadType(payload_type); - return *this; - } - - FrameBuilder& WithPictureId(int picture_id) { - frame_->SetId(picture_id); - return *this; - } - - std::unique_ptr Build() { return std::move(frame_); } - - private: - std::unique_ptr frame_; -}; - class VideoStreamDecoderImplTest : public ::testing::Test { public: VideoStreamDecoderImplTest() @@ -179,7 +150,8 @@ class VideoStreamDecoderImplTest : public ::testing::Test { }; TEST_F(VideoStreamDecoderImplTest, InsertAndDecodeFrame) { - video_stream_decoder_.OnFrame(FrameBuilder().WithPayloadType(1).Build()); + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); EXPECT_CALL(callbacks_, OnDecodedFrame); time_controller_.AdvanceTime(TimeDelta::Millis(1)); } @@ -190,7 +162,8 @@ TEST_F(VideoStreamDecoderImplTest, NonDecodableStateWaitingForKeyframe) { } TEST_F(VideoStreamDecoderImplTest, NonDecodableStateWaitingForDeltaFrame) { - video_stream_decoder_.OnFrame(FrameBuilder().WithPayloadType(1).Build()); + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); EXPECT_CALL(callbacks_, OnDecodedFrame); time_controller_.AdvanceTime(TimeDelta::Millis(1)); EXPECT_CALL(callbacks_, OnNonDecodableState); @@ -198,7 +171,8 @@ TEST_F(VideoStreamDecoderImplTest, NonDecodableStateWaitingForDeltaFrame) { } TEST_F(VideoStreamDecoderImplTest, InsertAndDecodeFrameWithKeyframeRequest) { - video_stream_decoder_.OnFrame(FrameBuilder().WithPayloadType(1).Build()); + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); EXPECT_CALL(decoder_factory_.Vp8Decoder(), DecodeCall) .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME)); EXPECT_CALL(callbacks_, OnDecodedFrame); @@ -207,7 +181,12 @@ TEST_F(VideoStreamDecoderImplTest, InsertAndDecodeFrameWithKeyframeRequest) { } TEST_F(VideoStreamDecoderImplTest, FailToInitDecoder) { - video_stream_decoder_.OnFrame(FrameBuilder().WithPayloadType(1).Build()); + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder() + .ReceivedTime(time_controller_.GetClock()->CurrentTime()) + .PayloadType(1) + .AsLast() + .Build()); ON_CALL(decoder_factory_.Vp8Decoder(), Configure) .WillByDefault(Return(false)); EXPECT_CALL(callbacks_, OnNonDecodableState); @@ -215,7 +194,8 @@ TEST_F(VideoStreamDecoderImplTest, FailToInitDecoder) { } TEST_F(VideoStreamDecoderImplTest, FailToDecodeFrame) { - video_stream_decoder_.OnFrame(FrameBuilder().WithPayloadType(1).Build()); + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); ON_CALL(decoder_factory_.Vp8Decoder(), DecodeCall) .WillByDefault(Return(WEBRTC_VIDEO_CODEC_ERROR)); EXPECT_CALL(callbacks_, OnNonDecodableState); @@ -225,13 +205,13 @@ TEST_F(VideoStreamDecoderImplTest, FailToDecodeFrame) { TEST_F(VideoStreamDecoderImplTest, ChangeFramePayloadType) { constexpr TimeDelta kFrameInterval = TimeDelta::Millis(1000 / 60); video_stream_decoder_.OnFrame( - FrameBuilder().WithPayloadType(1).WithPictureId(0).Build()); + test::FakeFrameBuilder().PayloadType(1).Id(0).AsLast().Build()); EXPECT_CALL(decoder_factory_.Vp8Decoder(), DecodeCall); EXPECT_CALL(callbacks_, OnDecodedFrame); time_controller_.AdvanceTime(kFrameInterval); video_stream_decoder_.OnFrame( - FrameBuilder().WithPayloadType(2).WithPictureId(1).Build()); + test::FakeFrameBuilder().PayloadType(2).Id(1).AsLast().Build()); EXPECT_CALL(decoder_factory_.Av1Decoder(), DecodeCall); EXPECT_CALL(callbacks_, OnDecodedFrame); time_controller_.AdvanceTime(kFrameInterval);