From 2e47f7c4eeb9c2a9cfe5e4e8b079db5b127cdf8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Tue, 16 Oct 2018 10:41:42 +0200 Subject: [PATCH] Implement test class LoopbackMediaTransport Bug: webrtc:9719 Change-Id: I82aa962d1cb8f2c8f56f766cb12562690e595045 Reviewed-on: https://webrtc-review.googlesource.com/c/105661 Commit-Queue: Niels Moller Reviewed-by: Peter Slatala Reviewed-by: Karl Wiberg Reviewed-by: Anton Sukhanov Cr-Commit-Position: refs/heads/master@{#25196} --- api/BUILD.gn | 71 +++++++++------- api/test/loopback_media_transport.h | 80 +++++++++++++++++++ api/test/loopback_media_transport_unittest.cc | 60 ++++++++++++++ 3 files changed, 183 insertions(+), 28 deletions(-) create mode 100644 api/test/loopback_media_transport.h create mode 100644 api/test/loopback_media_transport_unittest.cc diff --git a/api/BUILD.gn b/api/BUILD.gn index 5aee9486da..0cfa592ab5 100644 --- a/api/BUILD.gn +++ b/api/BUILD.gn @@ -550,34 +550,6 @@ if (rtc_include_tests) { ] } - 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 @@ if (rtc_include_tests) { "../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 0000000000..04e14b287c --- /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 + +#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 0000000000..bff74b8930 --- /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 + +#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(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 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