1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <gtest/gtest.h> 6e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include <stdint.h> 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind_helpers.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/test/simple_test_tick_clock.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/values.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/cast/cast_config.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/cast_transport_config.h" 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/cast_transport_sender_impl.h" 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/rtcp/rtcp.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/cast/test/fake_single_thread_task_runner.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace media { 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace cast { 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace { 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const int64 kStartMillisecond = INT64_C(12345678900000); 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const uint32 kVideoSsrc = 1; 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const uint32 kAudioSsrc = 2; 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} // namespace 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass FakePacketSender : public PacketSender { 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public: 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FakePacketSender() 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : paused_(false), packets_sent_(0), bytes_sent_(0) {} 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual bool SendPacket(PacketRef packet, const base::Closure& cb) OVERRIDE { 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (paused_) { 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) stored_packet_ = packet; 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) callback_ = cb; 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ++packets_sent_; 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bytes_sent_ += packet->data.size(); 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return true; 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) virtual int64 GetBytesSent() OVERRIDE { 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return bytes_sent_; 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void SetPaused(bool paused) { 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) paused_ = paused; 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!paused && stored_packet_.get()) { 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) SendPacket(stored_packet_, callback_); 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) callback_.Run(); 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int packets_sent() const { return packets_sent_; } 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private: 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool paused_; 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Closure callback_; 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PacketRef stored_packet_; 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int packets_sent_; 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) int64 bytes_sent_; 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FakePacketSender); 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class CastTransportSenderImplTest : public ::testing::Test { 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) protected: 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) CastTransportSenderImplTest() 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : num_times_callback_called_(0) { 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) testing_clock_.Advance( 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kStartMillisecond)); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) task_runner_ = new test::FakeSingleThreadTaskRunner(&testing_clock_); 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual ~CastTransportSenderImplTest() {} 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void InitWithoutLogging() { 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transport_sender_.reset( 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new CastTransportSenderImpl(NULL, 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &testing_clock_, 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::IPEndPoint(), 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci make_scoped_ptr(new base::DictionaryValue), 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&UpdateCastTransportStatus), 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci BulkRawEventsCallback(), 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::TimeDelta(), 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_, 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &transport_)); 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_->RunTasks(); 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void InitWithOptions() { 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<base::DictionaryValue> options( 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new base::DictionaryValue); 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci options->SetBoolean("DHCP", true); 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci options->SetBoolean("disable_wifi_scan", true); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci options->SetBoolean("media_streaming_mode", true); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci options->SetInteger("pacer_target_burst_size", 20); 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci options->SetInteger("pacer_max_burst_size", 100); 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transport_sender_.reset( 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new CastTransportSenderImpl(NULL, 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &testing_clock_, 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::IPEndPoint(), 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci options.Pass(), 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&UpdateCastTransportStatus), 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BulkRawEventsCallback(), 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta(), 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) task_runner_, 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &transport_)); 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) task_runner_->RunTasks(); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) void InitWithLogging() { 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) transport_sender_.reset(new CastTransportSenderImpl( 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL, 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &testing_clock_, 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::IPEndPoint(), 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci make_scoped_ptr(new base::DictionaryValue), 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&UpdateCastTransportStatus), 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&CastTransportSenderImplTest::LogRawEvents, 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this)), 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10), 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) task_runner_, 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &transport_)); 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) task_runner_->RunTasks(); 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void InitializeVideo() { 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CastTransportRtpConfig rtp_config; 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) rtp_config.ssrc = kVideoSsrc; 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) rtp_config.feedback_ssrc = 2; 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) rtp_config.rtp_payload_type = 3; 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->InitializeVideo(rtp_config, 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessageCallback(), 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpRttCallback()); 13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) void InitializeAudio() { 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) CastTransportRtpConfig rtp_config; 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) rtp_config.ssrc = kAudioSsrc; 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) rtp_config.feedback_ssrc = 3; 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) rtp_config.rtp_payload_type = 4; 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->InitializeAudio(rtp_config, 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessageCallback(), 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpRttCallback()); 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void LogRawEvents(const std::vector<PacketEvent>& packet_events, 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::vector<FrameEvent>& frame_events) { 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) num_times_callback_called_++; 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch static void UpdateCastTransportStatus(CastTransportStatus status) { 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::SimpleTestTickClock testing_clock_; 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<CastTransportSenderImpl> transport_sender_; 161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FakePacketSender transport_; 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int num_times_callback_called_; 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(CastTransportSenderImplTest, InitWithoutLogging) { 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitWithoutLogging(); 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(0, num_times_callback_called_); 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST_F(CastTransportSenderImplTest, InitWithLogging) { 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) InitWithLogging(); 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(5, num_times_callback_called_); 175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(CastTransportSenderImplTest, InitWithOptions) { 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InitWithOptions(); 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(0, num_times_callback_called_); 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(CastTransportSenderImplTest, NacksCancelRetransmits) { 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitWithoutLogging(); 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitializeVideo(); 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // A fake frame that will be decomposed into 4 packets. 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EncodedFrame fake_frame; 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.frame_id = 1; 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.rtp_timestamp = 1; 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.dependency = EncodedFrame::KEY; 19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.data.resize(5000, ' '); 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transport_sender_->InsertFrame(kVideoSsrc, fake_frame); 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(4, transport_.packets_sent()); 19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resend packet 0. 20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MissingFramesAndPacketsMap missing_packets; 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) missing_packets[1].insert(0); 20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) missing_packets[1].insert(1); 20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) missing_packets[1].insert(2); 20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(true); 20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DedupInfo dedup_info; 20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10); 20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->ResendPackets( 20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) kVideoSsrc, missing_packets, true, dedup_info); 21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessage cast_message; 21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.media_ssrc = kVideoSsrc; 21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.ack_frame_id = 1; 21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.missing_frames_and_packets[1].insert(3); 21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->OnReceivedCastMessage(kVideoSsrc, 21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessageCallback(), 21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message); 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(false); 22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resend one packet in the socket when unpaused. 22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resend one more packet from NACK. 22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(6, transport_.packets_sent()); 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(CastTransportSenderImplTest, CancelRetransmits) { 22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitWithoutLogging(); 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitializeVideo(); 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // A fake frame that will be decomposed into 4 packets. 23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EncodedFrame fake_frame; 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.frame_id = 1; 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.rtp_timestamp = 1; 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.dependency = EncodedFrame::KEY; 23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.data.resize(5000, ' '); 23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transport_sender_->InsertFrame(kVideoSsrc, fake_frame); 24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(4, transport_.packets_sent()); 24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resend all packets for frame 1. 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MissingFramesAndPacketsMap missing_packets; 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) missing_packets[1].insert(kRtcpCastAllPacketsLost); 24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(true); 24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DedupInfo dedup_info; 25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10); 25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->ResendPackets( 25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) kVideoSsrc, missing_packets, true, dedup_info); 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<uint32> cancel_sending_frames; 25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cancel_sending_frames.push_back(1); 25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->CancelSendingFrames(kVideoSsrc, 25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cancel_sending_frames); 25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(false); 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resend one packet in the socket when unpaused. 26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(5, transport_.packets_sent()); 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(CastTransportSenderImplTest, Kickstart) { 26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitWithoutLogging(); 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitializeVideo(); 26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); 27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // A fake frame that will be decomposed into 4 packets. 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EncodedFrame fake_frame; 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.frame_id = 1; 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.rtp_timestamp = 1; 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.dependency = EncodedFrame::KEY; 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_frame.data.resize(5000, ' '); 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(true); 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transport_sender_->InsertFrame(kVideoSsrc, fake_frame); 28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1); 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(false); 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(4, transport_.packets_sent()); 28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resend 2 packets for frame 1. 28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) MissingFramesAndPacketsMap missing_packets; 28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) missing_packets[1].insert(0); 28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) missing_packets[1].insert(1); 28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(true); 29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DedupInfo dedup_info; 29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) dedup_info.resend_interval = base::TimeDelta::FromMilliseconds(10); 29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->ResendPackets( 29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) kVideoSsrc, missing_packets, true, dedup_info); 29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->ResendFrameForKickstart(kVideoSsrc, 1); 29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_.SetPaused(false); 29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Resend one packet in the socket when unpaused. 30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Two more retransmission packets sent. 30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(7, transport_.packets_sent()); 30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TEST_F(CastTransportSenderImplTest, DedupRetransmissionWithAudio) { 30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitWithoutLogging(); 30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitializeAudio(); 30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) InitializeVideo(); 30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(50)); 30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Send two audio frames. 31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EncodedFrame fake_audio; 31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_audio.frame_id = 1; 31303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_audio.reference_time = testing_clock_.NowTicks(); 31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_audio.dependency = EncodedFrame::KEY; 31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_audio.data.resize(100, ' '); 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transport_sender_->InsertFrame(kAudioSsrc, fake_audio); 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2)); 31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_audio.frame_id = 2; 31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_audio.reference_time = testing_clock_.NowTicks(); 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transport_sender_->InsertFrame(kAudioSsrc, fake_audio); 32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2)); 32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(2, transport_.packets_sent()); 32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Ack the first audio frame. 32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessage cast_message; 32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.media_ssrc = kAudioSsrc; 32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.ack_frame_id = 1; 32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->OnReceivedCastMessage(kAudioSsrc, 32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessageCallback(), 33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message); 33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->RunTasks(); 33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(2, transport_.packets_sent()); 33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Send a fake video frame that will be decomposed into 4 packets. 33503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EncodedFrame fake_video; 33603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_video.frame_id = 1; 33703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_video.dependency = EncodedFrame::KEY; 33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) fake_video.data.resize(5000, ' '); 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci transport_sender_->InsertFrame(kVideoSsrc, fake_video); 34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->RunTasks(); 34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(6, transport_.packets_sent()); 34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Retransmission is reject because audio is not acked yet. 34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.media_ssrc = kVideoSsrc; 34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.ack_frame_id = 0; 34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.missing_frames_and_packets[1].insert(3); 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(10)); 34803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->OnReceivedCastMessage(kVideoSsrc, 34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessageCallback(), 35003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message); 35103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->RunTasks(); 35203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(6, transport_.packets_sent()); 35303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 35403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Ack the second audio frame. 35503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.media_ssrc = kAudioSsrc; 35603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.ack_frame_id = 2; 35703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.missing_frames_and_packets.clear(); 35803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2)); 35903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->OnReceivedCastMessage(kAudioSsrc, 36003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessageCallback(), 36103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message); 36203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->RunTasks(); 36303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(6, transport_.packets_sent()); 36403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 36503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // Retransmission of video packet now accepted. 36603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.media_ssrc = kVideoSsrc; 36703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.ack_frame_id = 1; 36803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message.missing_frames_and_packets[1].insert(3); 36903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->Sleep(base::TimeDelta::FromMilliseconds(2)); 37003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) transport_sender_->OnReceivedCastMessage(kVideoSsrc, 37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) RtcpCastMessageCallback(), 37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) cast_message); 37303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) task_runner_->RunTasks(); 37403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) EXPECT_EQ(7, transport_.packets_sent()); 37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 37603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 377a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace cast 378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace media 379