Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(364)

Side by Side Diff: chrome/renderer/media/cast_session_delegate.cc

Issue 163553006: Cast: Refactoring Cast API's (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/media/cast_session_delegate.h ('k') | media/cast/audio_sender/audio_encoder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop_proxy.h" 9 #include "base/message_loop/message_loop_proxy.h"
10 #include "chrome/renderer/media/cast_threads.h" 10 #include "chrome/renderer/media/cast_threads.h"
(...skipping 25 matching lines...) Expand all
36 // each frame will take up to 150 bytes. 36 // each frame will take up to 150 bytes.
37 const int kMaxVideoEventEntries = kMaxSerializedBytes / 150; 37 const int kMaxVideoEventEntries = kMaxSerializedBytes / 150;
38 38
39 // Allow about 9MB for audio event logs. Assume serialized log data for 39 // Allow about 9MB for audio event logs. Assume serialized log data for
40 // each frame will take up to 75 bytes. 40 // each frame will take up to 75 bytes.
41 const int kMaxAudioEventEntries = kMaxSerializedBytes / 75; 41 const int kMaxAudioEventEntries = kMaxSerializedBytes / 75;
42 42
43 } // namespace 43 } // namespace
44 44
45 CastSessionDelegate::CastSessionDelegate() 45 CastSessionDelegate::CastSessionDelegate()
46 : transport_configured_(false), 46 : io_message_loop_proxy_(
47 io_message_loop_proxy_(
48 content::RenderThread::Get()->GetIOMessageLoopProxy()), 47 content::RenderThread::Get()->GetIOMessageLoopProxy()),
49 weak_factory_(this) { 48 weak_factory_(this) {
50 DCHECK(io_message_loop_proxy_); 49 DCHECK(io_message_loop_proxy_);
51 } 50 }
52 51
53 CastSessionDelegate::~CastSessionDelegate() { 52 CastSessionDelegate::~CastSessionDelegate() {
54 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 53 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
55 54
56 if (audio_event_subscriber_.get()) { 55 if (audio_event_subscriber_.get()) {
57 cast_environment_->Logging()->RemoveRawEventSubscriber( 56 cast_environment_->Logging()->RemoveRawEventSubscriber(
58 audio_event_subscriber_.get()); 57 audio_event_subscriber_.get());
59 } 58 }
60 if (video_event_subscriber_.get()) { 59 if (video_event_subscriber_.get()) {
61 cast_environment_->Logging()->RemoveRawEventSubscriber( 60 cast_environment_->Logging()->RemoveRawEventSubscriber(
62 video_event_subscriber_.get()); 61 video_event_subscriber_.get());
63 } 62 }
64 } 63 }
65 64
66 void CastSessionDelegate::Initialize( 65 void CastSessionDelegate::StartAudio(
67 const media::cast::CastLoggingConfig& logging_config) { 66 const AudioSenderConfig& config,
68 if (cast_environment_) 67 const AudioFrameInputAvailableCallback& callback) {
69 return; // Already initialized. 68 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
69
70 audio_frame_input_available_callback_ = callback;
71 media::cast::transport::CastTransportAudioConfig transport_config;
72 transport_config.base.ssrc = config.sender_ssrc;
73 transport_config.codec = config.codec;
74 transport_config.base.rtp_config = config.rtp_config;
75 transport_config.frequency = config.frequency;
76 transport_config.channels = config.channels;
77 cast_transport_->InitializeAudio(transport_config);
78 cast_sender_->InitializeAudio(
79 config,
80 base::Bind(&CastSessionDelegate::InitializationResult,
81 weak_factory_.GetWeakPtr()));
82 }
83
84 void CastSessionDelegate::StartVideo(
85 const VideoSenderConfig& config,
86 const VideoFrameInputAvailableCallback& callback) {
87 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
88 video_frame_input_available_callback_ = callback;
89
90 media::cast::transport::CastTransportVideoConfig transport_config;
91 transport_config.base.ssrc = config.sender_ssrc;
92 transport_config.codec = config.codec;
93 transport_config.base.rtp_config = config.rtp_config;
94 cast_transport_->InitializeVideo(transport_config);
95 // TODO(mikhal): Pass in a valid GpuVideoAcceleratorFactories to support
96 // hardware video encoding.
97 cast_sender_->InitializeVideo(
98 config,
99 base::Bind(&CastSessionDelegate::InitializationResult,
100 weak_factory_.GetWeakPtr()),
101 NULL /* GPU*/);
102 }
103
104 void CastSessionDelegate::StartUDP(const net::IPEndPoint& local_endpoint,
105 const net::IPEndPoint& remote_endpoint) {
106 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
70 107
71 // CastSender uses the renderer's IO thread as the main thread. This reduces 108 // CastSender uses the renderer's IO thread as the main thread. This reduces
72 // thread hopping for incoming video frames and outgoing network packets. 109 // thread hopping for incoming video frames and outgoing network packets.
73 // There's no need to decode so no thread assigned for decoding. 110 // There's no need to decode so no thread assigned for decoding.
74 cast_environment_ = new CastEnvironment( 111 cast_environment_ = new CastEnvironment(
75 scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(), 112 scoped_ptr<base::TickClock>(new base::DefaultTickClock()).Pass(),
76 base::MessageLoopProxy::current(), 113 base::MessageLoopProxy::current(),
77 g_cast_threads.Get().GetAudioEncodeMessageLoopProxy(), 114 g_cast_threads.Get().GetAudioEncodeMessageLoopProxy(),
78 NULL, 115 NULL,
79 g_cast_threads.Get().GetVideoEncodeMessageLoopProxy(), 116 g_cast_threads.Get().GetVideoEncodeMessageLoopProxy(),
80 NULL, 117 NULL,
81 base::MessageLoopProxy::current(), 118 base::MessageLoopProxy::current(),
82 logging_config); 119 media::cast::GetLoggingConfigWithRawEventsAndStatsEnabled());
120
121 // Logging: enable raw events and stats collection.
122 media::cast::CastLoggingConfig logging_config =
123 media::cast::GetLoggingConfigWithRawEventsAndStatsEnabled();
124 // Rationale for using unretained: The callback cannot be called after the
125 // destruction of CastTransportSenderIPC, and they both share the same thread.
126 cast_transport_.reset(new CastTransportSenderIPC(
127 local_endpoint,
128 remote_endpoint,
129 base::Bind(&CastSessionDelegate::StatusNotificationCB,
130 base::Unretained(this)),
131 logging_config,
132 base::Bind(&CastSessionDelegate::LogRawEvents, base::Unretained(this))));
133
134 cast_sender_ = CastSender::Create(cast_environment_, cast_transport_.get());
135 cast_transport_->SetPacketReceiver(cast_sender_->packet_receiver());
83 } 136 }
84 137
85 void CastSessionDelegate::StartAudio( 138 void CastSessionDelegate::ToggleLogging(bool is_audio, bool enable) {
86 const AudioSenderConfig& config,
87 const FrameInputAvailableCallback& callback) {
88 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
89
90 audio_config_.reset(new AudioSenderConfig(config));
91 video_frame_input_available_callback_ = callback;
92 StartSendingInternal();
93 }
94
95 void CastSessionDelegate::StartVideo(
96 const VideoSenderConfig& config,
97 const FrameInputAvailableCallback& callback) {
98 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
99 audio_frame_input_available_callback_ = callback;
100
101 video_config_.reset(new VideoSenderConfig(config));
102 StartSendingInternal();
103 }
104
105 void CastSessionDelegate::StartUDP(const net::IPEndPoint& local_endpoint,
106 const net::IPEndPoint& remote_endpoint) {
107 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
108 transport_configured_ = true;
109 local_endpoint_ = local_endpoint;
110 remote_endpoint_ = remote_endpoint;
111 StartSendingInternal();
112 }
113
114 void CastSessionDelegate::ToggleLogging(bool is_audio,
115 bool enable) {
116 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 139 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
117 if (enable) { 140 if (enable) {
118 if (is_audio) { 141 if (is_audio) {
119 if (audio_event_subscriber_.get()) 142 if (audio_event_subscriber_.get())
120 return; 143 return;
121 audio_event_subscriber_.reset(new media::cast::EncodingEventSubscriber( 144 audio_event_subscriber_.reset(new media::cast::EncodingEventSubscriber(
122 media::cast::AUDIO_EVENT, kMaxAudioEventEntries)); 145 media::cast::AUDIO_EVENT, kMaxAudioEventEntries));
123 cast_environment_->Logging()->AddRawEventSubscriber( 146 cast_environment_->Logging()->AddRawEventSubscriber(
124 audio_event_subscriber_.get()); 147 audio_event_subscriber_.get());
125 } else { 148 } else {
(...skipping 15 matching lines...) Expand all
141 if (!video_event_subscriber_.get()) 164 if (!video_event_subscriber_.get())
142 return; 165 return;
143 cast_environment_->Logging()->RemoveRawEventSubscriber( 166 cast_environment_->Logging()->RemoveRawEventSubscriber(
144 video_event_subscriber_.get()); 167 video_event_subscriber_.get());
145 video_event_subscriber_.reset(); 168 video_event_subscriber_.reset();
146 } 169 }
147 } 170 }
148 } 171 }
149 172
150 void CastSessionDelegate::GetEventLogsAndReset( 173 void CastSessionDelegate::GetEventLogsAndReset(
151 bool is_audio, const EventLogsCallback& callback) { 174 bool is_audio,
175 const EventLogsCallback& callback) {
152 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 176 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
153 177
154 media::cast::EncodingEventSubscriber* subscriber = is_audio ? 178 media::cast::EncodingEventSubscriber* subscriber =
155 audio_event_subscriber_.get() : video_event_subscriber_.get(); 179 is_audio ? audio_event_subscriber_.get() : video_event_subscriber_.get();
156 if (!subscriber) { 180 if (!subscriber) {
157 callback.Run(make_scoped_ptr(new std::string).Pass()); 181 callback.Run(make_scoped_ptr(new std::string).Pass());
158 return; 182 return;
159 } 183 }
160 184
161 media::cast::FrameEventMap frame_events; 185 media::cast::FrameEventMap frame_events;
162 media::cast::PacketEventMap packet_events; 186 media::cast::PacketEventMap packet_events;
163 media::cast::RtpTimestamp rtp_timestamp; 187 media::cast::RtpTimestamp rtp_timestamp;
164 188
165 subscriber->GetEventsAndReset(&frame_events, &packet_events, &rtp_timestamp); 189 subscriber->GetEventsAndReset(&frame_events, &packet_events, &rtp_timestamp);
(...skipping 29 matching lines...) Expand all
195 219
196 callback.Run(stats.Pass()); 220 callback.Run(stats.Pass());
197 } 221 }
198 222
199 void CastSessionDelegate::StatusNotificationCB( 223 void CastSessionDelegate::StatusNotificationCB(
200 media::cast::transport::CastTransportStatus unused_status) { 224 media::cast::transport::CastTransportStatus unused_status) {
201 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 225 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
202 // TODO(hubbe): Call javascript UDPTransport error function. 226 // TODO(hubbe): Call javascript UDPTransport error function.
203 } 227 }
204 228
205 void CastSessionDelegate::StartSendingInternal() {
206 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
207
208 // No transport, wait.
209 if (!transport_configured_)
210 return;
211
212 // No audio or video, wait.
213 if (!audio_config_ || !video_config_)
214 return;
215
216 // Logging: enable raw events and stats collection.
217 media::cast::CastLoggingConfig logging_config =
218 media::cast::GetLoggingConfigWithRawEventsAndStatsEnabled();
219 Initialize(logging_config);
220
221 // Rationale for using unretained: The callback cannot be called after the
222 // destruction of CastTransportSenderIPC, and they both share the same thread.
223 cast_transport_.reset(new CastTransportSenderIPC(
224 local_endpoint_,
225 remote_endpoint_,
226 base::Bind(&CastSessionDelegate::StatusNotificationCB,
227 base::Unretained(this)),
228 logging_config,
229 base::Bind(&CastSessionDelegate::LogRawEvents,
230 base::Unretained(this))));
231
232 // TODO(hubbe): set config.aes_key and config.aes_iv_mask.
233 if (audio_config_) {
234 media::cast::transport::CastTransportAudioConfig config;
235 config.base.ssrc = audio_config_->sender_ssrc;
236 config.codec = audio_config_->codec;
237 config.base.rtp_config = audio_config_->rtp_config;
238 config.frequency = audio_config_->frequency;
239 config.channels = audio_config_->channels;
240 cast_transport_->InitializeAudio(config);
241 }
242 if (video_config_) {
243 media::cast::transport::CastTransportVideoConfig config;
244 config.base.ssrc = video_config_->sender_ssrc;
245 config.codec = video_config_->codec;
246 config.base.rtp_config = video_config_->rtp_config;
247 cast_transport_->InitializeVideo(config);
248 }
249
250 cast_sender_.reset(CastSender::CreateCastSender(
251 cast_environment_,
252 audio_config_.get(),
253 video_config_.get(),
254 NULL, // GPU.
255 base::Bind(&CastSessionDelegate::InitializationResult,
256 weak_factory_.GetWeakPtr()),
257 cast_transport_.get()));
258 cast_transport_->SetPacketReceiver(cast_sender_->packet_receiver());
259 }
260
261 void CastSessionDelegate::InitializationResult( 229 void CastSessionDelegate::InitializationResult(
262 media::cast::CastInitializationStatus result) const { 230 media::cast::CastInitializationStatus result) const {
263 DCHECK(cast_sender_); 231 DCHECK(cast_sender_);
264 232
265 // TODO(pwestin): handle the error codes. 233 // TODO(pwestin): handle the error codes.
266 if (result == media::cast::STATUS_INITIALIZED) { 234 if (result == media::cast::STATUS_AUDIO_INITIALIZED) {
267 if (!audio_frame_input_available_callback_.is_null()) { 235 if (!audio_frame_input_available_callback_.is_null()) {
268 audio_frame_input_available_callback_.Run(cast_sender_->frame_input()); 236 audio_frame_input_available_callback_.Run(
237 cast_sender_->audio_frame_input());
269 } 238 }
239 } else if (result == media::cast::STATUS_VIDEO_INITIALIZED) {
270 if (!video_frame_input_available_callback_.is_null()) { 240 if (!video_frame_input_available_callback_.is_null()) {
271 video_frame_input_available_callback_.Run(cast_sender_->frame_input()); 241 video_frame_input_available_callback_.Run(
242 cast_sender_->video_frame_input());
272 } 243 }
273 } 244 }
274 } 245 }
275 246
276 void CastSessionDelegate::LogRawEvents( 247 void CastSessionDelegate::LogRawEvents(
277 const std::vector<media::cast::PacketEvent>& packet_events) { 248 const std::vector<media::cast::PacketEvent>& packet_events) {
278 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); 249 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread());
279 250
280 for (std::vector<media::cast::PacketEvent>::const_iterator it = 251 for (std::vector<media::cast::PacketEvent>::const_iterator it =
281 packet_events.begin(); 252 packet_events.begin();
282 it != packet_events.end(); 253 it != packet_events.end();
283 ++it) { 254 ++it) {
284 cast_environment_->Logging()->InsertPacketEvent(it->timestamp, 255 cast_environment_->Logging()->InsertPacketEvent(it->timestamp,
285 it->type, 256 it->type,
286 it->rtp_timestamp, 257 it->rtp_timestamp,
287 it->frame_id, 258 it->frame_id,
288 it->packet_id, 259 it->packet_id,
289 it->max_packet_id, 260 it->max_packet_id,
290 it->size); 261 it->size);
291 } 262 }
292 } 263 }
OLDNEW
« no previous file with comments | « chrome/renderer/media/cast_session_delegate.h ('k') | media/cast/audio_sender/audio_encoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698