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 "content/public/renderer/p2p_socket_client.h" | |
9 #include "content/public/renderer/render_thread.h" | 10 #include "content/public/renderer/render_thread.h" |
11 #include "media/cast/cast_config.h" | |
10 #include "media/cast/cast_environment.h" | 12 #include "media/cast/cast_environment.h" |
11 #include "media/cast/cast_sender.h" | 13 #include "media/cast/cast_sender.h" |
12 #include "media/cast/logging/logging_defines.h" | 14 #include "media/cast/logging/logging_defines.h" |
13 | 15 |
14 using media::cast::AudioSenderConfig; | 16 using media::cast::AudioSenderConfig; |
15 using media::cast::CastEnvironment; | 17 using media::cast::CastEnvironment; |
16 using media::cast::CastSender; | 18 using media::cast::CastSender; |
17 using media::cast::VideoSenderConfig; | 19 using media::cast::VideoSenderConfig; |
18 | 20 |
19 CastSessionDelegate::CastSessionDelegate() | 21 CastSessionDelegate::CastSessionDelegate() |
20 : audio_encode_thread_("CastAudioEncodeThread"), | 22 : audio_encode_thread_("CastAudioEncodeThread"), |
21 video_encode_thread_("CastVideoEncodeThread"), | 23 video_encode_thread_("CastVideoEncodeThread"), |
22 audio_configured_(false), | 24 audio_configured_(false), |
23 video_configured_(false), | 25 video_configured_(false), |
24 io_message_loop_proxy_( | 26 io_message_loop_proxy_( |
25 content::RenderThread::Get()->GetIOMessageLoopProxy()) { | 27 content::RenderThread::Get()->GetIOMessageLoopProxy()) { |
26 } | 28 } |
27 | 29 |
28 CastSessionDelegate::~CastSessionDelegate() { | 30 CastSessionDelegate::~CastSessionDelegate() { |
29 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 31 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
30 } | 32 } |
31 | 33 |
34 void CastSessionDelegate::SetSocketFactory( | |
35 scoped_ptr<CastSession::SocketFactory> socket_factory, | |
36 const net::IPEndPoint& remote_address) { | |
37 socket_factory_ = socket_factory.Pass(); | |
38 remote_address_ = remote_address; | |
39 } | |
40 | |
32 void CastSessionDelegate::StartAudio(const AudioSenderConfig& config) { | 41 void CastSessionDelegate::StartAudio(const AudioSenderConfig& config) { |
33 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 42 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
34 | 43 |
35 audio_configured_ = true; | 44 audio_configured_ = true; |
36 audio_config_ = config; | 45 audio_config_ = config; |
37 MaybeStartSending(); | 46 MaybeStartSending(); |
38 } | 47 } |
39 | 48 |
40 void CastSessionDelegate::StartVideo(const VideoSenderConfig& config) { | 49 void CastSessionDelegate::StartVideo(const VideoSenderConfig& config) { |
41 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 50 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
42 | 51 |
43 video_configured_ = true; | 52 video_configured_ = true; |
44 video_config_ = config; | 53 video_config_ = config; |
45 MaybeStartSending(); | 54 MaybeStartSending(); |
46 } | 55 } |
47 | 56 |
48 void CastSessionDelegate::StartSending() { | 57 void CastSessionDelegate::StartSending() { |
49 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); | 58 DCHECK(io_message_loop_proxy_->BelongsToCurrentThread()); |
50 | 59 |
51 if (cast_environment_) | 60 if (cast_environment_) |
52 return; | 61 return; |
53 | 62 |
63 if (!socket_factory_) { | |
64 // TODO(hubbe): Post an error back to the user | |
65 return; | |
66 } | |
67 | |
68 socket_ = socket_factory_->create(); | |
69 socket_->SetDelegate(this); | |
70 | |
54 audio_encode_thread_.Start(); | 71 audio_encode_thread_.Start(); |
55 video_encode_thread_.Start(); | 72 video_encode_thread_.Start(); |
56 | 73 |
57 // CastSender uses the renderer's IO thread as the main thread. This reduces | 74 // CastSender uses the renderer's IO thread as the main thread. This reduces |
58 // thread hopping for incoming video frames and outgoing network packets. | 75 // thread hopping for incoming video frames and outgoing network packets. |
59 // There's no need to decode so no thread assigned for decoding. | 76 // There's no need to decode so no thread assigned for decoding. |
60 // Get default logging: All disabled. | 77 // Get default logging: All disabled. |
61 cast_environment_ = new CastEnvironment( | 78 cast_environment_ = new CastEnvironment( |
62 &clock_, | 79 &clock_, |
63 base::MessageLoopProxy::current(), | 80 base::MessageLoopProxy::current(), |
64 audio_encode_thread_.message_loop_proxy(), | 81 audio_encode_thread_.message_loop_proxy(), |
65 NULL, | 82 NULL, |
66 video_encode_thread_.message_loop_proxy(), | 83 video_encode_thread_.message_loop_proxy(), |
67 NULL, | 84 NULL, |
68 media::cast::GetDefaultCastLoggingConfig()); | 85 media::cast::GetDefaultCastLoggingConfig()); |
69 | 86 |
70 // TODO(hclam): A couple things need to be done here: | 87 // TODO(hclam): Implement VideoEncoderController to configure hardware |
71 // 1. Connect media::cast::PacketSender to net::Socket interface. | 88 // encoder. |
72 // 2. Implement VideoEncoderController to configure hardware encoder. | |
73 cast_sender_.reset(CastSender::CreateCastSender( | 89 cast_sender_.reset(CastSender::CreateCastSender( |
74 cast_environment_, | 90 cast_environment_, |
75 audio_config_, | 91 audio_config_, |
76 video_config_, | 92 video_config_, |
77 NULL, | 93 NULL, |
78 NULL)); | 94 this)); |
95 } | |
96 | |
97 // media::cast::PacketSender Implementation | |
98 bool CastSessionDelegate::SendPacket( | |
99 const media::cast::Packet& packet) { | |
100 // TODO(hubbe): Make sure audio and video packets gets the right DSCP. | |
101 socket_->SendWithDscp( | |
102 remote_address_, | |
103 *reinterpret_cast<const std::vector<char> *>(&packet), | |
104 net::DSCP_AF41); | |
105 return true; | |
106 } | |
107 | |
108 bool CastSessionDelegate::SendPackets( | |
109 const media::cast::PacketList& packets) { | |
110 // TODO(hubbe): Add ability to send multiple packets in one IPC message. | |
111 for (size_t i = 0; i < packets.size(); i++) { | |
112 SendPacket(packets[i]); | |
113 } | |
114 return true; | |
115 } | |
116 | |
117 // content::P2PSocketClient::Delegate Implementation | |
118 void CastSessionDelegate::OnOpen( | |
119 const net::IPEndPoint& address) { | |
120 // Called once Init completes. Ignored. | |
121 } | |
122 | |
123 void CastSessionDelegate::OnIncomingTcpConnection( | |
124 const net::IPEndPoint& address, | |
125 content::P2PSocketClient* client) { | |
126 // We don't support server sockets. | |
Sergey Ulanov
2013/12/07 01:15:29
Do you ever use TCP sockets for cast? If not, then
hubbe
2013/12/10 18:25:57
Done.
| |
127 NOTREACHED(); | |
128 } | |
129 | |
130 void CastSessionDelegate::OnSendComplete() { | |
131 // Ignored for now. | |
132 } | |
133 | |
134 void CastSessionDelegate::OnError() { | |
135 // TODO(hubbe): Report this back to the user. | |
136 } | |
137 | |
138 void CastSessionDelegate::OnDataReceived(const net::IPEndPoint& address, | |
139 const std::vector<char>& data) { | |
140 uint8 *packet_copy = new uint8[data.size()]; | |
141 memcpy(packet_copy, &data[0], data.size()); | |
142 cast_sender_->packet_receiver()->ReceivedPacket( | |
143 packet_copy, | |
144 data.size(), | |
145 base::Bind(&media::cast::PacketReceiver::DeletePacket, | |
146 packet_copy)); | |
79 } | 147 } |
80 | 148 |
81 void CastSessionDelegate::MaybeStartSending() { | 149 void CastSessionDelegate::MaybeStartSending() { |
82 if (!audio_configured_ || !video_configured_) | 150 if (!audio_configured_ || !video_configured_) |
83 return; | 151 return; |
84 StartSending(); | 152 StartSending(); |
85 } | 153 } |
OLD | NEW |