Implement test class LoopbackMediaTransport
Bug: webrtc:9719
Change-Id: I82aa962d1cb8f2c8f56f766cb12562690e595045
Reviewed-on: https://webrtc-review.googlesource.com/c/105661
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Peter Slatala <psla@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Anton Sukhanov <sukhanov@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25196}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 5aee948..0cfa592 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -550,34 +550,6 @@
]
}
- rtc_source_set("rtc_api_unittests") {
- testonly = true
-
- sources = [
- "array_view_unittest.cc",
- "ortc/mediadescription_unittest.cc",
- "ortc/sessiondescription_unittest.cc",
- "rtcerror_unittest.cc",
- "rtpparameters_unittest.cc",
- ]
-
- if (!build_with_chromium && is_clang) {
- # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
- suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
- }
-
- deps = [
- ":array_view",
- ":libjingle_peerconnection_api",
- ":ortc_api",
- "../rtc_base:checks",
- "../rtc_base:rtc_base_approved",
- "../rtc_base:rtc_base_tests_utils",
- "../test:test_support",
- "units:units_unittests",
- ]
- }
-
rtc_source_set("fake_media_transport") {
testonly = true
@@ -590,4 +562,47 @@
"../rtc_base:checks",
]
}
+
+ rtc_source_set("loopback_media_transport") {
+ testonly = true
+
+ sources = [
+ "test/loopback_media_transport.h",
+ ]
+
+ deps = [
+ ":libjingle_peerconnection_api",
+ "../rtc_base:checks",
+ ]
+ }
+
+ rtc_source_set("rtc_api_unittests") {
+ testonly = true
+
+ sources = [
+ "array_view_unittest.cc",
+ "ortc/mediadescription_unittest.cc",
+ "ortc/sessiondescription_unittest.cc",
+ "rtcerror_unittest.cc",
+ "rtpparameters_unittest.cc",
+ "test/loopback_media_transport_unittest.cc",
+ ]
+
+ if (!build_with_chromium && is_clang) {
+ # Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
+ suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
+ }
+
+ deps = [
+ ":array_view",
+ ":libjingle_peerconnection_api",
+ ":loopback_media_transport",
+ ":ortc_api",
+ "../rtc_base:checks",
+ "../rtc_base:rtc_base_approved",
+ "../rtc_base:rtc_base_tests_utils",
+ "../test:test_support",
+ "units:units_unittests",
+ ]
+ }
}
diff --git a/api/test/loopback_media_transport.h b/api/test/loopback_media_transport.h
new file mode 100644
index 0000000..04e14b2
--- /dev/null
+++ b/api/test/loopback_media_transport.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2018 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 API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_
+#define API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_
+
+#include <utility>
+
+#include "api/media_transport_interface.h"
+
+namespace webrtc {
+
+// Contains two MediaTransportsInterfaces that are connected to each other.
+// Currently supports audio only.
+class MediaTransportPair {
+ public:
+ MediaTransportPair()
+ : pipe_{LoopbackMediaTransport(&pipe_[1]),
+ LoopbackMediaTransport(&pipe_[0])} {}
+
+ // Ownership stays with MediaTransportPair
+ MediaTransportInterface* first() { return &pipe_[0]; }
+ MediaTransportInterface* second() { return &pipe_[1]; }
+
+ private:
+ class LoopbackMediaTransport : public MediaTransportInterface {
+ public:
+ explicit LoopbackMediaTransport(LoopbackMediaTransport* other)
+ : other_(other) {}
+ ~LoopbackMediaTransport() { RTC_CHECK(sink_ == nullptr); }
+
+ RTCError SendAudioFrame(uint64_t channel_id,
+ MediaTransportEncodedAudioFrame frame) override {
+ other_->OnData(channel_id, std::move(frame));
+ return RTCError::OK();
+ };
+
+ RTCError SendVideoFrame(
+ uint64_t channel_id,
+ const MediaTransportEncodedVideoFrame& frame) override {
+ return RTCError::OK();
+ }
+
+ RTCError RequestKeyFrame(uint64_t channel_id) override {
+ return RTCError::OK();
+ }
+
+ void SetReceiveAudioSink(MediaTransportAudioSinkInterface* sink) override {
+ if (sink) {
+ RTC_CHECK(sink_ == nullptr);
+ }
+ sink_ = sink;
+ }
+
+ void SetReceiveVideoSink(MediaTransportVideoSinkInterface* sink) override {}
+
+ private:
+ void OnData(uint64_t channel_id, MediaTransportEncodedAudioFrame frame) {
+ if (sink_) {
+ sink_->OnData(channel_id, frame);
+ }
+ }
+
+ MediaTransportAudioSinkInterface* sink_ = nullptr;
+ LoopbackMediaTransport* other_;
+ };
+
+ LoopbackMediaTransport pipe_[2];
+};
+
+} // namespace webrtc
+
+#endif // API_TEST_LOOPBACK_MEDIA_TRANSPORT_H_
diff --git a/api/test/loopback_media_transport_unittest.cc b/api/test/loopback_media_transport_unittest.cc
new file mode 100644
index 0000000..bff74b8
--- /dev/null
+++ b/api/test/loopback_media_transport_unittest.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2018 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 <vector>
+
+#include "api/test/loopback_media_transport.h"
+#include "test/gmock.h"
+
+namespace webrtc {
+
+namespace {
+
+class MockMediaTransportAudioSinkInterface
+ : public MediaTransportAudioSinkInterface {
+ public:
+ MOCK_METHOD2(OnData, void(uint64_t, MediaTransportEncodedAudioFrame));
+};
+
+// Test only uses the sequence number.
+MediaTransportEncodedAudioFrame CreateAudioFrame(int sequence_number) {
+ static constexpr int kSamplingRateHz = 48000;
+ static constexpr int kStartingSampleIndex = 0;
+ static constexpr int kSamplesPerChannel = 480;
+ static constexpr uint8_t kPayloadType = 17;
+
+ return MediaTransportEncodedAudioFrame(
+ kSamplingRateHz, kStartingSampleIndex, kSamplesPerChannel,
+ sequence_number, MediaTransportEncodedAudioFrame::FrameType::kSpeech,
+ kPayloadType, std::vector<uint8_t>(kSamplesPerChannel));
+}
+
+} // namespace
+
+TEST(LoopbackMediaTransport, AudioWithNoSinkSilentlyIgnored) {
+ MediaTransportPair transport_pair;
+ transport_pair.first()->SendAudioFrame(1, CreateAudioFrame(0));
+ transport_pair.second()->SendAudioFrame(2, CreateAudioFrame(0));
+}
+
+TEST(LoopbackMediaTransport, AudioDeliveredToSink) {
+ MediaTransportPair transport_pair;
+ testing::StrictMock<MockMediaTransportAudioSinkInterface> sink;
+ EXPECT_CALL(sink,
+ OnData(1, testing::Property(
+ &MediaTransportEncodedAudioFrame::sequence_number,
+ testing::Eq(10))));
+ transport_pair.second()->SetReceiveAudioSink(&sink);
+ transport_pair.first()->SendAudioFrame(1, CreateAudioFrame(10));
+
+ transport_pair.second()->SetReceiveAudioSink(nullptr);
+}
+
+} // namespace webrtc