OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/renderer/media/media_stream_impl.h" | 5 #include "content/renderer/media/media_stream_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "content/renderer/media/capture_video_decoder.h" | 13 #include "content/renderer/media/capture_video_decoder.h" |
14 #include "content/renderer/media/media_stream_dependency_factory.h" | 14 #include "content/renderer/media/media_stream_dependency_factory.h" |
15 #include "content/renderer/media/media_stream_dispatcher.h" | 15 #include "content/renderer/media/media_stream_dispatcher.h" |
16 #include "content/renderer/media/peer_connection_handler.h" | 16 #include "content/renderer/media/peer_connection_handler.h" |
17 #include "content/renderer/media/rtc_video_decoder.h" | 17 #include "content/renderer/media/rtc_video_decoder.h" |
18 #include "content/renderer/media/video_capture_impl_manager.h" | 18 #include "content/renderer/media/video_capture_impl_manager.h" |
19 #include "content/renderer/media/video_capture_module_impl.h" | 19 #include "content/renderer/media/video_capture_module_impl.h" |
20 #include "content/renderer/media/webrtc_audio_device_impl.h" | 20 #include "content/renderer/media/webrtc_audio_device_impl.h" |
21 #include "content/renderer/p2p/ipc_network_manager.h" | 21 #include "content/renderer/p2p/ipc_network_manager.h" |
22 #include "content/renderer/p2p/ipc_socket_factory.h" | 22 #include "content/renderer/p2p/ipc_socket_factory.h" |
23 #include "content/renderer/p2p/socket_dispatcher.h" | 23 #include "content/renderer/p2p/socket_dispatcher.h" |
24 #include "jingle/glue/thread_wrapper.h" | 24 #include "jingle/glue/thread_wrapper.h" |
25 #include "media/base/message_loop_factory.h" | 25 #include "media/base/message_loop_factory.h" |
26 #include "third_party/libjingle/source/talk/p2p/client/httpportallocator.h" | |
27 #include "third_party/libjingle/source/talk/session/phone/dummydevicemanager.h" | |
28 #include "third_party/libjingle/source/talk/session/phone/webrtcmediaengine.h" | |
29 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre amDescriptor.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre amDescriptor.h" |
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistr y.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistr y.h" |
31 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre amSource.h" | 28 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre amSource.h" |
32 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" |
33 | 30 |
34 namespace { | 31 namespace { |
35 | 32 |
36 static const int kVideoCaptureWidth = 352; | 33 static const int kVideoCaptureWidth = 352; |
37 static const int kVideoCaptureHeight = 288; | 34 static const int kVideoCaptureHeight = 288; |
38 static const int kVideoCaptureFramePerSecond = 30; | 35 static const int kVideoCaptureFramePerSecond = 30; |
39 | 36 |
40 } // namespace | 37 } // namespace |
41 | 38 |
42 int MediaStreamImpl::next_request_id_ = 0; | 39 int MediaStreamImpl::next_request_id_ = 0; |
43 | 40 |
41 // TODO(grunell): BEFORE COMMIT. Add DCHECK(CalledOnValidThread()) in all | |
42 // functions. | |
43 | |
44 MediaStreamImpl::MediaStreamImpl( | 44 MediaStreamImpl::MediaStreamImpl( |
45 MediaStreamDispatcher* media_stream_dispatcher, | 45 MediaStreamDispatcher* media_stream_dispatcher, |
46 content::P2PSocketDispatcher* p2p_socket_dispatcher, | 46 content::P2PSocketDispatcher* p2p_socket_dispatcher, |
47 VideoCaptureImplManager* vc_manager, | 47 VideoCaptureImplManager* vc_manager, |
48 MediaStreamDependencyFactory* dependency_factory) | 48 MediaStreamDependencyFactory* dependency_factory) |
49 : dependency_factory_(dependency_factory), | 49 : dependency_factory_(dependency_factory), |
50 media_stream_dispatcher_(media_stream_dispatcher), | 50 media_stream_dispatcher_(media_stream_dispatcher), |
51 media_engine_(NULL), | |
52 p2p_socket_dispatcher_(p2p_socket_dispatcher), | 51 p2p_socket_dispatcher_(p2p_socket_dispatcher), |
53 network_manager_(NULL), | 52 network_manager_(NULL), |
54 vc_manager_(vc_manager), | 53 vc_manager_(vc_manager), |
55 peer_connection_handler_(NULL), | 54 peer_connection_handler_(NULL), |
56 message_loop_proxy_(base::MessageLoopProxy::current()), | 55 message_loop_proxy_(base::MessageLoopProxy::current()), |
57 signaling_thread_(NULL), | 56 signaling_thread_(NULL), |
58 worker_thread_(NULL), | 57 worker_thread_(NULL), |
59 chrome_worker_thread_("Chrome_libJingle_WorkerThread"), | 58 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { |
60 vcm_created_(false) { | |
61 } | 59 } |
62 | 60 |
63 MediaStreamImpl::~MediaStreamImpl() { | 61 MediaStreamImpl::~MediaStreamImpl() { |
64 DCHECK(!peer_connection_handler_); | 62 DCHECK(!peer_connection_handler_); |
65 if (dependency_factory_.get()) | 63 if (dependency_factory_.get()) |
66 dependency_factory_->DeletePeerConnectionFactory(); | 64 dependency_factory_->ReleasePeerConnectionFactory(); |
67 if (network_manager_) { | 65 if (network_manager_) { |
68 // The network manager needs to free its resources on the thread they were | 66 // The network manager needs to free its resources on the thread they were |
69 // created, which is the worked thread. | 67 // created, which is the worked thread. |
70 if (chrome_worker_thread_.IsRunning()) { | 68 if (chrome_worker_thread_.IsRunning()) { |
71 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 69 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
72 &MediaStreamImpl::DeleteIpcNetworkManager, | 70 &MediaStreamImpl::DeleteIpcNetworkManager, |
73 base::Unretained(this))); | 71 base::Unretained(this))); |
74 } else { | 72 } else { |
75 NOTREACHED() << "Worker thread not running."; | 73 NOTREACHED() << "Worker thread not running."; |
76 } | 74 } |
77 } | 75 } |
78 } | 76 } |
79 | 77 |
80 WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler( | 78 WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler( |
81 WebKit::WebPeerConnectionHandlerClient* client) { | 79 WebKit::WebPeerConnectionHandlerClient* client) { |
82 DCHECK(CalledOnValidThread()); | 80 DCHECK(CalledOnValidThread()); |
83 if (peer_connection_handler_) { | 81 if (peer_connection_handler_) { |
84 DVLOG(1) << "A PeerConnection already exists"; | 82 DVLOG(1) << "A PeerConnection already exists"; |
85 return NULL; | 83 return NULL; |
86 } | 84 } |
87 | 85 EnsurePeerConnectionFactory(); |
88 if (!media_engine_) { | |
89 media_engine_ = dependency_factory_->CreateWebRtcMediaEngine(); | |
90 } | |
91 | |
92 if (!signaling_thread_) { | |
93 jingle_glue::JingleThreadWrapper::EnsureForCurrentThread(); | |
94 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | |
95 signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); | |
96 } | |
97 | |
98 if (!worker_thread_) { | |
99 if (!chrome_worker_thread_.IsRunning()) { | |
100 if (!chrome_worker_thread_.Start()) { | |
101 LOG(ERROR) << "Could not start worker thread"; | |
102 delete media_engine_; | |
103 media_engine_ = NULL; | |
104 signaling_thread_ = NULL; | |
105 return NULL; | |
106 } | |
107 } | |
108 base::WaitableEvent event(true, false); | |
109 chrome_worker_thread_.message_loop()->PostTask( | |
110 FROM_HERE, | |
111 base::Bind(&MediaStreamImpl::InitializeWorkerThread, this, | |
112 &worker_thread_, &event)); | |
113 event.Wait(); | |
114 DCHECK(worker_thread_); | |
115 } | |
116 | |
117 if (!network_manager_) | |
118 network_manager_ = new content::IpcNetworkManager(p2p_socket_dispatcher_); | |
119 | |
120 if (!socket_factory_.get()) { | |
121 socket_factory_.reset( | |
122 new content::IpcPacketSocketFactory(p2p_socket_dispatcher_)); | |
123 } | |
124 | |
125 if (!dependency_factory_->PeerConnectionFactoryCreated()) { | |
126 if (!dependency_factory_->CreatePeerConnectionFactory(media_engine_, | |
127 worker_thread_)) { | |
128 LOG(ERROR) << "Could not initialize PeerConnection factory"; | |
129 return NULL; | |
130 } | |
131 } | |
132 | 86 |
133 peer_connection_handler_ = new PeerConnectionHandler( | 87 peer_connection_handler_ = new PeerConnectionHandler( |
134 client, | 88 client, |
135 this, | 89 this, |
136 dependency_factory_.get(), | 90 dependency_factory_.get()); |
137 signaling_thread_, | |
138 p2p_socket_dispatcher_, | |
139 network_manager_, | |
140 socket_factory_.get()); | |
141 | 91 |
142 return peer_connection_handler_; | 92 return peer_connection_handler_; |
143 } | 93 } |
144 | 94 |
145 void MediaStreamImpl::ClosePeerConnection() { | 95 void MediaStreamImpl::ClosePeerConnection() { |
146 DCHECK(CalledOnValidThread()); | 96 DCHECK(CalledOnValidThread()); |
147 rtc_video_decoder_ = NULL; | 97 video_renderer_ = NULL; |
148 media_engine_->SetVideoCaptureModule(NULL); | |
149 vcm_created_ = false; | |
150 peer_connection_handler_ = NULL; | 98 peer_connection_handler_ = NULL; |
99 // TODO(grunell): This is a temporary workaround for an error in native | |
100 // PeerConnection where added live tracks are not seen on the remote side. | |
101 MediaStreamTrackPtrMap::const_iterator it = local_tracks_.begin(); | |
102 for (; it != local_tracks_.end(); ++it) | |
103 it->second->set_state(webrtc::MediaStreamTrackInterface::kEnded); | |
151 } | 104 } |
152 | 105 |
153 bool MediaStreamImpl::SetVideoCaptureModule(const std::string& label) { | 106 webrtc::MediaStreamTrackInterface* MediaStreamImpl::GetLocalMediaStreamTrack( |
154 DCHECK(CalledOnValidThread()); | 107 std::string label) { |
155 if (vcm_created_) | 108 MediaStreamTrackPtrMap::iterator it = local_tracks_.find(label); |
156 return true; | 109 if (it == local_tracks_.end()) |
157 // Set the capture device. | 110 return NULL; |
158 // TODO(grunell): Instead of using the first track, the selected track | 111 MediaStreamTrackPtr stream = it->second; |
159 // should be used. | 112 return stream.get(); |
160 int id = media_stream_dispatcher_->video_session_id(label, 0); | |
161 if (id == media_stream::StreamDeviceInfo::kNoId) | |
162 return false; | |
163 webrtc::VideoCaptureModule* vcm = | |
164 new VideoCaptureModuleImpl(id, vc_manager_.get()); | |
165 vcm_created_ = true; | |
166 media_engine_->SetVideoCaptureModule(vcm); | |
167 return true; | |
168 } | 113 } |
169 | 114 |
170 void MediaStreamImpl::requestUserMedia( | 115 void MediaStreamImpl::requestUserMedia( |
171 const WebKit::WebUserMediaRequest& user_media_request, | 116 const WebKit::WebUserMediaRequest& user_media_request, |
172 const WebKit::WebVector<WebKit::WebMediaStreamSource>& | 117 const WebKit::WebVector<WebKit::WebMediaStreamSource>& |
173 media_stream_source_vector) { | 118 media_stream_source_vector) { |
174 DCHECK(CalledOnValidThread()); | 119 DCHECK(CalledOnValidThread()); |
175 DCHECK(!user_media_request.isNull()); | 120 DCHECK(!user_media_request.isNull()); |
176 | 121 |
177 int request_id = next_request_id_++; | 122 int request_id = next_request_id_++; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
219 } | 164 } |
220 | 165 |
221 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( | 166 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( |
222 const GURL& url, | 167 const GURL& url, |
223 media::MessageLoopFactory* message_loop_factory) { | 168 media::MessageLoopFactory* message_loop_factory) { |
224 DCHECK(CalledOnValidThread()); | 169 DCHECK(CalledOnValidThread()); |
225 WebKit::WebMediaStreamDescriptor descriptor( | 170 WebKit::WebMediaStreamDescriptor descriptor( |
226 WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url)); | 171 WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url)); |
227 if (descriptor.isNull()) | 172 if (descriptor.isNull()) |
228 return NULL; // This is not a valid stream. | 173 return NULL; // This is not a valid stream. |
174 | |
175 // We must find out if this is a local or remote stream. The tracks in a local | |
176 // stream have IDs that are in the form | |
177 // <MediaStreamManager-label>#{audio,video}-<session-ID>. We extract the | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
can we move the code that does this parsing out to
Henrik Grunell
2012/01/26 13:03:16
Broke out the generation and parsing of the track
| |
178 // MSM-label and if found in the dispatcher we have a local stream, otherwise | |
179 // we have a remote stream. There will be changes soon so that we don't have | |
180 // to bother about the type of stream here. Hence this solution is OK for now. | |
229 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector; | 181 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector; |
230 descriptor.sources(source_vector); | 182 descriptor.sources(source_vector); |
231 std::string label; | 183 std::string msm_label; |
232 for (size_t i = 0; i < source_vector.size(); ++i) { | 184 for (size_t i = 0; i < source_vector.size(); ++i) { |
233 if (source_vector[i].type() == WebKit::WebMediaStreamSource::TypeVideo) { | 185 if (source_vector[i].type() == WebKit::WebMediaStreamSource::TypeVideo) { |
234 label = UTF16ToUTF8(source_vector[i].id()); | 186 // We assume there is one video track only. |
187 msm_label = UTF16ToUTF8(source_vector[i].id()); | |
188 size_t pos = msm_label.rfind("#"); | |
189 msm_label = msm_label.substr(0, pos); | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
what if pos is npos?
Henrik Grunell
2012/01/26 13:03:16
Commented on that in the new functions. (Doesn't m
| |
235 break; | 190 break; |
236 } | 191 } |
237 } | 192 } |
238 if (label.empty()) | 193 if (msm_label.empty()) |
239 return NULL; | 194 return NULL; |
240 | 195 |
241 scoped_refptr<media::VideoDecoder> decoder; | 196 scoped_refptr<media::VideoDecoder> decoder; |
242 if (media_stream_dispatcher_->IsStream(label)) { | 197 if (media_stream_dispatcher_->IsStream(msm_label)) { |
243 // It's a local stream. | 198 // It's a local stream. |
244 int video_session_id = media_stream_dispatcher_->video_session_id(label, 0); | 199 int video_session_id = |
200 media_stream_dispatcher_->video_session_id(msm_label, 0); | |
245 media::VideoCapture::VideoCaptureCapability capability; | 201 media::VideoCapture::VideoCaptureCapability capability; |
246 capability.width = kVideoCaptureWidth; | 202 capability.width = kVideoCaptureWidth; |
247 capability.height = kVideoCaptureHeight; | 203 capability.height = kVideoCaptureHeight; |
248 capability.max_fps = kVideoCaptureFramePerSecond; | 204 capability.max_fps = kVideoCaptureFramePerSecond; |
249 capability.expected_capture_delay = 0; | 205 capability.expected_capture_delay = 0; |
250 capability.raw_type = media::VideoFrame::I420; | 206 capability.raw_type = media::VideoFrame::I420; |
251 capability.interlaced = false; | 207 capability.interlaced = false; |
252 decoder = new CaptureVideoDecoder( | 208 decoder = new CaptureVideoDecoder( |
253 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), | 209 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), |
254 video_session_id, | 210 video_session_id, |
255 vc_manager_.get(), | 211 vc_manager_.get(), |
256 capability); | 212 capability); |
257 } else { | 213 } else { |
258 // It's a remote stream. | 214 // It's a remote stream. |
259 size_t found = label.rfind("-remote"); | 215 if (!video_renderer_.get()) |
260 if (found != std::string::npos) | 216 video_renderer_ = new talk_base::RefCountedObject<VideoRendererWrapper>(); |
261 label = label.substr(0, found); | 217 if (video_renderer_->renderer()) { |
262 if (rtc_video_decoder_.get()) { | |
263 // The renderer is used by PeerConnection, release it first. | 218 // The renderer is used by PeerConnection, release it first. |
264 if (peer_connection_handler_) | 219 if (peer_connection_handler_) { |
265 peer_connection_handler_->SetVideoRenderer(label, NULL); | 220 peer_connection_handler_->SetVideoRenderer( |
221 UTF16ToUTF8(descriptor.label()), | |
222 NULL); | |
223 } | |
224 video_renderer_->SetVideoDecoder(NULL); | |
266 } | 225 } |
267 rtc_video_decoder_ = new RTCVideoDecoder( | 226 RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder( |
268 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), | 227 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), |
269 url.spec()); | 228 url.spec()); |
270 decoder = rtc_video_decoder_; | 229 decoder = rtc_video_decoder; |
271 if (peer_connection_handler_) | 230 video_renderer_->SetVideoDecoder(rtc_video_decoder); |
272 peer_connection_handler_->SetVideoRenderer(label, rtc_video_decoder_); | 231 if (peer_connection_handler_) { |
232 peer_connection_handler_->SetVideoRenderer( | |
233 UTF16ToUTF8(descriptor.label()), | |
234 video_renderer_); | |
235 } | |
273 } | 236 } |
274 return decoder; | 237 return decoder; |
275 } | 238 } |
276 | 239 |
277 void MediaStreamImpl::OnStreamGenerated( | 240 void MediaStreamImpl::OnStreamGenerated( |
278 int request_id, | 241 int request_id, |
279 const std::string& label, | 242 const std::string& label, |
280 const media_stream::StreamDeviceInfoArray& audio_array, | 243 const media_stream::StreamDeviceInfoArray& audio_array, |
281 const media_stream::StreamDeviceInfoArray& video_array) { | 244 const media_stream::StreamDeviceInfoArray& video_array) { |
282 DCHECK(CalledOnValidThread()); | 245 DCHECK(CalledOnValidThread()); |
246 EnsurePeerConnectionFactory(); | |
283 | 247 |
284 // We only support max one audio track and one video track. If the UI | |
285 // for selecting device starts to allow several devices, we must implement | |
286 // handling for this. | |
287 DCHECK_LE(audio_array.size(), 1u); | |
288 DCHECK_LE(video_array.size(), 1u); | |
289 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector( | 248 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector( |
290 audio_array.size() + video_array.size()); | 249 audio_array.size() + video_array.size()); |
291 | 250 |
292 WebKit::WebString track_label_audio(UTF8ToUTF16("AudioDevice")); | 251 // The label for a stream is globally unique. The track session id is globally |
293 WebKit::WebString track_label_video(UTF8ToUTF16("VideoCapture")); | 252 // unique for the set of audio tracks and video tracks respectively. An audio |
294 size_t track_num = source_vector.size(); | 253 // track and a video track can have the same session id (without being |
295 while (track_num--) { | 254 // related). Hence we create a unique track label from the stream label, track |
296 if (track_num < audio_array.size()) { | 255 // type and track session id. |
297 source_vector[track_num].initialize( | 256 |
298 UTF8ToUTF16(label), | 257 // Add audio tracks. |
258 size_t i = 0; | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
unless you use 'i' outside the loops, just declare
Henrik Grunell
2012/01/26 13:03:16
Relic from earlier stage of local dev. Fixed.
| |
259 std::string track_label; | |
260 for (; i < audio_array.size(); ++i) { | |
261 track_label = label; | |
262 track_label += "#audio-"; | |
263 track_label += audio_array[i].session_id; | |
264 talk_base::scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( | |
265 dependency_factory_->CreateLocalAudioTrack(audio_array[i].name, NULL)); | |
266 local_tracks_.insert( | |
267 std::pair<std::string, MediaStreamTrackPtr>(track_label, audio_track)); | |
268 source_vector[i].initialize( | |
269 UTF8ToUTF16(track_label), | |
299 WebKit::WebMediaStreamSource::TypeAudio, | 270 WebKit::WebMediaStreamSource::TypeAudio, |
300 track_label_audio); | 271 UTF8ToUTF16(audio_array[i].name)); |
301 } else { | 272 } |
302 source_vector[track_num].initialize( | 273 |
303 UTF8ToUTF16(label), | 274 // Add video tracks. |
275 for (i = 0; i < video_array.size(); ++i) { | |
276 track_label = label; | |
277 track_label += "#video-"; | |
278 track_label += video_array[i].session_id; | |
279 webrtc::VideoCaptureModule* vcm = | |
280 new VideoCaptureModuleImpl(video_array[i].session_id, | |
281 vc_manager_.get()); | |
282 talk_base::scoped_refptr<webrtc::LocalVideoTrackInterface> video_track( | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
should video_track be of type MediaStreamTrackPtr?
Henrik Grunell
2012/01/26 13:03:16
Yes, that's better. Changed it and for audio_track
| |
283 dependency_factory_->CreateLocalVideoTrack( | |
284 video_array[i].name, | |
285 webrtc::CreateVideoCapturer(vcm))); | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
add a comment about the ownership of vcm?
Henrik Grunell
2012/01/26 13:03:16
Done.
| |
286 local_tracks_.insert( | |
287 std::pair<std::string, MediaStreamTrackPtr>(track_label, video_track)); | |
288 source_vector[audio_array.size() + i].initialize( | |
289 UTF8ToUTF16(track_label), | |
304 WebKit::WebMediaStreamSource::TypeVideo, | 290 WebKit::WebMediaStreamSource::TypeVideo, |
305 track_label_video); | 291 UTF8ToUTF16(video_array[i].name)); |
306 } | |
307 } | 292 } |
308 | 293 |
294 // TODO(grunell): Remove tracks from the map when support to stop is | |
295 // added in WebKit. | |
296 | |
309 MediaRequestMap::iterator it = user_media_requests_.find(request_id); | 297 MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
310 if (it == user_media_requests_.end()) { | 298 if (it == user_media_requests_.end()) { |
311 DVLOG(1) << "Request ID not found"; | 299 DVLOG(1) << "Request ID not found"; |
312 return; | 300 return; |
313 } | 301 } |
314 WebKit::WebUserMediaRequest user_media_request = it->second; | 302 WebKit::WebUserMediaRequest user_media_request = it->second; |
315 user_media_requests_.erase(it); | 303 user_media_requests_.erase(it); |
316 stream_labels_.push_back(label); | |
317 | 304 |
318 user_media_request.requestSucceeded(source_vector); | 305 user_media_request.requestSucceeded(source_vector); |
319 } | 306 } |
320 | 307 |
321 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { | 308 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { |
322 DCHECK(CalledOnValidThread()); | 309 DCHECK(CalledOnValidThread()); |
323 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" | 310 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" |
324 << request_id << ")"; | 311 << request_id << ")"; |
325 MediaRequestMap::iterator it = user_media_requests_.find(request_id); | 312 MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
326 if (it == user_media_requests_.end()) { | 313 if (it == user_media_requests_.end()) { |
(...skipping 30 matching lines...) Expand all Loading... | |
357 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 344 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
358 *thread = jingle_glue::JingleThreadWrapper::current(); | 345 *thread = jingle_glue::JingleThreadWrapper::current(); |
359 event->Signal(); | 346 event->Signal(); |
360 } | 347 } |
361 | 348 |
362 void MediaStreamImpl::DeleteIpcNetworkManager() { | 349 void MediaStreamImpl::DeleteIpcNetworkManager() { |
363 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); | 350 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); |
364 delete network_manager_; | 351 delete network_manager_; |
365 network_manager_ = NULL; | 352 network_manager_ = NULL; |
366 } | 353 } |
354 | |
355 bool MediaStreamImpl::EnsurePeerConnectionFactory() { | |
356 DCHECK(CalledOnValidThread()); | |
357 if (!signaling_thread_) { | |
358 jingle_glue::JingleThreadWrapper::EnsureForCurrentThread(); | |
359 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | |
360 signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); | |
361 } | |
362 | |
363 if (!worker_thread_) { | |
364 if (!chrome_worker_thread_.IsRunning()) { | |
365 if (!chrome_worker_thread_.Start()) { | |
366 LOG(ERROR) << "Could not start worker thread"; | |
367 signaling_thread_ = NULL; | |
368 return false; | |
369 } | |
370 } | |
371 base::WaitableEvent event(true, false); | |
372 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | |
373 &MediaStreamImpl::InitializeWorkerThread, | |
374 this, | |
375 &worker_thread_, | |
376 &event)); | |
377 event.Wait(); | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
is there a specific reason why we need to do this
Henrik Grunell
2012/01/26 13:03:16
Yes there's a reason. worker_thread_ must be set b
| |
378 DCHECK(worker_thread_); | |
379 } | |
380 | |
381 if (!network_manager_) | |
382 network_manager_ = new content::IpcNetworkManager(p2p_socket_dispatcher_); | |
383 | |
384 if (!socket_factory_.get()) { | |
385 socket_factory_.reset( | |
386 new content::IpcPacketSocketFactory(p2p_socket_dispatcher_)); | |
387 } | |
388 | |
389 if (!dependency_factory_->PeerConnectionFactoryCreated()) { | |
390 if (!dependency_factory_->CreatePeerConnectionFactory( | |
391 worker_thread_, | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
it feels weird to me to see parameters indented to
Henrik Grunell
2012/01/26 13:03:16
That seems better. Fixed.
| |
392 signaling_thread_, | |
393 p2p_socket_dispatcher_, | |
394 network_manager_, | |
395 socket_factory_.get())) { | |
396 LOG(ERROR) << "Could not initialize PeerConnection factory"; | |
397 return false; | |
398 } | |
399 } | |
400 | |
401 return true; | |
402 } | |
403 | |
404 MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper() {} | |
405 | |
406 MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() {} | |
407 | |
408 cricket::VideoRenderer* MediaStreamImpl::VideoRendererWrapper::renderer() { | |
tommi (sloooow) - chröme
2012/01/24 15:18:56
nit: one liners like this one (all lower case) usu
Henrik Grunell
2012/01/26 13:03:16
Done.
| |
409 return rtc_video_decoder_.get(); | |
410 } | |
411 | |
412 void MediaStreamImpl::VideoRendererWrapper::SetVideoDecoder( | |
413 RTCVideoDecoder* decoder) { | |
414 rtc_video_decoder_ = decoder; | |
415 } | |
OLD | NEW |