summaryrefslogtreecommitdiffstats
path: root/media/cast
diff options
context:
space:
mode:
authormikhal@chromium.org <mikhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-04 00:26:10 +0000
committermikhal@chromium.org <mikhal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-03-04 00:26:10 +0000
commit0bec2d88ede93585840b6775be337e5d6ce035d5 (patch)
tree2bb8cc56d6c60a6cb5b92ca77a002f0b1298fe57 /media/cast
parent4be5aac332f8cd47b660f8b7b5d8e275d9388d78 (diff)
downloadchromium_src-0bec2d88ede93585840b6775be337e5d6ce035d5.zip
chromium_src-0bec2d88ede93585840b6775be337e5d6ce035d5.tar.gz
chromium_src-0bec2d88ede93585840b6775be337e5d6ce035d5.tar.bz2
Cast:Transport: Dividing A/V Initialization pipeline
This cl is part of the effort to split the A/V initialization pipeline, which started in https://chromiumcodereview.appspot.com/163553006/. Main changes in this cl: 1. Adding initialization functions to audio and video. 2. Changing the Create API to return a scoped ptr. 3. Using weak pointers in lieu of Unretained (part of BUG=344621) BUG=346822 This cl must be committed prior to issue 163553006 Review URL: https://codereview.chromium.org/174183003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254615 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/cast')
-rw-r--r--media/cast/audio_sender/audio_sender.cc10
-rw-r--r--media/cast/audio_sender/audio_sender_unittest.cc14
-rw-r--r--media/cast/rtcp/rtcp_unittest.cc9
-rw-r--r--media/cast/test/end2end_unittest.cc45
-rw-r--r--media/cast/test/sender.cc32
-rw-r--r--media/cast/transport/cast_transport_config.cc27
-rw-r--r--media/cast/transport/cast_transport_config.h40
-rw-r--r--media/cast/transport/cast_transport_defines.h6
-rw-r--r--media/cast/transport/cast_transport_sender.h19
-rw-r--r--media/cast/transport/cast_transport_sender_impl.cc79
-rw-r--r--media/cast/transport/cast_transport_sender_impl.h14
-rw-r--r--media/cast/transport/pacing/paced_sender.h2
-rw-r--r--media/cast/transport/rtp_sender/rtp_sender.cc56
-rw-r--r--media/cast/transport/rtp_sender/rtp_sender.h24
-rw-r--r--media/cast/transport/transport_audio_sender.cc16
-rw-r--r--media/cast/transport/transport_audio_sender.h4
-rw-r--r--media/cast/transport/transport_video_sender.cc18
-rw-r--r--media/cast/transport/transport_video_sender.h5
-rw-r--r--media/cast/video_sender/video_sender_unittest.cc9
19 files changed, 257 insertions, 172 deletions
diff --git a/media/cast/audio_sender/audio_sender.cc b/media/cast/audio_sender/audio_sender.cc
index bdf6b29..4ca58ea 100644
--- a/media/cast/audio_sender/audio_sender.cc
+++ b/media/cast/audio_sender/audio_sender.cc
@@ -43,9 +43,11 @@ class LocalRtpSenderStatistics : public RtpSenderStatistics {
: transport_sender_(transport_sender),
frequency_(0),
sender_info_(),
- rtp_timestamp_(0) {
- transport_sender_->SubscribeAudioRtpStatsCallback(base::Bind(
- &LocalRtpSenderStatistics::StoreStatistics, base::Unretained(this)));
+ rtp_timestamp_(0),
+ weak_factory_(this) {
+ transport_sender_->SubscribeAudioRtpStatsCallback(
+ base::Bind(&LocalRtpSenderStatistics::StoreStatistics,
+ weak_factory_.GetWeakPtr()));
}
virtual void GetStatistics(const base::TimeTicks& now,
@@ -84,6 +86,8 @@ class LocalRtpSenderStatistics : public RtpSenderStatistics {
base::TimeTicks time_sent_;
uint32 rtp_timestamp_;
+ base::WeakPtrFactory<LocalRtpSenderStatistics> weak_factory_;
+
DISALLOW_IMPLICIT_CONSTRUCTORS(LocalRtpSenderStatistics);
};
diff --git a/media/cast/audio_sender/audio_sender_unittest.cc b/media/cast/audio_sender/audio_sender_unittest.cc
index 1546996..8db06cb 100644
--- a/media/cast/audio_sender/audio_sender_unittest.cc
+++ b/media/cast/audio_sender/audio_sender_unittest.cc
@@ -77,16 +77,20 @@ class AudioSenderTest : public ::testing::Test {
audio_config_.bitrate = kDefaultAudioEncoderBitrate;
audio_config_.rtp_config.payload_type = 127;
- transport::CastTransportConfig transport_config;
- transport_config.audio_rtp_config.payload_type = 127;
- transport_config.audio_channels = 2;
+ transport::CastTransportAudioConfig transport_config;
+ transport_config.base.rtp_config.payload_type = 127;
+ transport_config.channels = 2;
+ net::IPEndPoint dummy_endpoint;
+
transport_sender_.reset(new transport::CastTransportSenderImpl(
NULL,
testing_clock_,
- transport_config,
+ dummy_endpoint,
+ dummy_endpoint,
base::Bind(&UpdateCastTransportStatus),
task_runner_,
&transport_));
+ transport_sender_->InitializeAudio(transport_config);
audio_sender_.reset(new AudioSender(
cast_environment_, audio_config_, transport_sender_.get()));
task_runner_->RunTasks();
@@ -95,7 +99,7 @@ class AudioSenderTest : public ::testing::Test {
virtual ~AudioSenderTest() {}
static void UpdateCastTransportStatus(transport::CastTransportStatus status) {
- EXPECT_EQ(status, transport::TRANSPORT_INITIALIZED);
+ EXPECT_EQ(status, transport::TRANSPORT_AUDIO_INITIALIZED);
}
base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment.
diff --git a/media/cast/rtcp/rtcp_unittest.cc b/media/cast/rtcp/rtcp_unittest.cc
index 99e4a32..9ee0523 100644
--- a/media/cast/rtcp/rtcp_unittest.cc
+++ b/media/cast/rtcp/rtcp_unittest.cc
@@ -158,11 +158,12 @@ class RtcpTest : public ::testing::Test {
receiver_to_sender_(cast_environment_, testing_clock_) {
testing_clock_->Advance(
base::TimeDelta::FromMilliseconds(kStartMillisecond));
- transport::CastTransportConfig transport_config;
+ net::IPEndPoint dummy_endpoint;
transport_sender_.reset(new transport::CastTransportSenderImpl(
NULL,
testing_clock_,
- transport_config,
+ dummy_endpoint,
+ dummy_endpoint,
base::Bind(&UpdateCastTransportStatus),
task_runner_,
&sender_to_receiver_));
@@ -172,7 +173,9 @@ class RtcpTest : public ::testing::Test {
virtual ~RtcpTest() {}
static void UpdateCastTransportStatus(transport::CastTransportStatus status) {
- EXPECT_EQ(status, transport::TRANSPORT_INITIALIZED);
+ bool result = (status == transport::TRANSPORT_AUDIO_INITIALIZED ||
+ status == transport::TRANSPORT_VIDEO_INITIALIZED);
+ EXPECT_TRUE(result);
}
void RunTasks(int during_ms) {
diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc
index 9c4562a..70f7c46 100644
--- a/media/cast/test/end2end_unittest.cc
+++ b/media/cast/test/end2end_unittest.cc
@@ -90,7 +90,9 @@ std::string ConvertFromBase16String(const std::string base_16) {
void OwnThatAudioBus(scoped_ptr<AudioBus> audio_bus) {}
void UpdateCastTransportStatus(transport::CastTransportStatus status) {
- EXPECT_EQ(status, transport::TRANSPORT_INITIALIZED);
+ bool result = (status == transport::TRANSPORT_AUDIO_INITIALIZED ||
+ status == transport::TRANSPORT_VIDEO_INITIALIZED);
+ EXPECT_TRUE(result);
}
// This is wrapped in a struct because it needs to be put into a std::map.
@@ -478,14 +480,14 @@ class End2EndTest : public ::testing::Test {
video_receiver_config_.use_external_decoder = false;
video_receiver_config_.codec = video_sender_config_.codec;
- transport_config_.audio_ssrc = audio_sender_config_.sender_ssrc;
- transport_config_.video_ssrc = video_sender_config_.sender_ssrc;
- transport_config_.video_codec = video_sender_config_.codec;
- transport_config_.audio_codec = audio_sender_config_.codec;
- transport_config_.video_rtp_config = video_sender_config_.rtp_config;
- transport_config_.audio_rtp_config = audio_sender_config_.rtp_config;
- transport_config_.audio_frequency = audio_sender_config_.frequency;
- transport_config_.audio_channels = audio_sender_config_.channels;
+ transport_audio_config_.base.ssrc = audio_sender_config_.sender_ssrc;
+ transport_audio_config_.codec = audio_sender_config_.codec;
+ transport_audio_config_.base.rtp_config = audio_sender_config_.rtp_config;
+ transport_audio_config_.frequency = audio_sender_config_.frequency;
+ transport_audio_config_.channels = audio_sender_config_.channels;
+ transport_video_config_.base.ssrc = video_sender_config_.sender_ssrc;
+ transport_video_config_.codec = video_sender_config_.codec;
+ transport_video_config_.base.rtp_config = video_sender_config_.rtp_config;
}
void Create() {
@@ -494,13 +496,17 @@ class End2EndTest : public ::testing::Test {
audio_receiver_config_,
video_receiver_config_,
&receiver_to_sender_));
+ net::IPEndPoint dummy_endpoint;
transport_sender_.reset(new transport::CastTransportSenderImpl(
NULL,
testing_clock_sender_,
- transport_config_,
+ dummy_endpoint,
+ dummy_endpoint,
base::Bind(&UpdateCastTransportStatus),
task_runner_,
&sender_to_receiver_));
+ transport_sender_->InitializeAudio(transport_audio_config_);
+ transport_sender_->InitializeVideo(transport_video_config_);
cast_sender_.reset(CastSender::CreateCastSender(
cast_environment_sender_,
@@ -565,7 +571,8 @@ class End2EndTest : public ::testing::Test {
VideoReceiverConfig video_receiver_config_;
AudioSenderConfig audio_sender_config_;
VideoSenderConfig video_sender_config_;
- transport::CastTransportConfig transport_config_;
+ transport::CastTransportAudioConfig transport_audio_config_;
+ transport::CastTransportVideoConfig transport_video_config_;
base::TimeTicks start_time_;
base::SimpleTestTickClock* testing_clock_sender_;
@@ -974,13 +981,13 @@ TEST_F(End2EndTest, ResetReferenceFrameId) {
TEST_F(End2EndTest, CryptoVideo) {
SetupConfig(transport::kPcm16, 32000, false, 1);
- transport_config_.aes_iv_mask =
+ transport_video_config_.base.aes_iv_mask =
ConvertFromBase16String("1234567890abcdeffedcba0987654321");
- transport_config_.aes_key =
+ transport_video_config_.base.aes_key =
ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef");
- video_receiver_config_.aes_iv_mask = transport_config_.aes_iv_mask;
- video_receiver_config_.aes_key = transport_config_.aes_key;
+ video_receiver_config_.aes_iv_mask = transport_video_config_.base.aes_iv_mask;
+ video_receiver_config_.aes_key = transport_video_config_.base.aes_key;
Create();
@@ -1011,13 +1018,13 @@ TEST_F(End2EndTest, CryptoVideo) {
TEST_F(End2EndTest, CryptoAudio) {
SetupConfig(transport::kPcm16, 32000, false, 1);
- transport_config_.aes_iv_mask =
+ transport_audio_config_.base.aes_iv_mask =
ConvertFromBase16String("abcdeffedcba12345678900987654321");
- transport_config_.aes_key =
+ transport_audio_config_.base.aes_key =
ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0");
- audio_receiver_config_.aes_iv_mask = transport_config_.aes_iv_mask;
- audio_receiver_config_.aes_key = transport_config_.aes_key;
+ audio_receiver_config_.aes_iv_mask = transport_audio_config_.base.aes_iv_mask;
+ audio_receiver_config_.aes_key = transport_audio_config_.base.aes_key;
Create();
diff --git a/media/cast/test/sender.cc b/media/cast/test/sender.cc
index 16f55dc..af369eb 100644
--- a/media/cast/test/sender.cc
+++ b/media/cast/test/sender.cc
@@ -411,21 +411,27 @@ int main(int argc, char** argv) {
media::cast::GetVideoSenderConfig();
// Setting up transport config.
- media::cast::transport::CastTransportConfig config;
- config.receiver_endpoint = CreateUDPAddress(remote_ip_address, remote_port);
- config.local_endpoint = CreateUDPAddress("0.0.0.0", 0);
- config.audio_ssrc = audio_config.sender_ssrc;
- config.video_ssrc = video_config.sender_ssrc;
- config.audio_rtp_config = audio_config.rtp_config;
- config.video_rtp_config = video_config.rtp_config;
-
- scoped_ptr<media::cast::transport::CastTransportSender> transport_sender(
- media::cast::transport::CastTransportSender::CreateCastTransportSender(
- NULL,
+ media::cast::transport::CastTransportAudioConfig transport_audio_config;
+ media::cast::transport::CastTransportVideoConfig transport_video_config;
+ net::IPEndPoint remote_endpoint =
+ CreateUDPAddress(remote_ip_address, remote_port);
+ net::IPEndPoint local_endpoint = CreateUDPAddress("0.0.0.0", 0);
+ transport_audio_config.base.ssrc = audio_config.sender_ssrc;
+ transport_audio_config.base.rtp_config = audio_config.rtp_config;
+ transport_video_config.base.ssrc = video_config.sender_ssrc;
+ transport_video_config.base.rtp_config = video_config.rtp_config;
+
+ scoped_ptr<media::cast::transport::CastTransportSender> transport_sender =
+ media::cast::transport::CastTransportSender::Create(
+ NULL, // net log.
clock.get(),
- config,
+ local_endpoint,
+ remote_endpoint,
base::Bind(&UpdateCastTransportStatus),
- io_message_loop.message_loop_proxy()));
+ io_message_loop.message_loop_proxy());
+
+ transport_sender->InitializeAudio(transport_audio_config);
+ transport_sender->InitializeVideo(transport_video_config);
// Enable main and send side threads only. Enable raw event and stats logging.
// Running transport on the main thread.
diff --git a/media/cast/transport/cast_transport_config.cc b/media/cast/transport/cast_transport_config.cc
index 1ec6be5..cdff2fc 100644
--- a/media/cast/transport/cast_transport_config.cc
+++ b/media/cast/transport/cast_transport_config.cc
@@ -18,17 +18,19 @@ RtpConfig::RtpConfig()
max_delay_ms(kDefaultRtpMaxDelayMs),
payload_type(0) {}
-CastTransportConfig::CastTransportConfig()
- : audio_ssrc(0),
- video_ssrc(0),
- video_codec(kVp8),
- audio_codec(kOpus),
- audio_frequency(0),
- audio_channels(0),
- aes_key(""),
- aes_iv_mask("") {}
-
-CastTransportConfig::~CastTransportConfig() {}
+CastTransportBaseConfig::CastTransportBaseConfig()
+ : ssrc(0) {}
+
+CastTransportBaseConfig::~CastTransportBaseConfig() {}
+
+CastTransportAudioConfig::CastTransportAudioConfig()
+ : codec(kOpus), frequency(0), channels(0) {}
+
+CastTransportAudioConfig::~CastTransportAudioConfig() {}
+
+CastTransportVideoConfig::CastTransportVideoConfig() : codec(kVp8) {}
+
+CastTransportVideoConfig::~CastTransportVideoConfig() {}
EncodedVideoFrame::EncodedVideoFrame()
: codec(kVp8),
@@ -70,8 +72,7 @@ RtcpDlrrReportBlock::RtcpDlrrReportBlock()
RtcpDlrrReportBlock::~RtcpDlrrReportBlock() {}
SendRtcpFromRtpSenderData::SendRtcpFromRtpSenderData()
- : packet_type_flags(0),
- sending_ssrc(0) {}
+ : packet_type_flags(0), sending_ssrc(0) {}
SendRtcpFromRtpSenderData::~SendRtcpFromRtpSenderData() {}
} // namespace transport
diff --git a/media/cast/transport/cast_transport_config.h b/media/cast/transport/cast_transport_config.h
index 90d039c..9191606 100644
--- a/media/cast/transport/cast_transport_config.h
+++ b/media/cast/transport/cast_transport_config.h
@@ -43,29 +43,33 @@ struct RtpConfig {
int payload_type;
};
-struct CastTransportConfig {
- CastTransportConfig();
- ~CastTransportConfig();
+// TODO(mikhal): Consider combining this with the cast_sender config.
+struct CastTransportBaseConfig {
+ CastTransportBaseConfig();
+ ~CastTransportBaseConfig();
- // Transport: Local receiver.
- net::IPEndPoint receiver_endpoint;
- net::IPEndPoint local_endpoint;
-
- uint32 audio_ssrc;
- uint32 video_ssrc;
+ uint32 ssrc;
+ RtpConfig rtp_config;
+ std::string aes_key; // Binary string of size kAesKeySize.
+ std::string aes_iv_mask; // Binary string of size kAesBlockSize.
+};
- VideoCodec video_codec;
- AudioCodec audio_codec;
+struct CastTransportAudioConfig {
+ CastTransportAudioConfig();
+ ~CastTransportAudioConfig();
- // RTP.
- RtpConfig audio_rtp_config;
- RtpConfig video_rtp_config;
+ CastTransportBaseConfig base;
+ AudioCodec codec;
+ int frequency;
+ int channels;
+};
- int audio_frequency;
- int audio_channels;
+struct CastTransportVideoConfig {
+ CastTransportVideoConfig();
+ ~CastTransportVideoConfig();
- std::string aes_key; // Binary string of size kAesKeySize.
- std::string aes_iv_mask; // Binary string of size kAesBlockSize.
+ CastTransportBaseConfig base;
+ VideoCodec codec;
};
struct EncodedVideoFrame {
diff --git a/media/cast/transport/cast_transport_defines.h b/media/cast/transport/cast_transport_defines.h
index 7d8f766..72089fc 100644
--- a/media/cast/transport/cast_transport_defines.h
+++ b/media/cast/transport/cast_transport_defines.h
@@ -18,8 +18,10 @@ namespace transport {
// TODO(mikhal): Implement and add more types.
enum CastTransportStatus {
- TRANSPORT_UNINITIALIZED = 0,
- TRANSPORT_INITIALIZED,
+ TRANSPORT_AUDIO_UNINITIALIZED = 0,
+ TRANSPORT_VIDEO_UNINITIALIZED,
+ TRANSPORT_AUDIO_INITIALIZED,
+ TRANSPORT_VIDEO_INITIALIZED,
TRANSPORT_INVALID_CRYPTO_CONFIG,
TRANSPORT_SOCKET_ERROR,
CAST_TRANSPORT_STATUS_LAST = TRANSPORT_SOCKET_ERROR
diff --git a/media/cast/transport/cast_transport_sender.h b/media/cast/transport/cast_transport_sender.h
index 63f6312..5bfa00e 100644
--- a/media/cast/transport/cast_transport_sender.h
+++ b/media/cast/transport/cast_transport_sender.h
@@ -5,7 +5,6 @@
// This is the main interface for the cast transport sender. The cast sender
// handles the cast pipeline from encoded frames (both audio and video), to
// encryption, packetization and transport.
-// All configurations are done at creation.
// Construction of the Cast Sender and the Cast Transport Sender should be done
// in the following order:
@@ -13,6 +12,8 @@
// 2. Create CastSender (accepts CastTransportSender as an input).
// 3. Call CastTransportSender::SetPacketReceiver to ensure that the packets
// received by the CastTransportSender will be sent to the CastSender.
+// 4. Initialize audio and/or video.
+// Steps 3 & 4 can be done interchangeably.
// Destruction: The CastTransportSender is assumed to be valid as long as the
// CastSender is alive. Therefore the CastSender should be destructed before the
@@ -39,6 +40,8 @@ namespace media {
namespace cast {
namespace transport {
+// Following the initialization of either audio or video an initialization
+// status will be sent via this callback.
typedef base::Callback<void(CastTransportStatus status)>
CastTransportStatusCallback;
@@ -49,15 +52,23 @@ typedef base::Callback<void(const RtcpSenderInfo& sender_info,
// The application should only trigger this class from the transport thread.
class CastTransportSender : public base::NonThreadSafe {
public:
- static CastTransportSender* CreateCastTransportSender(
+ static scoped_ptr<CastTransportSender> Create(
net::NetLog* net_log,
base::TickClock* clock,
- const CastTransportConfig& config,
+ const net::IPEndPoint& local_end_point,
+ const net::IPEndPoint& remote_end_point,
const CastTransportStatusCallback& status_callback,
const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner);
virtual ~CastTransportSender() {}
+ // Audio/Video initialization.
+ // Encoded frames cannot be transmitted until the relevant initialize method
+ // is called.
+ virtual void InitializeAudio(const CastTransportAudioConfig& config) = 0;
+
+ virtual void InitializeVideo(const CastTransportVideoConfig& config) = 0;
+
// Sets the Cast packet receiver. Should be called after creation on the
// Cast sender. Packets won't be received until this function is called.
virtual void SetPacketReceiver(
@@ -85,9 +96,9 @@ class CastTransportSender : public base::NonThreadSafe {
bool is_audio,
const MissingFramesAndPacketsMap& missing_packets) = 0;
- // Audio/Video RTP statistics.
// RTP statistics will be returned on a regular interval on the designated
// callback.
+ // Must be called after initialization of the corresponding A/V pipeline.
virtual void SubscribeAudioRtpStatsCallback(
const CastTransportRtpStatistics& callback) = 0;
diff --git a/media/cast/transport/cast_transport_sender_impl.cc b/media/cast/transport/cast_transport_sender_impl.cc
index d8f0de2..9975e3a 100644
--- a/media/cast/transport/cast_transport_sender_impl.cc
+++ b/media/cast/transport/cast_transport_sender_impl.cc
@@ -12,48 +12,67 @@ namespace media {
namespace cast {
namespace transport {
-CastTransportSender* CastTransportSender::CreateCastTransportSender(
+scoped_ptr<CastTransportSender> CastTransportSender::Create(
net::NetLog* net_log,
base::TickClock* clock,
- const CastTransportConfig& config,
+ const net::IPEndPoint& local_end_point,
+ const net::IPEndPoint& remote_end_point,
const CastTransportStatusCallback& status_callback,
const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) {
- return new CastTransportSenderImpl(net_log,
- clock,
- config,
- status_callback,
- transport_task_runner.get(),
- NULL);
+ return scoped_ptr<CastTransportSender>(
+ new CastTransportSenderImpl(net_log,
+ clock,
+ local_end_point,
+ remote_end_point,
+ status_callback,
+ transport_task_runner.get(),
+ NULL));
}
CastTransportSenderImpl::CastTransportSenderImpl(
net::NetLog* net_log,
base::TickClock* clock,
- const CastTransportConfig& config,
+ const net::IPEndPoint& local_end_point,
+ const net::IPEndPoint& remote_end_point,
const CastTransportStatusCallback& status_callback,
const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
PacketSender* external_transport)
- : transport_(external_transport ? NULL
+ : clock_(clock),
+ status_callback_(status_callback),
+ transport_task_runner_(transport_task_runner),
+ transport_(external_transport ? NULL
: new UdpTransport(net_log,
transport_task_runner,
- config.local_endpoint,
- config.receiver_endpoint,
+ local_end_point,
+ remote_end_point,
status_callback)),
pacer_(clock,
external_transport ? external_transport : transport_.get(),
transport_task_runner),
- rtcp_builder_(&pacer_),
- audio_sender_(config, clock, transport_task_runner, &pacer_),
- video_sender_(config, clock, transport_task_runner, &pacer_) {
- if (audio_sender_.initialized() && video_sender_.initialized()) {
- status_callback.Run(TRANSPORT_INITIALIZED);
- } else {
- status_callback.Run(TRANSPORT_UNINITIALIZED);
- }
-}
+ rtcp_builder_(&pacer_) {}
CastTransportSenderImpl::~CastTransportSenderImpl() {}
+void CastTransportSenderImpl::InitializeAudio(
+ const CastTransportAudioConfig& config) {
+ audio_sender_.reset(new TransportAudioSender(
+ config, clock_, transport_task_runner_, &pacer_));
+ if (audio_sender_->initialized())
+ status_callback_.Run(TRANSPORT_AUDIO_INITIALIZED);
+ else
+ status_callback_.Run(TRANSPORT_AUDIO_UNINITIALIZED);
+}
+
+void CastTransportSenderImpl::InitializeVideo(
+ const CastTransportVideoConfig& config) {
+ video_sender_.reset(new TransportVideoSender(
+ config, clock_, transport_task_runner_, &pacer_));
+ if (video_sender_->initialized())
+ status_callback_.Run(TRANSPORT_VIDEO_INITIALIZED);
+ else
+ status_callback_.Run(TRANSPORT_VIDEO_UNINITIALIZED);
+}
+
void CastTransportSenderImpl::SetPacketReceiver(
const PacketReceiverCallback& packet_receiver) {
transport_->StartReceiving(packet_receiver);
@@ -62,13 +81,15 @@ void CastTransportSenderImpl::SetPacketReceiver(
void CastTransportSenderImpl::InsertCodedAudioFrame(
const EncodedAudioFrame* audio_frame,
const base::TimeTicks& recorded_time) {
- audio_sender_.InsertCodedAudioFrame(audio_frame, recorded_time);
+ DCHECK(audio_sender_) << "Audio sender uninitialized";
+ audio_sender_->InsertCodedAudioFrame(audio_frame, recorded_time);
}
void CastTransportSenderImpl::InsertCodedVideoFrame(
const EncodedVideoFrame* video_frame,
const base::TimeTicks& capture_time) {
- video_sender_.InsertCodedVideoFrame(video_frame, capture_time);
+ DCHECK(video_sender_) << "Video sender uninitialized";
+ video_sender_->InsertCodedVideoFrame(video_frame, capture_time);
}
void CastTransportSenderImpl::SendRtcpFromRtpSender(
@@ -86,20 +107,24 @@ void CastTransportSenderImpl::ResendPackets(
bool is_audio,
const MissingFramesAndPacketsMap& missing_packets) {
if (is_audio) {
- audio_sender_.ResendPackets(missing_packets);
+ DCHECK(audio_sender_) << "Audio sender uninitialized";
+ audio_sender_->ResendPackets(missing_packets);
} else {
- video_sender_.ResendPackets(missing_packets);
+ DCHECK(video_sender_) << "Video sender uninitialized";
+ video_sender_->ResendPackets(missing_packets);
}
}
void CastTransportSenderImpl::SubscribeAudioRtpStatsCallback(
const CastTransportRtpStatistics& callback) {
- audio_sender_.SubscribeAudioRtpStatsCallback(callback);
+ DCHECK(audio_sender_) << "Audio sender uninitialized";
+ audio_sender_->SubscribeAudioRtpStatsCallback(callback);
}
void CastTransportSenderImpl::SubscribeVideoRtpStatsCallback(
const CastTransportRtpStatistics& callback) {
- video_sender_.SubscribeVideoRtpStatsCallback(callback);
+ DCHECK(video_sender_) << "Audio sender uninitialized";
+ video_sender_->SubscribeVideoRtpStatsCallback(callback);
}
} // namespace transport
diff --git a/media/cast/transport/cast_transport_sender_impl.h b/media/cast/transport/cast_transport_sender_impl.h
index d1f7d9a..b7ee50a 100644
--- a/media/cast/transport/cast_transport_sender_impl.h
+++ b/media/cast/transport/cast_transport_sender_impl.h
@@ -29,13 +29,18 @@ class CastTransportSenderImpl : public CastTransportSender {
CastTransportSenderImpl(
net::NetLog* net_log,
base::TickClock* clock,
- const CastTransportConfig& config,
+ const net::IPEndPoint& local_end_point,
+ const net::IPEndPoint& remote_end_point,
const CastTransportStatusCallback& status_callback,
const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
PacketSender* external_transport);
virtual ~CastTransportSenderImpl();
+ virtual void InitializeAudio(const CastTransportAudioConfig& config) OVERRIDE;
+
+ virtual void InitializeVideo(const CastTransportVideoConfig& config) OVERRIDE;
+
// CastTransportSender implementation.
virtual void SetPacketReceiver(const PacketReceiverCallback& packet_receiver)
OVERRIDE;
@@ -66,11 +71,14 @@ class CastTransportSenderImpl : public CastTransportSender {
const CastTransportRtpStatistics& callback) OVERRIDE;
private:
+ base::TickClock* clock_; // Not owned by this class.
+ CastTransportStatusCallback status_callback_;
+ scoped_refptr<base::SingleThreadTaskRunner> transport_task_runner_;
scoped_ptr<UdpTransport> transport_;
PacedSender pacer_;
RtcpBuilder rtcp_builder_;
- TransportAudioSender audio_sender_;
- TransportVideoSender video_sender_;
+ scoped_ptr<TransportAudioSender> audio_sender_;
+ scoped_ptr<TransportVideoSender> video_sender_;
DISALLOW_COPY_AND_ASSIGN(CastTransportSenderImpl);
};
diff --git a/media/cast/transport/pacing/paced_sender.h b/media/cast/transport/pacing/paced_sender.h
index 80e2b3f..69a6079 100644
--- a/media/cast/transport/pacing/paced_sender.h
+++ b/media/cast/transport/pacing/paced_sender.h
@@ -76,7 +76,7 @@ class PacedSender : public PacedPacketSender,
// Not owned by this class.
base::TickClock* const clock_;
PacketSender* transport_; // Not owned by this class.
- scoped_refptr<base::TaskRunner> transport_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> transport_task_runner_;
size_t burst_size_;
size_t packets_sent_in_burst_;
base::TimeTicks time_last_process_;
diff --git a/media/cast/transport/rtp_sender/rtp_sender.cc b/media/cast/transport/rtp_sender/rtp_sender.cc
index 91122de..b08c541 100644
--- a/media/cast/transport/rtp_sender/rtp_sender.cc
+++ b/media/cast/transport/rtp_sender/rtp_sender.cc
@@ -20,53 +20,55 @@ static const int kStatsCallbackIntervalMs = 33;
RtpSender::RtpSender(
base::TickClock* clock,
- const CastTransportConfig& config,
- bool is_audio,
- const scoped_refptr<base::TaskRunner>& transport_task_runner,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
PacedSender* const transport)
- : config_(),
+ : clock_(clock),
transport_(transport),
stats_callback_(),
- transport_task_runner_(transport_task_runner) {
- // Store generic cast config and create packetizer config.
- if (is_audio) {
- storage_.reset(
- new PacketStorage(clock, config.audio_rtp_config.history_ms));
- config_.audio = true;
- config_.ssrc = config.audio_ssrc;
- config_.payload_type = config.audio_rtp_config.payload_type;
- config_.frequency = config.audio_frequency;
- config_.audio_codec = config.audio_codec;
- } else {
- storage_.reset(
- new PacketStorage(clock, config.audio_rtp_config.history_ms));
- config_.audio = false;
- config_.ssrc = config.video_ssrc;
- config_.payload_type = config.video_rtp_config.payload_type;
- config_.frequency = kVideoFrequency;
- config_.video_codec = config.video_codec;
- }
- // Randomly set start values.
+ transport_task_runner_(transport_task_runner),
+ weak_factory_(this) {
+ // Randomly set sequence number start value.
config_.sequence_number = base::RandInt(0, 65535);
- packetizer_.reset(
- new RtpPacketizer(transport, storage_.get(), config_));
}
RtpSender::~RtpSender() {}
+void RtpSender::InitializeAudio(const CastTransportAudioConfig& config) {
+ storage_.reset(new PacketStorage(clock_, config.base.rtp_config.history_ms));
+ config_.audio = true;
+ config_.ssrc = config.base.ssrc;
+ config_.payload_type = config.base.rtp_config.payload_type;
+ config_.frequency = config.frequency;
+ config_.audio_codec = config.codec;
+ packetizer_.reset(new RtpPacketizer(transport_, storage_.get(), config_));
+}
+
+void RtpSender::InitializeVideo(const CastTransportVideoConfig& config) {
+ storage_.reset(new PacketStorage(clock_, config.base.rtp_config.history_ms));
+ config_.audio = false;
+ config_.ssrc = config.base.ssrc;
+ config_.payload_type = config.base.rtp_config.payload_type;
+ config_.frequency = kVideoFrequency;
+ config_.video_codec = config.codec;
+ packetizer_.reset(new RtpPacketizer(transport_, storage_.get(), config_));
+}
+
void RtpSender::IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame,
const base::TimeTicks& capture_time) {
+ DCHECK(packetizer_);
packetizer_->IncomingEncodedVideoFrame(video_frame, capture_time);
}
void RtpSender::IncomingEncodedAudioFrame(
const EncodedAudioFrame* audio_frame,
const base::TimeTicks& recorded_time) {
+ DCHECK(packetizer_);
packetizer_->IncomingEncodedAudioFrame(audio_frame, recorded_time);
}
void RtpSender::ResendPackets(
const MissingFramesAndPacketsMap& missing_frames_and_packets) {
+ DCHECK(storage_);
// Iterate over all frames in the list.
for (MissingFramesAndPacketsMap::const_iterator it =
missing_frames_and_packets.begin();
@@ -133,7 +135,7 @@ void RtpSender::SubscribeRtpStatsCallback(
void RtpSender::ScheduleNextStatsReport() {
transport_task_runner_->PostDelayedTask(
FROM_HERE,
- base::Bind(&RtpSender::RtpStatistics, base::AsWeakPtr(this)),
+ base::Bind(&RtpSender::RtpStatistics, weak_factory_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kStatsCallbackIntervalMs));
}
diff --git a/media/cast/transport/rtp_sender/rtp_sender.h b/media/cast/transport/rtp_sender/rtp_sender.h
index 4fc4957..eea95d3 100644
--- a/media/cast/transport/rtp_sender/rtp_sender.h
+++ b/media/cast/transport/rtp_sender/rtp_sender.h
@@ -30,16 +30,23 @@ namespace transport {
// This class handles splitting encoded audio and video frames into packets and
// add an RTP header to each packet. The sent packets are stored until they are
// acknowledged by the remote peer or timed out.
-class RtpSender : public base::SupportsWeakPtr<RtpSender>{
+class RtpSender {
public:
- RtpSender(base::TickClock* clock,
- const CastTransportConfig& config,
- bool is_audio,
- const scoped_refptr<base::TaskRunner>& transport_task_runner,
- PacedSender* const transport);
+ RtpSender(
+ base::TickClock* clock,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
+ PacedSender* const transport);
~RtpSender();
+ // Initialize audio stack. Audio must be initialized prior to sending encoded
+ // audio frames.
+ void InitializeAudio(const CastTransportAudioConfig& config);
+
+ // Initialize video stack. Video must be initialized prior to sending encoded
+ // video frames.
+ void InitializeVideo(const CastTransportVideoConfig& config);
+
// The video_frame objects ownership is handled by the main cast thread.
void IncomingEncodedVideoFrame(const EncodedVideoFrame* video_frame,
const base::TimeTicks& capture_time);
@@ -60,12 +67,15 @@ class RtpSender : public base::SupportsWeakPtr<RtpSender>{
void RtpStatistics();
void UpdateSequenceNumber(Packet* packet);
+ base::TickClock* clock_; // Not owned by this class.
RtpPacketizerConfig config_;
scoped_ptr<RtpPacketizer> packetizer_;
scoped_ptr<PacketStorage> storage_;
PacedSender* const transport_;
CastTransportRtpStatistics stats_callback_;
- scoped_refptr<base::TaskRunner> transport_task_runner_;
+ scoped_refptr<base::SingleThreadTaskRunner> transport_task_runner_;
+
+ base::WeakPtrFactory<RtpSender> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(RtpSender);
};
diff --git a/media/cast/transport/transport_audio_sender.cc b/media/cast/transport/transport_audio_sender.cc
index 818f9b1..b704e23 100644
--- a/media/cast/transport/transport_audio_sender.cc
+++ b/media/cast/transport/transport_audio_sender.cc
@@ -14,17 +14,15 @@ namespace cast {
namespace transport {
TransportAudioSender::TransportAudioSender(
- const CastTransportConfig& config,
+ const CastTransportAudioConfig& config,
base::TickClock* clock,
- const scoped_refptr<base::TaskRunner>& transport_task_runner,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
PacedSender* const paced_packet_sender)
- : rtp_sender_(clock,
- config,
- true,
- transport_task_runner,
- paced_packet_sender),
+ : rtp_sender_(clock, transport_task_runner, paced_packet_sender),
encryptor_() {
- initialized_ = encryptor_.Initialize(config.aes_key, config.aes_iv_mask);
+ rtp_sender_.InitializeAudio(config);
+ initialized_ =
+ encryptor_.Initialize(config.base.aes_key, config.base.aes_iv_mask);
}
TransportAudioSender::~TransportAudioSender() {}
@@ -47,7 +45,7 @@ bool TransportAudioSender::EncryptAudioFrame(
const EncodedAudioFrame& audio_frame,
EncodedAudioFrame* encrypted_frame) {
if (!encryptor_.Encrypt(
- audio_frame.frame_id, audio_frame.data, &encrypted_frame->data))
+ audio_frame.frame_id, audio_frame.data, &encrypted_frame->data))
return false;
encrypted_frame->codec = audio_frame.codec;
diff --git a/media/cast/transport/transport_audio_sender.h b/media/cast/transport/transport_audio_sender.h
index c988714..4be74a9 100644
--- a/media/cast/transport/transport_audio_sender.h
+++ b/media/cast/transport/transport_audio_sender.h
@@ -22,9 +22,9 @@ class PacedSender;
class TransportAudioSender : public base::NonThreadSafe {
public:
TransportAudioSender(
- const CastTransportConfig& config,
+ const CastTransportAudioConfig& config,
base::TickClock* clock,
- const scoped_refptr<base::TaskRunner>& transport_task_runner,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
PacedSender* const paced_packet_sender);
virtual ~TransportAudioSender();
diff --git a/media/cast/transport/transport_video_sender.cc b/media/cast/transport/transport_video_sender.cc
index 060184f..1862458 100644
--- a/media/cast/transport/transport_video_sender.cc
+++ b/media/cast/transport/transport_video_sender.cc
@@ -17,19 +17,17 @@ namespace cast {
namespace transport {
TransportVideoSender::TransportVideoSender(
- const CastTransportConfig& config,
+ const CastTransportVideoConfig& config,
base::TickClock* clock,
- const scoped_refptr<base::TaskRunner>& transport_task_runner,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
PacedSender* const paced_packet_sender)
: rtp_max_delay_(base::TimeDelta::FromMilliseconds(
- config.video_rtp_config.max_delay_ms)),
+ config.base.rtp_config.max_delay_ms)),
encryptor_(),
- rtp_sender_(clock,
- config,
- false,
- transport_task_runner,
- paced_packet_sender) {
- initialized_ = encryptor_.Initialize(config.aes_key, config.aes_iv_mask);
+ rtp_sender_(clock, transport_task_runner, paced_packet_sender) {
+ rtp_sender_.InitializeVideo(config);
+ initialized_ =
+ encryptor_.Initialize(config.base.aes_key, config.base.aes_iv_mask);
}
TransportVideoSender::~TransportVideoSender() {}
@@ -57,7 +55,7 @@ bool TransportVideoSender::EncryptVideoFrame(
const EncodedVideoFrame& video_frame,
EncodedVideoFrame* encrypted_frame) {
if (!encryptor_.Encrypt(
- video_frame.frame_id, video_frame.data, &(encrypted_frame->data)))
+ video_frame.frame_id, video_frame.data, &(encrypted_frame->data)))
return false;
encrypted_frame->codec = video_frame.codec;
diff --git a/media/cast/transport/transport_video_sender.h b/media/cast/transport/transport_video_sender.h
index 2de67f1..3ed293a 100644
--- a/media/cast/transport/transport_video_sender.h
+++ b/media/cast/transport/transport_video_sender.h
@@ -19,7 +19,6 @@ class VideoFrame;
namespace cast {
namespace transport {
-
class PacedSender;
// Not thread safe. Only called from the main cast transport thread.
@@ -28,9 +27,9 @@ class PacedSender;
class TransportVideoSender : public base::NonThreadSafe {
public:
TransportVideoSender(
- const CastTransportConfig& config,
+ const CastTransportVideoConfig& config,
base::TickClock* clock,
- const scoped_refptr<base::TaskRunner>& transport_task_runner,
+ const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner,
PacedSender* const paced_packet_sender);
virtual ~TransportVideoSender();
diff --git a/media/cast/video_sender/video_sender_unittest.cc b/media/cast/video_sender/video_sender_unittest.cc
index 2f5c06e..130dac9 100644
--- a/media/cast/video_sender/video_sender_unittest.cc
+++ b/media/cast/video_sender/video_sender_unittest.cc
@@ -90,14 +90,17 @@ class VideoSenderTest : public ::testing::Test {
task_runner_,
task_runner_,
GetLoggingConfigWithRawEventsAndStatsEnabled());
- transport::CastTransportConfig transport_config;
+ transport::CastTransportVideoConfig transport_config;
+ net::IPEndPoint dummy_endpoint;
transport_sender_.reset(new transport::CastTransportSenderImpl(
NULL,
testing_clock_,
- transport_config,
+ dummy_endpoint,
+ dummy_endpoint,
base::Bind(&UpdateCastTransportStatus),
task_runner_,
&transport_));
+ transport_sender_->InitializeVideo(transport_config);
}
virtual ~VideoSenderTest() {}
@@ -108,7 +111,7 @@ class VideoSenderTest : public ::testing::Test {
}
static void UpdateCastTransportStatus(transport::CastTransportStatus status) {
- EXPECT_EQ(status, transport::TRANSPORT_INITIALIZED);
+ EXPECT_EQ(status, transport::TRANSPORT_VIDEO_INITIALIZED);
}
void InitEncoder(bool external) {