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" | |
18 #include "content/renderer/media/video_capture_impl_manager.h" | 17 #include "content/renderer/media/video_capture_impl_manager.h" |
19 #include "content/renderer/media/video_capture_module_impl.h" | 18 #include "content/renderer/media/video_capture_module_impl.h" |
20 #include "content/renderer/media/webrtc_audio_device_impl.h" | 19 #include "content/renderer/media/webrtc_audio_device_impl.h" |
21 #include "content/renderer/p2p/ipc_network_manager.h" | 20 #include "content/renderer/p2p/ipc_network_manager.h" |
22 #include "content/renderer/p2p/ipc_socket_factory.h" | 21 #include "content/renderer/p2p/ipc_socket_factory.h" |
23 #include "content/renderer/p2p/socket_dispatcher.h" | 22 #include "content/renderer/p2p/socket_dispatcher.h" |
24 #include "jingle/glue/thread_wrapper.h" | 23 #include "jingle/glue/thread_wrapper.h" |
25 #include "media/base/message_loop_factory.h" | 24 #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" | 25 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre
amDescriptor.h" |
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistr
y.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistr
y.h" |
31 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre
amSource.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebMediaStre
amSource.h" |
32 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" | 28 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h" |
33 | 29 |
34 namespace { | 30 namespace { |
35 | 31 |
36 static const int kVideoCaptureWidth = 352; | 32 static const int kVideoCaptureWidth = 352; |
37 static const int kVideoCaptureHeight = 288; | 33 static const int kVideoCaptureHeight = 288; |
38 static const int kVideoCaptureFramePerSecond = 30; | 34 static const int kVideoCaptureFramePerSecond = 30; |
39 | 35 |
40 } // namespace | 36 } // namespace |
41 | 37 |
| 38 // The MediaStreamMananger label for a stream is globally unique. The track |
| 39 // session id is globally unique for the set of audio tracks and video tracks |
| 40 // respectively. An audio track and a video track can have the same session id |
| 41 // (without being related). Hence we create a unique track label from the stream |
| 42 // label, track type and track session id: |
| 43 // <MediaStreamManager-label>#{audio,video}-<session-ID>. |
| 44 static std::string CreateTrackLabel( |
| 45 const std::string& manager_label, |
| 46 int session_id, |
| 47 bool is_video) { |
| 48 std::string track_label = manager_label; |
| 49 if (is_video) { |
| 50 track_label += "#video-"; |
| 51 } else { |
| 52 track_label += "#audio-"; |
| 53 } |
| 54 track_label += session_id; |
| 55 return track_label; |
| 56 } |
| 57 |
| 58 // Extracting the MediaStreamManager stream label will only work for track |
| 59 // labels created by CreateTrackLabel. If is wasn't, the contents of the |
| 60 // returned string is undefined. |
| 61 static std::string ExtractManagerStreamLabel( |
| 62 const std::string& track_label) { |
| 63 std::string manager_label = track_label; |
| 64 size_t pos = manager_label.rfind("#"); |
| 65 // If # isn't found, the string is left intact. |
| 66 manager_label = manager_label.substr(0, pos); |
| 67 return manager_label; |
| 68 } |
| 69 |
| 70 |
42 int MediaStreamImpl::next_request_id_ = 0; | 71 int MediaStreamImpl::next_request_id_ = 0; |
43 | 72 |
44 MediaStreamImpl::MediaStreamImpl( | 73 MediaStreamImpl::MediaStreamImpl( |
45 MediaStreamDispatcher* media_stream_dispatcher, | 74 MediaStreamDispatcher* media_stream_dispatcher, |
46 content::P2PSocketDispatcher* p2p_socket_dispatcher, | 75 content::P2PSocketDispatcher* p2p_socket_dispatcher, |
47 VideoCaptureImplManager* vc_manager, | 76 VideoCaptureImplManager* vc_manager, |
48 MediaStreamDependencyFactory* dependency_factory) | 77 MediaStreamDependencyFactory* dependency_factory) |
49 : dependency_factory_(dependency_factory), | 78 : dependency_factory_(dependency_factory), |
50 media_stream_dispatcher_(media_stream_dispatcher), | 79 media_stream_dispatcher_(media_stream_dispatcher), |
51 media_engine_(NULL), | |
52 p2p_socket_dispatcher_(p2p_socket_dispatcher), | 80 p2p_socket_dispatcher_(p2p_socket_dispatcher), |
53 network_manager_(NULL), | 81 network_manager_(NULL), |
54 vc_manager_(vc_manager), | 82 vc_manager_(vc_manager), |
55 peer_connection_handler_(NULL), | 83 peer_connection_handler_(NULL), |
56 message_loop_proxy_(base::MessageLoopProxy::current()), | 84 message_loop_proxy_(base::MessageLoopProxy::current()), |
57 signaling_thread_(NULL), | 85 signaling_thread_(NULL), |
58 worker_thread_(NULL), | 86 worker_thread_(NULL), |
59 chrome_worker_thread_("Chrome_libJingle_WorkerThread"), | 87 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { |
60 vcm_created_(false) { | |
61 } | 88 } |
62 | 89 |
63 MediaStreamImpl::~MediaStreamImpl() { | 90 MediaStreamImpl::~MediaStreamImpl() { |
64 DCHECK(!peer_connection_handler_); | 91 DCHECK(!peer_connection_handler_); |
65 if (dependency_factory_.get()) | 92 if (dependency_factory_.get()) |
66 dependency_factory_->DeletePeerConnectionFactory(); | 93 dependency_factory_->ReleasePeerConnectionFactory(); |
67 if (network_manager_) { | 94 if (network_manager_) { |
68 // The network manager needs to free its resources on the thread they were | 95 // The network manager needs to free its resources on the thread they were |
69 // created, which is the worked thread. | 96 // created, which is the worked thread. |
70 if (chrome_worker_thread_.IsRunning()) { | 97 if (chrome_worker_thread_.IsRunning()) { |
71 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 98 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
72 &MediaStreamImpl::DeleteIpcNetworkManager, | 99 &MediaStreamImpl::DeleteIpcNetworkManager, |
73 base::Unretained(this))); | 100 base::Unretained(this))); |
74 } else { | 101 } else { |
75 NOTREACHED() << "Worker thread not running."; | 102 NOTREACHED() << "Worker thread not running."; |
76 } | 103 } |
77 } | 104 } |
78 } | 105 } |
79 | 106 |
80 WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler( | 107 WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler( |
81 WebKit::WebPeerConnectionHandlerClient* client) { | 108 WebKit::WebPeerConnectionHandlerClient* client) { |
82 DCHECK(CalledOnValidThread()); | 109 DCHECK(CalledOnValidThread()); |
83 if (peer_connection_handler_) { | 110 if (peer_connection_handler_) { |
84 DVLOG(1) << "A PeerConnection already exists"; | 111 DVLOG(1) << "A PeerConnection already exists"; |
85 return NULL; | 112 return NULL; |
86 } | 113 } |
87 | 114 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 | 115 |
133 peer_connection_handler_ = new PeerConnectionHandler( | 116 peer_connection_handler_ = new PeerConnectionHandler( |
134 client, | 117 client, |
135 this, | 118 this, |
136 dependency_factory_.get(), | 119 dependency_factory_.get()); |
137 signaling_thread_, | |
138 p2p_socket_dispatcher_, | |
139 network_manager_, | |
140 socket_factory_.get()); | |
141 | 120 |
142 return peer_connection_handler_; | 121 return peer_connection_handler_; |
143 } | 122 } |
144 | 123 |
145 void MediaStreamImpl::ClosePeerConnection() { | 124 void MediaStreamImpl::ClosePeerConnection() { |
146 DCHECK(CalledOnValidThread()); | 125 DCHECK(CalledOnValidThread()); |
147 rtc_video_decoder_ = NULL; | 126 video_renderer_ = NULL; |
148 media_engine_->SetVideoCaptureModule(NULL); | |
149 vcm_created_ = false; | |
150 peer_connection_handler_ = NULL; | 127 peer_connection_handler_ = NULL; |
| 128 // TODO(grunell): This is a temporary workaround for an error in native |
| 129 // PeerConnection where added live tracks are not seen on the remote side. |
| 130 MediaStreamTrackPtrMap::const_iterator it = local_tracks_.begin(); |
| 131 for (; it != local_tracks_.end(); ++it) |
| 132 it->second->set_state(webrtc::MediaStreamTrackInterface::kEnded); |
151 } | 133 } |
152 | 134 |
153 bool MediaStreamImpl::SetVideoCaptureModule(const std::string& label) { | 135 webrtc::MediaStreamTrackInterface* MediaStreamImpl::GetLocalMediaStreamTrack( |
| 136 const std::string& label) { |
154 DCHECK(CalledOnValidThread()); | 137 DCHECK(CalledOnValidThread()); |
155 if (vcm_created_) | 138 MediaStreamTrackPtrMap::iterator it = local_tracks_.find(label); |
156 return true; | 139 if (it == local_tracks_.end()) |
157 // Set the capture device. | 140 return NULL; |
158 // TODO(grunell): Instead of using the first track, the selected track | 141 MediaStreamTrackPtr stream = it->second; |
159 // should be used. | 142 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 } | 143 } |
169 | 144 |
170 void MediaStreamImpl::requestUserMedia( | 145 void MediaStreamImpl::requestUserMedia( |
171 const WebKit::WebUserMediaRequest& user_media_request, | 146 const WebKit::WebUserMediaRequest& user_media_request, |
172 const WebKit::WebVector<WebKit::WebMediaStreamSource>& | 147 const WebKit::WebVector<WebKit::WebMediaStreamSource>& |
173 media_stream_source_vector) { | 148 media_stream_source_vector) { |
174 DCHECK(CalledOnValidThread()); | 149 DCHECK(CalledOnValidThread()); |
175 DCHECK(!user_media_request.isNull()); | 150 DCHECK(!user_media_request.isNull()); |
176 | 151 |
177 int request_id = next_request_id_++; | 152 int request_id = next_request_id_++; |
(...skipping 29 matching lines...) Expand all Loading... |
207 | 182 |
208 media_stream_dispatcher_->GenerateStream( | 183 media_stream_dispatcher_->GenerateStream( |
209 request_id, | 184 request_id, |
210 this, | 185 this, |
211 media_stream::StreamOptions(audio, video_option), | 186 media_stream::StreamOptions(audio, video_option), |
212 security_origin); | 187 security_origin); |
213 } | 188 } |
214 | 189 |
215 void MediaStreamImpl::cancelUserMediaRequest( | 190 void MediaStreamImpl::cancelUserMediaRequest( |
216 const WebKit::WebUserMediaRequest& user_media_request) { | 191 const WebKit::WebUserMediaRequest& user_media_request) { |
| 192 DCHECK(CalledOnValidThread()); |
217 // TODO(grunell): Implement. | 193 // TODO(grunell): Implement. |
218 NOTIMPLEMENTED(); | 194 NOTIMPLEMENTED(); |
219 } | 195 } |
220 | 196 |
221 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( | 197 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( |
222 const GURL& url, | 198 const GURL& url, |
223 media::MessageLoopFactory* message_loop_factory) { | 199 media::MessageLoopFactory* message_loop_factory) { |
224 DCHECK(CalledOnValidThread()); | 200 DCHECK(CalledOnValidThread()); |
225 WebKit::WebMediaStreamDescriptor descriptor( | 201 WebKit::WebMediaStreamDescriptor descriptor( |
226 WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url)); | 202 WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url)); |
227 if (descriptor.isNull()) | 203 if (descriptor.isNull()) |
228 return NULL; // This is not a valid stream. | 204 return NULL; // This is not a valid stream. |
| 205 |
| 206 // We must find out if this is a local or remote stream. We extract the |
| 207 // MediaStreamManager stream label and if found in the dispatcher we have a |
| 208 // local stream, otherwise we have a remote stream. There will be changes soon |
| 209 // so that we don't have to bother about the type of stream here. Hence this |
| 210 // solution is OK for now. |
| 211 |
229 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector; | 212 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector; |
230 descriptor.sources(source_vector); | 213 descriptor.sources(source_vector); |
231 std::string label; | 214 std::string msm_label; |
232 for (size_t i = 0; i < source_vector.size(); ++i) { | 215 for (size_t i = 0; i < source_vector.size(); ++i) { |
233 if (source_vector[i].type() == WebKit::WebMediaStreamSource::TypeVideo) { | 216 if (source_vector[i].type() == WebKit::WebMediaStreamSource::TypeVideo) { |
234 label = UTF16ToUTF8(source_vector[i].id()); | 217 // We assume there is one video track only. |
| 218 msm_label = ExtractManagerStreamLabel(UTF16ToUTF8(source_vector[i].id())); |
235 break; | 219 break; |
236 } | 220 } |
237 } | 221 } |
238 if (label.empty()) | 222 if (msm_label.empty()) |
239 return NULL; | 223 return NULL; |
240 | 224 |
241 scoped_refptr<media::VideoDecoder> decoder; | 225 scoped_refptr<media::VideoDecoder> decoder; |
242 if (media_stream_dispatcher_->IsStream(label)) { | 226 if (media_stream_dispatcher_->IsStream(msm_label)) { |
243 // It's a local stream. | 227 // It's a local stream. |
244 int video_session_id = media_stream_dispatcher_->video_session_id(label, 0); | 228 int video_session_id = |
| 229 media_stream_dispatcher_->video_session_id(msm_label, 0); |
245 media::VideoCapture::VideoCaptureCapability capability; | 230 media::VideoCapture::VideoCaptureCapability capability; |
246 capability.width = kVideoCaptureWidth; | 231 capability.width = kVideoCaptureWidth; |
247 capability.height = kVideoCaptureHeight; | 232 capability.height = kVideoCaptureHeight; |
248 capability.max_fps = kVideoCaptureFramePerSecond; | 233 capability.max_fps = kVideoCaptureFramePerSecond; |
249 capability.expected_capture_delay = 0; | 234 capability.expected_capture_delay = 0; |
250 capability.raw_type = media::VideoFrame::I420; | 235 capability.raw_type = media::VideoFrame::I420; |
251 capability.interlaced = false; | 236 capability.interlaced = false; |
252 decoder = new CaptureVideoDecoder( | 237 decoder = new CaptureVideoDecoder( |
253 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), | 238 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), |
254 video_session_id, | 239 video_session_id, |
255 vc_manager_.get(), | 240 vc_manager_.get(), |
256 capability); | 241 capability); |
257 } else { | 242 } else { |
258 // It's a remote stream. | 243 // It's a remote stream. |
259 size_t found = label.rfind("-remote"); | 244 if (!video_renderer_.get()) |
260 if (found != std::string::npos) | 245 video_renderer_ = new talk_base::RefCountedObject<VideoRendererWrapper>(); |
261 label = label.substr(0, found); | 246 if (video_renderer_->renderer()) { |
262 if (rtc_video_decoder_.get()) { | |
263 // The renderer is used by PeerConnection, release it first. | 247 // The renderer is used by PeerConnection, release it first. |
264 if (peer_connection_handler_) | 248 if (peer_connection_handler_) { |
265 peer_connection_handler_->SetVideoRenderer(label, NULL); | 249 peer_connection_handler_->SetVideoRenderer( |
| 250 UTF16ToUTF8(descriptor.label()), |
| 251 NULL); |
| 252 } |
| 253 video_renderer_->SetVideoDecoder(NULL); |
266 } | 254 } |
267 rtc_video_decoder_ = new RTCVideoDecoder( | 255 RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder( |
268 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), | 256 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), |
269 url.spec()); | 257 url.spec()); |
270 decoder = rtc_video_decoder_; | 258 decoder = rtc_video_decoder; |
271 if (peer_connection_handler_) | 259 video_renderer_->SetVideoDecoder(rtc_video_decoder); |
272 peer_connection_handler_->SetVideoRenderer(label, rtc_video_decoder_); | 260 if (peer_connection_handler_) { |
| 261 peer_connection_handler_->SetVideoRenderer( |
| 262 UTF16ToUTF8(descriptor.label()), |
| 263 video_renderer_); |
| 264 } |
273 } | 265 } |
274 return decoder; | 266 return decoder; |
275 } | 267 } |
276 | 268 |
277 void MediaStreamImpl::OnStreamGenerated( | 269 void MediaStreamImpl::OnStreamGenerated( |
278 int request_id, | 270 int request_id, |
279 const std::string& label, | 271 const std::string& label, |
280 const media_stream::StreamDeviceInfoArray& audio_array, | 272 const media_stream::StreamDeviceInfoArray& audio_array, |
281 const media_stream::StreamDeviceInfoArray& video_array) { | 273 const media_stream::StreamDeviceInfoArray& video_array) { |
282 DCHECK(CalledOnValidThread()); | 274 DCHECK(CalledOnValidThread()); |
| 275 EnsurePeerConnectionFactory(); |
283 | 276 |
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( | 277 WebKit::WebVector<WebKit::WebMediaStreamSource> source_vector( |
290 audio_array.size() + video_array.size()); | 278 audio_array.size() + video_array.size()); |
291 | 279 |
292 WebKit::WebString track_label_audio(UTF8ToUTF16("AudioDevice")); | 280 // Add audio tracks. |
293 WebKit::WebString track_label_video(UTF8ToUTF16("VideoCapture")); | 281 std::string track_label; |
294 size_t track_num = source_vector.size(); | 282 for (size_t i = 0; i < audio_array.size(); ++i) { |
295 while (track_num--) { | 283 track_label = CreateTrackLabel(label, audio_array[i].session_id, false); |
296 if (track_num < audio_array.size()) { | 284 MediaStreamTrackPtr audio_track( |
297 source_vector[track_num].initialize( | 285 dependency_factory_->CreateLocalAudioTrack(audio_array[i].name, NULL)); |
298 UTF8ToUTF16(label), | 286 local_tracks_.insert( |
| 287 std::pair<std::string, MediaStreamTrackPtr>(track_label, audio_track)); |
| 288 source_vector[i].initialize( |
| 289 UTF8ToUTF16(track_label), |
299 WebKit::WebMediaStreamSource::TypeAudio, | 290 WebKit::WebMediaStreamSource::TypeAudio, |
300 track_label_audio); | 291 UTF8ToUTF16(audio_array[i].name)); |
301 } else { | 292 } |
302 source_vector[track_num].initialize( | 293 |
303 UTF8ToUTF16(label), | 294 // Add video tracks. |
| 295 for (size_t i = 0; i < video_array.size(); ++i) { |
| 296 track_label = CreateTrackLabel(label, video_array[i].session_id, true); |
| 297 webrtc::VideoCaptureModule* vcm = |
| 298 new VideoCaptureModuleImpl(video_array[i].session_id, |
| 299 vc_manager_.get()); |
| 300 MediaStreamTrackPtr video_track(dependency_factory_->CreateLocalVideoTrack( |
| 301 video_array[i].name, |
| 302 // The video capturer takes ownership of |vcm|. |
| 303 webrtc::CreateVideoCapturer(vcm))); |
| 304 local_tracks_.insert( |
| 305 std::pair<std::string, MediaStreamTrackPtr>(track_label, video_track)); |
| 306 source_vector[audio_array.size() + i].initialize( |
| 307 UTF8ToUTF16(track_label), |
304 WebKit::WebMediaStreamSource::TypeVideo, | 308 WebKit::WebMediaStreamSource::TypeVideo, |
305 track_label_video); | 309 UTF8ToUTF16(video_array[i].name)); |
306 } | |
307 } | 310 } |
308 | 311 |
| 312 // TODO(grunell): Remove tracks from the map when support to stop is |
| 313 // added in WebKit. |
| 314 |
309 MediaRequestMap::iterator it = user_media_requests_.find(request_id); | 315 MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
310 if (it == user_media_requests_.end()) { | 316 if (it == user_media_requests_.end()) { |
311 DVLOG(1) << "Request ID not found"; | 317 DVLOG(1) << "Request ID not found"; |
312 return; | 318 return; |
313 } | 319 } |
314 WebKit::WebUserMediaRequest user_media_request = it->second; | 320 WebKit::WebUserMediaRequest user_media_request = it->second; |
315 user_media_requests_.erase(it); | 321 user_media_requests_.erase(it); |
316 stream_labels_.push_back(label); | |
317 | 322 |
318 user_media_request.requestSucceeded(source_vector); | 323 user_media_request.requestSucceeded(source_vector); |
319 } | 324 } |
320 | 325 |
321 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { | 326 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { |
322 DCHECK(CalledOnValidThread()); | 327 DCHECK(CalledOnValidThread()); |
323 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" | 328 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" |
324 << request_id << ")"; | 329 << request_id << ")"; |
325 MediaRequestMap::iterator it = user_media_requests_.find(request_id); | 330 MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
326 if (it == user_media_requests_.end()) { | 331 if (it == user_media_requests_.end()) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 391 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
387 *thread = jingle_glue::JingleThreadWrapper::current(); | 392 *thread = jingle_glue::JingleThreadWrapper::current(); |
388 event->Signal(); | 393 event->Signal(); |
389 } | 394 } |
390 | 395 |
391 void MediaStreamImpl::DeleteIpcNetworkManager() { | 396 void MediaStreamImpl::DeleteIpcNetworkManager() { |
392 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); | 397 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); |
393 delete network_manager_; | 398 delete network_manager_; |
394 network_manager_ = NULL; | 399 network_manager_ = NULL; |
395 } | 400 } |
| 401 |
| 402 bool MediaStreamImpl::EnsurePeerConnectionFactory() { |
| 403 DCHECK(CalledOnValidThread()); |
| 404 if (!signaling_thread_) { |
| 405 jingle_glue::JingleThreadWrapper::EnsureForCurrentThread(); |
| 406 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| 407 signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); |
| 408 } |
| 409 |
| 410 if (!worker_thread_) { |
| 411 if (!chrome_worker_thread_.IsRunning()) { |
| 412 if (!chrome_worker_thread_.Start()) { |
| 413 LOG(ERROR) << "Could not start worker thread"; |
| 414 signaling_thread_ = NULL; |
| 415 return false; |
| 416 } |
| 417 } |
| 418 base::WaitableEvent event(true, false); |
| 419 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
| 420 &MediaStreamImpl::InitializeWorkerThread, |
| 421 this, |
| 422 &worker_thread_, |
| 423 &event)); |
| 424 event.Wait(); |
| 425 DCHECK(worker_thread_); |
| 426 } |
| 427 |
| 428 if (!network_manager_) |
| 429 network_manager_ = new content::IpcNetworkManager(p2p_socket_dispatcher_); |
| 430 |
| 431 if (!socket_factory_.get()) { |
| 432 socket_factory_.reset( |
| 433 new content::IpcPacketSocketFactory(p2p_socket_dispatcher_)); |
| 434 } |
| 435 |
| 436 if (!dependency_factory_->PeerConnectionFactoryCreated()) { |
| 437 if (!dependency_factory_->CreatePeerConnectionFactory( |
| 438 worker_thread_, |
| 439 signaling_thread_, |
| 440 p2p_socket_dispatcher_, |
| 441 network_manager_, |
| 442 socket_factory_.get())) { |
| 443 LOG(ERROR) << "Could not initialize PeerConnection factory"; |
| 444 return false; |
| 445 } |
| 446 } |
| 447 |
| 448 return true; |
| 449 } |
| 450 |
| 451 MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper() {} |
| 452 |
| 453 MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() {} |
| 454 |
| 455 void MediaStreamImpl::VideoRendererWrapper::SetVideoDecoder( |
| 456 RTCVideoDecoder* decoder) { |
| 457 rtc_video_decoder_ = decoder; |
| 458 } |
OLD | NEW |