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

Side by Side Diff: content/renderer/media/peer_connection_handler.cc

Issue 8060055: Adding support for MediaStream and PeerConnection functionality (Closed) Base URL: http://git.chromium.org/chromium/chromium.git@trunk
Patch Set: Code review fixes. Created 9 years 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
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/media/peer_connection_handler.h"
6
7 #include <stdlib.h>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/string_number_conversions.h"
13 #include "base/utf_string_conversions.h"
14 #include "content/renderer/media/media_stream_dependency_factory.h"
15 #include "content/renderer/media/media_stream_impl.h"
16 #include "third_party/libjingle/source/talk/base/thread.h"
17 #include "third_party/libjingle/source/talk/p2p/client/httpportallocator.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamDescrip tor.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamSource. h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPeerConnectionHand lerClient.h"
21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
22
23 PeerConnectionHandler::PeerConnectionHandler(
24 WebKit::WebPeerConnectionHandlerClient* client,
25 MediaStreamImpl* msi,
26 MediaStreamDependencyFactory* dependency_factory,
27 talk_base::Thread* signaling_thread,
28 cricket::HttpPortAllocator* port_allocator)
29 : client_(client),
30 media_stream_impl_(msi),
31 dependency_factory_(dependency_factory),
32 message_loop_proxy_(base::MessageLoopProxy::current()),
33 signaling_thread_(signaling_thread),
34 port_allocator_(port_allocator),
35 call_state_(NOT_STARTED) {
36 }
37
38 PeerConnectionHandler::~PeerConnectionHandler() {
39 if (native_peer_connection_.get()) {
40 native_peer_connection_->RegisterObserver(NULL);
41 native_peer_connection_->Close();
42 }
43 }
44
45 bool PeerConnectionHandler::SetVideoRenderer(
46 const std::string& stream_label,
47 cricket::VideoRenderer* renderer) {
48 return native_peer_connection_->SetVideoRenderer(stream_label, renderer);
49 }
50
51 void PeerConnectionHandler::initialize(
52 const WebKit::WebString& server_configuration,
53 const WebKit::WebSecurityOrigin& security_origin) {
54 // We support the following server configuration format:
55 // "STUN <address>:<port>". We only support STUN at the moment.
56
57 // Strip "STUN ".
58 std::string strip_string = "STUN ";
59 std::string config = UTF16ToUTF8(server_configuration);
60 size_t pos = config.find(strip_string);
61 DCHECK_EQ(pos, 0u);
scherkus (not reviewing) 2011/11/23 22:52:04 are these strings passed in from WebKit via JS/HTM
Henrik Grunell 2011/11/24 11:32:59 Yes.
62 if (pos != 0) {
63 VLOG(1) << "Invalid configuration string.";
scherkus (not reviewing) 2011/11/23 22:52:04 DVLOG?
Henrik Grunell 2011/11/24 11:32:59 Sure, fixed.
64 return;
65 }
66 config = config.substr(strip_string.length());
67 // Parse out port.
68 pos = config.find(':');
69 DCHECK(pos != std::string::npos);
scherkus (not reviewing) 2011/11/23 22:52:04 ditto for this + other DCHECKs
Henrik Grunell 2011/11/24 11:32:59 Done.
70 if (pos == std::string::npos) {
71 VLOG(1) << "Invalid configuration string.";
72 return;
73 }
74 int port = 0;
75 bool success = base::StringToInt(config.substr(pos+1), &port);
76 DCHECK(success && (port != 0));
77 if (!success || (port == 0)) {
78 VLOG(1) << "Invalid configuration string.";
79 return;
80 }
81 // Get address.
82 std::string address = config.substr(0, pos);
83
84 std::vector<talk_base::SocketAddress> stun_hosts;
85 stun_hosts.push_back(talk_base::SocketAddress(address, port));
86 port_allocator_->SetStunHosts(stun_hosts);
87
88 native_peer_connection_.reset(dependency_factory_->CreatePeerConnection(
89 signaling_thread_));
90 native_peer_connection_->RegisterObserver(this);
91 }
92
93 void PeerConnectionHandler::produceInitialOffer(
94 const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>&
95 pending_add_streams) {
96 // We currently don't support creating an initial offer without a stream.
97 // Native PeerConnection will anyway create the initial offer when the first
98 // (and only) stream is added, so it will be done when processPendingStreams
99 // is called if not here.
100 if (pending_add_streams.isEmpty()) {
101 DVLOG(1) << "Can't produce initial offer with no stream.";
102 return;
103 }
104 // TODO(grunell): Support several streams.
105 DCHECK_EQ(pending_add_streams.size(), 1u);
106 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector;
107 pending_add_streams[0].sources(source_vector);
108 DCHECK_GT(source_vector.size(), 0u);
109 std::string label = UTF16ToUTF8(source_vector[0].id());
110 AddStream(label);
111 }
112
113 void PeerConnectionHandler::handleInitialOffer(const WebKit::WebString& sdp) {
114 native_peer_connection_->SignalingMessage(UTF16ToUTF8(sdp));
115 }
116
117 void PeerConnectionHandler::processSDP(const WebKit::WebString& sdp) {
118 native_peer_connection_->SignalingMessage(UTF16ToUTF8(sdp));
119 }
120
121 void PeerConnectionHandler::processPendingStreams(
122 const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>&
123 pending_add_streams,
124 const WebKit::WebVector<WebKit::WebMediaStreamDescriptor>&
125 pending_remove_streams) {
126 // TODO(grunell): Support several streams.
127 if (!pending_add_streams.isEmpty()) {
128 DCHECK_EQ(pending_add_streams.size(), 1u);
129 AddStream(UTF16ToUTF8(pending_add_streams[0].label()));
130 }
131 // Currently we ignore remove stream, no support in native PeerConnection.
132 }
133
134 void PeerConnectionHandler::sendDataStreamMessage(
135 const char* data,
136 size_t length) {
137 // TODO(grunell): Implement. Not supported in native PeerConnection.
138 NOTIMPLEMENTED();
139 }
140
141 void PeerConnectionHandler::stop() {
142 if (native_peer_connection_.get())
143 native_peer_connection_->RegisterObserver(NULL);
144 native_peer_connection_.reset();
145 // The close function will delete us.
146 media_stream_impl_->ClosePeerConnection();
147 }
148
149 void PeerConnectionHandler::OnSignalingMessage(const std::string& msg) {
150 if (!message_loop_proxy_->BelongsToCurrentThread()) {
151 message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
152 &PeerConnectionHandler::OnSignalingMessage,
153 base::Unretained(this),
154 msg));
155 return;
156 }
157 client_->didGenerateSDP(UTF8ToUTF16(msg));
158 }
159
160 void PeerConnectionHandler::OnAddStream(const std::string& stream_id,
161 bool video) {
162 if (!video)
163 return;
164
165 if (!message_loop_proxy_->BelongsToCurrentThread()) {
166 message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
167 &PeerConnectionHandler::OnAddStreamCallback,
168 base::Unretained(this),
169 stream_id));
170 } else {
171 OnAddStreamCallback(stream_id);
172 }
173 }
174
175 void PeerConnectionHandler::OnRemoveStream(
176 const std::string& stream_id,
177 bool video) {
178 if (!video)
179 return;
180
181 if (!message_loop_proxy_->BelongsToCurrentThread()) {
182 message_loop_proxy_->PostTask(FROM_HERE, base::Bind(
183 &PeerConnectionHandler::OnRemoveStreamCallback,
184 base::Unretained(this),
185 remote_label_));
186 } else {
187 OnRemoveStreamCallback(remote_label_);
188 }
189 }
190
191 void PeerConnectionHandler::AddStream(const std::string label) {
192 // TODO(grunell): Fix code in this function after a new native PeerConnection
193 // version has been rolled out.
194 if (call_state_ == NOT_STARTED) {
195 // TODO(grunell): Add audio and/or video depending on what's enabled
196 // in the stream.
197 std::string audio_label = label;
198 audio_label.append("-audio");
199 native_peer_connection_->AddStream(audio_label, false); // Audio
200 native_peer_connection_->AddStream(label, true); // Video
201 call_state_ = INITIATING;
202 }
203 if (call_state_ == INITIATING || call_state_ == RECEIVING) {
204 local_label_ = label;
205 if (media_stream_impl_->SetVideoCaptureModule(label))
206 native_peer_connection_->SetVideoCapture("");
207 if (call_state_ == INITIATING)
208 native_peer_connection_->Connect();
209 else if (call_state_ == RECEIVING)
210 call_state_ = SENDING_AND_RECEIVING;
211 } else {
212 DLOG(ERROR) << "Multiple streams not supported";
213 }
214 }
215
216 void PeerConnectionHandler::OnAddStreamCallback(
217 const std::string& stream_label) {
218 // TODO(grunell): Fix code in this function after a new native PeerConnection
219 // version has been rolled out.
220 if (call_state_ == NOT_STARTED) {
221 remote_label_ = stream_label;
222 call_state_ = RECEIVING;
223 } else if (call_state_ == INITIATING) {
224 remote_label_ = local_label_;
225 remote_label_ += "-remote";
226 call_state_ = SENDING_AND_RECEIVING;
227 }
228
229 // TODO(grunell): Support several tracks.
230 WebKit::WebVector<WebKit::WebMediaStreamSource>
231 source_vector(static_cast<size_t>(2));
232 source_vector[0].initialize(WebKit::WebString::fromUTF8(remote_label_),
233 WebKit::WebMediaStreamSource::TypeVideo,
234 WebKit::WebString::fromUTF8("RemoteVideo"));
235 source_vector[1].initialize(WebKit::WebString::fromUTF8(remote_label_),
236 WebKit::WebMediaStreamSource::TypeAudio,
237 WebKit::WebString::fromUTF8("RemoteAudio"));
238 WebKit::WebMediaStreamDescriptor descriptor;
239 descriptor.initialize(UTF8ToUTF16(remote_label_), source_vector);
240 client_->didAddRemoteStream(descriptor);
241 }
242
243 void PeerConnectionHandler::OnRemoveStreamCallback(
244 const std::string& stream_label) {
245 // TODO(grunell): Support several tracks.
246 WebKit::WebVector<WebKit::WebMediaStreamSource>
247 source_vector(static_cast<size_t>(2));
248 source_vector[0].initialize(WebKit::WebString::fromUTF8(stream_label),
249 WebKit::WebMediaStreamSource::TypeVideo,
250 WebKit::WebString::fromUTF8("RemoteVideo"));
251 source_vector[1].initialize(WebKit::WebString::fromUTF8(stream_label),
252 WebKit::WebMediaStreamSource::TypeAudio,
253 WebKit::WebString::fromUTF8("RemoteAudio"));
254 WebKit::WebMediaStreamDescriptor descriptor;
255 descriptor.initialize(UTF8ToUTF16(stream_label), source_vector);
256 client_->didRemoveRemoteStream(descriptor);
257 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698