OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/media/cast_session_delegate.h" | 5 #include "chrome/renderer/media/cast_session_delegate.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.h" |
9 #include "chrome/renderer/media/cast_transport_sender_ipc.h" | |
9 #include "content/public/renderer/p2p_socket_client.h" | 10 #include "content/public/renderer/p2p_socket_client.h" |
10 #include "content/public/renderer/render_thread.h" | 11 #include "content/public/renderer/render_thread.h" |
11 #include "media/cast/cast_config.h" | 12 #include "media/cast/cast_config.h" |
12 #include "media/cast/cast_environment.h" | 13 #include "media/cast/cast_environment.h" |
13 #include "media/cast/cast_sender.h" | 14 #include "media/cast/cast_sender.h" |
14 #include "media/cast/logging/logging_defines.h" | 15 #include "media/cast/logging/logging_defines.h" |
15 #include "media/cast/transport/cast_transport_config.h" | 16 #include "media/cast/transport/cast_transport_config.h" |
16 #include "media/cast/transport/cast_transport_sender.h" | 17 #include "media/cast/transport/cast_transport_sender.h" |
17 | 18 |
18 using media::cast::AudioSenderConfig; | 19 using media::cast::AudioSenderConfig; |
19 using media::cast::CastEnvironment; | 20 using media::cast::CastEnvironment; |
20 using media::cast::CastSender; | 21 using media::cast::CastSender; |
21 using media::cast::VideoSenderConfig; | 22 using media::cast::VideoSenderConfig; |
22 | 23 |
23 namespace { | |
24 | |
25 // This is a dummy class that does nothing. This is needed temporarily | |
26 // to enable tests for cast.streaming extension APIs. | |
27 // The real implementation of CastTransportSender is to use IPC to send | |
28 // data to the browser process. | |
29 // See crbug.com/327482 for more details. | |
30 class DummyTransport : public media::cast::transport::CastTransportSender { | |
31 public: | |
32 DummyTransport() {} | |
33 virtual ~DummyTransport() {} | |
34 | |
35 // CastTransportSender implementations. | |
36 virtual void SetPacketReceiver( | |
37 const media::cast::transport::PacketReceiverCallback& packet_receiver) | |
38 OVERRIDE {} | |
39 virtual void InsertCodedAudioFrame( | |
40 const media::cast::transport::EncodedAudioFrame* audio_frame, | |
41 const base::TimeTicks& recorded_time) OVERRIDE {} | |
42 virtual void InsertCodedVideoFrame( | |
43 const media::cast::transport::EncodedVideoFrame* video_frame, | |
44 const base::TimeTicks& capture_time) OVERRIDE {} | |
45 virtual void SendRtcpFromRtpSender( | |
46 uint32 packet_type_flags, | |
47 const media::cast::transport::RtcpSenderInfo& sender_info, | |
48 const media::cast::transport::RtcpDlrrReportBlock& dlrr, | |
49 const media::cast::transport::RtcpSenderLogMessage& sender_log, | |
50 uint32 sending_ssrc, | |
51 const std::string& c_name) OVERRIDE {} | |
52 virtual void ResendPackets( | |
53 bool is_audio, | |
54 const media::cast::transport::MissingFramesAndPacketsMap& missing_packets) | |
55 OVERRIDE {} | |
56 virtual void RtpAudioStatistics( | |
57 const base::TimeTicks& now, | |
58 media::cast::transport::RtcpSenderInfo* sender_info) OVERRIDE {} | |
59 virtual void RtpVideoStatistics( | |
60 const base::TimeTicks& now, | |
61 media::cast::transport::RtcpSenderInfo* sender_info) OVERRIDE {} | |
62 | |
63 private: | |
64 DISALLOW_COPY_AND_ASSIGN(DummyTransport); | |
65 }; | |
66 | |
67 } // namespace | |
68 | |
69 CastSessionDelegate::CastSessionDelegate() | 24 CastSessionDelegate::CastSessionDelegate() |
70 : audio_encode_thread_("CastAudioEncodeThread"), | 25 : audio_encode_thread_("CastAudioEncodeThread"), |
71 video_encode_thread_("CastVideoEncodeThread"), | 26 video_encode_thread_("CastVideoEncodeThread"), |
72 audio_configured_(false), | 27 audio_configured_(false), |
73 video_configured_(false), | 28 video_configured_(false), |
29 transport_configured_(false), | |
74 io_message_loop_proxy_( | 30 io_message_loop_proxy_( |
75 content::RenderThread::Get()->GetIOMessageLoopProxy()) { | 31 content::RenderThread::Get()->GetIOMessageLoopProxy()) { |
32 DCHECK(io_message_loop_proxy_.get()); | |
76 } | 33 } |
77 | 34 |
78 CastSessionDelegate::~CastSessionDelegate() { | 35 CastSessionDelegate::~CastSessionDelegate() { |
79 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 36 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
80 } | 37 } |
81 | 38 |
82 void CastSessionDelegate::StartAudio( | 39 void CastSessionDelegate::StartAudio( |
83 const AudioSenderConfig& config, | 40 const AudioSenderConfig& config, |
84 const FrameInputAvailableCallback& callback) { | 41 const FrameInputAvailableCallback& callback) { |
85 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 42 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
86 | 43 |
87 audio_configured_ = true; | 44 audio_configured_ = true; |
88 audio_config_ = config; | 45 audio_config_ = config; |
89 frame_input_available_callbacks_.push_back(callback); | 46 frame_input_available_callbacks_.push_back(callback); |
90 StartSendingInternal(); | 47 StartSendingInternal(); |
91 } | 48 } |
92 | 49 |
93 void CastSessionDelegate::StartVideo( | 50 void CastSessionDelegate::StartVideo( |
94 const VideoSenderConfig& config, | 51 const VideoSenderConfig& config, |
95 const FrameInputAvailableCallback& callback) { | 52 const FrameInputAvailableCallback& callback) { |
96 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 53 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
97 | 54 |
98 video_configured_ = true; | 55 video_configured_ = true; |
99 video_config_ = config; | 56 video_config_ = config; |
100 frame_input_available_callbacks_.push_back(callback); | 57 frame_input_available_callbacks_.push_back(callback); |
101 StartSendingInternal(); | 58 StartSendingInternal(); |
102 } | 59 } |
103 | 60 |
61 void CastSessionDelegate::StartUDP( | |
62 const net::IPEndPoint& local_endpoint, | |
63 const net::IPEndPoint& remote_endpoint) { | |
64 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | |
65 transport_configured_ = true; | |
66 local_endpoint_ = local_endpoint; | |
67 remote_endpoint_ = remote_endpoint; | |
68 StartSendingInternal(); | |
69 } | |
70 | |
71 static void IgnoreStatusCB( | |
72 media::cast::transport::CastTransportStatus unused_status) { | |
73 } | |
74 | |
104 // TODO(pwestin): This design does not work; as soon as audio or video is | 75 // TODO(pwestin): This design does not work; as soon as audio or video is |
105 // initialized it will prevent the other from being enabled. | 76 // initialized it will prevent the other from being enabled. |
106 void CastSessionDelegate::StartSendingInternal() { | 77 void CastSessionDelegate::StartSendingInternal() { |
107 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 78 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
108 | 79 |
109 if (cast_environment_) | 80 if (cast_environment_) |
110 return; | 81 return; |
111 | 82 |
112 if (!audio_configured_ || !video_configured_) | 83 if (!audio_configured_ || !video_configured_ || !transport_configured_) |
mikhal1
2014/02/05 21:09:43
We must have the transport configured to be able t
hubbe
2014/02/05 21:14:54
Until Patrik's changes are checked in, the code on
| |
113 return; | 84 return; |
114 | 85 |
115 cast_transport_.reset(new DummyTransport()); | 86 media::cast::transport::CastTransportConfig config; |
87 | |
88 // TODO(hubbe): receiver_endpoint, local_endpoint | |
89 config.local_endpoint = local_endpoint_; | |
90 config.receiver_endpoint = remote_endpoint_; | |
91 config.audio_ssrc = audio_config_.sender_ssrc; | |
92 config.video_ssrc = video_config_.sender_ssrc; | |
93 config.audio_codec = audio_config_.codec; | |
94 config.video_codec = video_config_.codec; | |
95 config.audio_rtp_config = audio_config_.rtp_config; | |
96 config.video_rtp_config = video_config_.rtp_config; | |
97 config.audio_frequency = audio_config_.frequency; | |
98 config.audio_channels = audio_config_.channels; | |
99 // TODO(Hubbe): aes_key, aes_iv_mask | |
100 | |
101 cast_transport_.reset(new cast::CastTransportSenderIPC( | |
102 config, | |
103 base::Bind(&IgnoreStatusCB))); | |
116 audio_encode_thread_.Start(); | 104 audio_encode_thread_.Start(); |
117 video_encode_thread_.Start(); | 105 video_encode_thread_.Start(); |
118 | 106 |
119 // CastSender uses the renderer's IO thread as the main thread. This reduces | 107 // CastSender uses the renderer's IO thread as the main thread. This reduces |
120 // thread hopping for incoming video frames and outgoing network packets. | 108 // thread hopping for incoming video frames and outgoing network packets. |
121 // There's no need to decode so no thread assigned for decoding. | 109 // There's no need to decode so no thread assigned for decoding. |
122 // Get default logging: All disabled. | 110 // Get default logging: All disabled. |
123 cast_environment_ = new CastEnvironment( | 111 cast_environment_ = new CastEnvironment( |
124 scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(), | 112 scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(), |
125 base::MessageLoopProxy::current(), | 113 base::MessageLoopProxy::current(), |
126 audio_encode_thread_.message_loop_proxy(), | 114 audio_encode_thread_.message_loop_proxy(), |
127 NULL, | 115 NULL, |
128 video_encode_thread_.message_loop_proxy(), | 116 video_encode_thread_.message_loop_proxy(), |
129 NULL, | 117 NULL, |
130 base::MessageLoopProxy::current(), | 118 base::MessageLoopProxy::current(), |
131 media::cast::GetDefaultCastSenderLoggingConfig()); | 119 media::cast::GetDefaultCastSenderLoggingConfig()); |
132 | 120 |
133 cast_sender_.reset(CastSender::CreateCastSender( | 121 cast_sender_.reset(CastSender::CreateCastSender( |
134 cast_environment_, | 122 cast_environment_, |
135 audio_config_, | 123 audio_config_, |
136 video_config_, | 124 video_config_, |
137 NULL, // GPU. | 125 NULL, // GPU. |
138 base::Bind(&CastSessionDelegate::InitializationResult, | 126 base::Bind(&CastSessionDelegate::InitializationResult, |
139 base::Unretained(this)), | 127 base::Unretained(this)), |
140 cast_transport_.get())); | 128 cast_transport_.get())); |
129 cast_transport_->SetPacketReceiver(cast_sender_->packet_receiver()); | |
141 } | 130 } |
142 | 131 |
143 void CastSessionDelegate::InitializationResult( | 132 void CastSessionDelegate::InitializationResult( |
144 media::cast::CastInitializationStatus result) { | 133 media::cast::CastInitializationStatus result) { |
145 DCHECK(cast_sender_); | 134 DCHECK(cast_sender_); |
146 | 135 |
147 // TODO(pwestin): handle the error codes. | 136 // TODO(pwestin): handle the error codes. |
148 | 137 |
149 for (size_t i = 0; i < frame_input_available_callbacks_.size(); ++i) { | 138 for (size_t i = 0; i < frame_input_available_callbacks_.size(); ++i) { |
150 frame_input_available_callbacks_[i].Run( | 139 frame_input_available_callbacks_[i].Run( |
151 cast_sender_->frame_input()); | 140 cast_sender_->frame_input()); |
152 } | 141 } |
153 frame_input_available_callbacks_.clear(); | 142 frame_input_available_callbacks_.clear(); |
154 } | 143 } |
OLD | NEW |