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/callback_helpers.h" | |
7 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
8 #include "base/logging.h" | 9 #include "base/logging.h" |
9 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
11 #include "base/strings/stringprintf.h" | |
10 #include "chrome/common/chrome_version_info.h" | 12 #include "chrome/common/chrome_version_info.h" |
11 #include "chrome/renderer/media/cast_threads.h" | 13 #include "chrome/renderer/media/cast_threads.h" |
12 #include "chrome/renderer/media/cast_transport_sender_ipc.h" | 14 #include "chrome/renderer/media/cast_transport_sender_ipc.h" |
13 #include "content/public/renderer/render_thread.h" | 15 #include "content/public/renderer/render_thread.h" |
14 #include "media/cast/cast_config.h" | 16 #include "media/cast/cast_config.h" |
15 #include "media/cast/cast_environment.h" | 17 #include "media/cast/cast_environment.h" |
16 #include "media/cast/cast_sender.h" | 18 #include "media/cast/cast_sender.h" |
17 #include "media/cast/logging/log_serializer.h" | 19 #include "media/cast/logging/log_serializer.h" |
18 #include "media/cast/logging/logging_defines.h" | 20 #include "media/cast/logging/logging_defines.h" |
19 #include "media/cast/logging/proto/raw_events.pb.h" | 21 #include "media/cast/logging/proto/raw_events.pb.h" |
(...skipping 27 matching lines...) Expand all Loading... | |
47 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 49 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
48 | 50 |
49 if (!cast_transport_ || !cast_sender_) { | 51 if (!cast_transport_ || !cast_sender_) { |
50 error_callback.Run("Destination not set."); | 52 error_callback.Run("Destination not set."); |
51 return; | 53 return; |
52 } | 54 } |
53 | 55 |
54 audio_frame_input_available_callback_ = callback; | 56 audio_frame_input_available_callback_ = callback; |
55 cast_sender_->InitializeAudio( | 57 cast_sender_->InitializeAudio( |
56 config, | 58 config, |
57 base::Bind(&CastSessionDelegate::InitializationResultCB, | 59 base::Bind(&CastSessionDelegate::OnOperationalStatusChange, |
58 weak_factory_.GetWeakPtr(), error_callback)); | 60 weak_factory_.GetWeakPtr(), true, error_callback)); |
59 } | 61 } |
60 | 62 |
61 void CastSessionDelegate::StartVideo( | 63 void CastSessionDelegate::StartVideo( |
62 const VideoSenderConfig& config, | 64 const VideoSenderConfig& config, |
63 const VideoFrameInputAvailableCallback& callback, | 65 const VideoFrameInputAvailableCallback& callback, |
64 const ErrorCallback& error_callback, | 66 const ErrorCallback& error_callback, |
65 const media::cast::CreateVideoEncodeAcceleratorCallback& create_vea_cb, | 67 const media::cast::CreateVideoEncodeAcceleratorCallback& create_vea_cb, |
66 const media::cast::CreateVideoEncodeMemoryCallback& | 68 const media::cast::CreateVideoEncodeMemoryCallback& |
67 create_video_encode_mem_cb) { | 69 create_video_encode_mem_cb) { |
68 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 70 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
69 | 71 |
70 if (!cast_transport_ || !cast_sender_) { | 72 if (!cast_transport_ || !cast_sender_) { |
71 error_callback.Run("Destination not set."); | 73 error_callback.Run("Destination not set."); |
72 return; | 74 return; |
73 } | 75 } |
74 | 76 |
75 video_frame_input_available_callback_ = callback; | 77 video_frame_input_available_callback_ = callback; |
76 | 78 |
77 cast_sender_->InitializeVideo( | 79 cast_sender_->InitializeVideo( |
78 config, | 80 config, |
79 base::Bind(&CastSessionDelegate::InitializationResultCB, | 81 base::Bind(&CastSessionDelegate::OnOperationalStatusChange, |
80 weak_factory_.GetWeakPtr(), error_callback), | 82 weak_factory_.GetWeakPtr(), false, error_callback), |
81 create_vea_cb, | 83 create_vea_cb, |
82 create_video_encode_mem_cb); | 84 create_video_encode_mem_cb); |
83 } | 85 } |
84 | 86 |
85 void CastSessionDelegate::StartUDP(const net::IPEndPoint& remote_endpoint, | 87 void CastSessionDelegate::StartUDP(const net::IPEndPoint& remote_endpoint, |
86 scoped_ptr<base::DictionaryValue> options) { | 88 scoped_ptr<base::DictionaryValue> options) { |
87 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 89 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
88 | 90 |
89 // CastSender uses the renderer's IO thread as the main thread. This reduces | 91 // CastSender uses the renderer's IO thread as the main thread. This reduces |
90 // thread hopping for incoming video frames and outgoing network packets. | 92 // thread hopping for incoming video frames and outgoing network packets. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 | 201 |
200 callback.Run(stats.Pass()); | 202 callback.Run(stats.Pass()); |
201 } | 203 } |
202 | 204 |
203 void CastSessionDelegate::StatusNotificationCB( | 205 void CastSessionDelegate::StatusNotificationCB( |
204 media::cast::CastTransportStatus unused_status) { | 206 media::cast::CastTransportStatus unused_status) { |
205 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 207 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
206 // TODO(hubbe): Call javascript UDPTransport error function. | 208 // TODO(hubbe): Call javascript UDPTransport error function. |
207 } | 209 } |
208 | 210 |
209 void CastSessionDelegate::InitializationResultCB( | 211 void CastSessionDelegate::OnOperationalStatusChange( |
212 bool is_for_audio, | |
210 const ErrorCallback& error_callback, | 213 const ErrorCallback& error_callback, |
211 media::cast::CastInitializationStatus result) const { | 214 media::cast::OperationalStatus status) { |
212 DCHECK(cast_sender_); | 215 DCHECK(cast_sender_); |
213 | 216 |
214 switch (result) { | 217 switch (status) { |
215 case media::cast::STATUS_AUDIO_INITIALIZED: | 218 case media::cast::STATUS_UNINITIALIZED: |
216 audio_frame_input_available_callback_.Run( | 219 case media::cast::STATUS_CODEC_REINIT_PENDING: |
217 cast_sender_->audio_frame_input()); | 220 // Not an error. |
221 // TODO(miu): As an optimization, signal the client to pause sending more | |
222 // frames until the state becomes STATUS_INITIALIZED again. | |
218 break; | 223 break; |
219 case media::cast::STATUS_VIDEO_INITIALIZED: | 224 case media::cast::STATUS_INITIALIZED: |
220 video_frame_input_available_callback_.Run( | 225 // Once initialized, run the "frame input available" callback to allow the |
221 cast_sender_->video_frame_input()); | 226 // client to begin sending frames. If STATUS_INITIALIZED is encountered |
227 // again, do nothing since this is only an indication that the codec has | |
228 // successfully re-initialized. | |
229 if (is_for_audio) { | |
230 if (!audio_frame_input_available_callback_.is_null()) { | |
231 base::ResetAndReturn(&audio_frame_input_available_callback_).Run( | |
232 cast_sender_->audio_frame_input()); | |
233 } | |
234 } else { | |
235 if (!video_frame_input_available_callback_.is_null()) { | |
236 base::ResetAndReturn(&video_frame_input_available_callback_).Run( | |
237 cast_sender_->video_frame_input()); | |
238 } | |
239 } | |
222 break; | 240 break; |
Alpha Left Google
2015/02/07 01:18:57
Can we log this or there's already a log for frame
miu
2015/02/07 01:37:02
Yes, there's logging there: https://code.google.co
| |
223 case media::cast::STATUS_INVALID_CAST_ENVIRONMENT: | 241 case media::cast::STATUS_INVALID_CONFIGURATION: |
224 error_callback.Run("Invalid cast environment."); | 242 error_callback.Run(base::StringPrintf("Invalid %s configuration.", |
243 is_for_audio ? "audio" : "video")); | |
225 break; | 244 break; |
226 case media::cast::STATUS_INVALID_CRYPTO_CONFIGURATION: | 245 case media::cast::STATUS_UNSUPPORTED_CODEC: |
227 error_callback.Run("Invalid encryption keys."); | 246 error_callback.Run(base::StringPrintf("%s codec not supported.", |
247 is_for_audio ? "Audio" : "Video")); | |
228 break; | 248 break; |
229 case media::cast::STATUS_UNSUPPORTED_AUDIO_CODEC: | 249 case media::cast::STATUS_CODEC_INIT_FAILED: |
230 error_callback.Run("Audio codec not supported."); | 250 error_callback.Run(base::StringPrintf("%s codec initialization failed.", |
251 is_for_audio ? "Audio" : "Video")); | |
231 break; | 252 break; |
232 case media::cast::STATUS_UNSUPPORTED_VIDEO_CODEC: | 253 case media::cast::STATUS_CODEC_RUNTIME_ERROR: |
233 error_callback.Run("Video codec not supported."); | 254 error_callback.Run(base::StringPrintf("%s codec runtime error.", |
234 break; | 255 is_for_audio ? "Audio" : "Video")); |
235 case media::cast::STATUS_INVALID_AUDIO_CONFIGURATION: | |
236 error_callback.Run("Invalid audio configuration."); | |
237 break; | |
238 case media::cast::STATUS_INVALID_VIDEO_CONFIGURATION: | |
239 error_callback.Run("Invalid video configuration."); | |
240 break; | |
241 case media::cast::STATUS_HW_VIDEO_ENCODER_NOT_SUPPORTED: | |
242 error_callback.Run("Hardware video encoder not supported."); | |
243 break; | |
244 case media::cast::STATUS_AUDIO_UNINITIALIZED: | |
245 case media::cast::STATUS_VIDEO_UNINITIALIZED: | |
246 NOTREACHED() << "Not an error."; | |
247 break; | 256 break; |
248 } | 257 } |
249 } | 258 } |
250 | 259 |
251 void CastSessionDelegate::LogRawEvents( | 260 void CastSessionDelegate::LogRawEvents( |
252 const std::vector<media::cast::PacketEvent>& packet_events, | 261 const std::vector<media::cast::PacketEvent>& packet_events, |
253 const std::vector<media::cast::FrameEvent>& frame_events) { | 262 const std::vector<media::cast::FrameEvent>& frame_events) { |
254 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 263 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
255 | 264 |
256 for (std::vector<media::cast::PacketEvent>::const_iterator it = | 265 for (std::vector<media::cast::PacketEvent>::const_iterator it = |
(...skipping 24 matching lines...) Expand all Loading... | |
281 } else { | 290 } else { |
282 cast_environment_->Logging()->InsertFrameEvent( | 291 cast_environment_->Logging()->InsertFrameEvent( |
283 it->timestamp, | 292 it->timestamp, |
284 it->type, | 293 it->type, |
285 it->media_type, | 294 it->media_type, |
286 it->rtp_timestamp, | 295 it->rtp_timestamp, |
287 it->frame_id); | 296 it->frame_id); |
288 } | 297 } |
289 } | 298 } |
290 } | 299 } |
OLD | NEW |