Chromium Code Reviews| 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 |