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/peer_connection_handler_jsep.h" | |
17 #include "content/renderer/media/video_capture_impl_manager.h" | 18 #include "content/renderer/media/video_capture_impl_manager.h" |
18 #include "content/renderer/media/video_capture_module_impl.h" | 19 #include "content/renderer/media/video_capture_module_impl.h" |
19 #include "content/renderer/media/webrtc_audio_device_impl.h" | 20 #include "content/renderer/media/webrtc_audio_device_impl.h" |
20 #include "content/renderer/p2p/ipc_network_manager.h" | 21 #include "content/renderer/p2p/ipc_network_manager.h" |
21 #include "content/renderer/p2p/ipc_socket_factory.h" | 22 #include "content/renderer/p2p/ipc_socket_factory.h" |
22 #include "content/renderer/p2p/socket_dispatcher.h" | 23 #include "content/renderer/p2p/socket_dispatcher.h" |
23 #include "jingle/glue/thread_wrapper.h" | 24 #include "jingle/glue/thread_wrapper.h" |
24 #include "media/base/message_loop_factory.h" | 25 #include "media/base/message_loop_factory.h" |
25 #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" |
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistr y.h" | 27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistr y.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
73 MediaStreamImpl::MediaStreamImpl( | 74 MediaStreamImpl::MediaStreamImpl( |
74 MediaStreamDispatcher* media_stream_dispatcher, | 75 MediaStreamDispatcher* media_stream_dispatcher, |
75 content::P2PSocketDispatcher* p2p_socket_dispatcher, | 76 content::P2PSocketDispatcher* p2p_socket_dispatcher, |
76 VideoCaptureImplManager* vc_manager, | 77 VideoCaptureImplManager* vc_manager, |
77 MediaStreamDependencyFactory* dependency_factory) | 78 MediaStreamDependencyFactory* dependency_factory) |
78 : dependency_factory_(dependency_factory), | 79 : dependency_factory_(dependency_factory), |
79 media_stream_dispatcher_(media_stream_dispatcher), | 80 media_stream_dispatcher_(media_stream_dispatcher), |
80 p2p_socket_dispatcher_(p2p_socket_dispatcher), | 81 p2p_socket_dispatcher_(p2p_socket_dispatcher), |
81 network_manager_(NULL), | 82 network_manager_(NULL), |
82 vc_manager_(vc_manager), | 83 vc_manager_(vc_manager), |
83 peer_connection_handler_(NULL), | |
84 message_loop_proxy_(base::MessageLoopProxy::current()), | |
85 signaling_thread_(NULL), | 84 signaling_thread_(NULL), |
86 worker_thread_(NULL), | 85 worker_thread_(NULL), |
87 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { | 86 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { |
88 } | 87 } |
89 | 88 |
90 MediaStreamImpl::~MediaStreamImpl() { | 89 MediaStreamImpl::~MediaStreamImpl() { |
91 DCHECK(!peer_connection_handler_); | 90 DCHECK(peer_connection_handlers_.empty()); |
92 if (dependency_factory_.get()) | 91 if (dependency_factory_.get()) |
93 dependency_factory_->ReleasePeerConnectionFactory(); | 92 dependency_factory_->ReleasePeerConnectionFactory(); |
94 if (network_manager_) { | 93 if (network_manager_) { |
95 // The network manager needs to free its resources on the thread they were | 94 // The network manager needs to free its resources on the thread they were |
96 // created, which is the worked thread. | 95 // created, which is the worked thread. |
97 if (chrome_worker_thread_.IsRunning()) { | 96 if (chrome_worker_thread_.IsRunning()) { |
98 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 97 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
99 &MediaStreamImpl::DeleteIpcNetworkManager, | 98 &MediaStreamImpl::DeleteIpcNetworkManager, |
100 base::Unretained(this))); | 99 base::Unretained(this))); |
101 // Stopping the thread will wait until all tasks have been | 100 // Stopping the thread will wait until all tasks have been |
102 // processed before returning. We wait for the above task to finish before | 101 // processed before returning. We wait for the above task to finish before |
103 // letting the destructor continue to avoid any potential race issues. | 102 // letting the destructor continue to avoid any potential race issues. |
104 chrome_worker_thread_.Stop(); | 103 chrome_worker_thread_.Stop(); |
105 } else { | 104 } else { |
106 NOTREACHED() << "Worker thread not running."; | 105 NOTREACHED() << "Worker thread not running."; |
107 } | 106 } |
108 } | 107 } |
109 } | 108 } |
110 | 109 |
111 WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler( | 110 WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler( |
112 WebKit::WebPeerConnectionHandlerClient* client) { | 111 WebKit::WebPeerConnectionHandlerClient* client) { |
113 DCHECK(CalledOnValidThread()); | 112 DCHECK(CalledOnValidThread()); |
114 if (peer_connection_handler_) { | |
115 DVLOG(1) << "A PeerConnection already exists"; | |
116 return NULL; | |
117 } | |
118 if (!EnsurePeerConnectionFactory()) | 113 if (!EnsurePeerConnectionFactory()) |
119 return NULL; | 114 return NULL; |
120 | 115 |
121 peer_connection_handler_ = new PeerConnectionHandler( | 116 PeerConnectionHandler* pc_handler = new PeerConnectionHandler( |
122 client, | 117 client, |
123 this, | 118 this, |
124 dependency_factory_.get()); | 119 dependency_factory_.get()); |
120 if (pc_handler) { | |
121 peer_connection_handlers_.push_back(pc_handler); | |
122 } else { | |
123 LOG(ERROR) << "Could not create PeerConnection handler"; | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
if this is an oom situation, we more commonly just
scherkus (not reviewing)
2012/03/26 22:04:37
actually chrome's OOM handler will take care of th
Henrik Grunell
2012/03/27 07:22:05
OK, I'll remove the if-else and logging, just put
| |
124 } | |
125 | 125 |
126 return peer_connection_handler_; | 126 return pc_handler; |
127 } | 127 } |
128 | 128 |
129 void MediaStreamImpl::ClosePeerConnection() { | 129 WebKit::WebPeerConnection00Handler* |
130 MediaStreamImpl::CreatePeerConnectionHandlerJsep( | |
131 WebKit::WebPeerConnection00HandlerClient* client) { | |
130 DCHECK(CalledOnValidThread()); | 132 DCHECK(CalledOnValidThread()); |
131 video_renderer_ = NULL; | 133 if (!EnsurePeerConnectionFactory()) |
132 peer_connection_handler_ = NULL; | 134 return NULL; |
133 // TODO(grunell): This is a temporary workaround for an error in native | 135 |
134 // PeerConnection where added live tracks are not seen on the remote side. | 136 PeerConnectionHandlerJsep* pc_handler = new PeerConnectionHandlerJsep( |
135 MediaStreamTrackPtrMap::const_iterator it = local_tracks_.begin(); | 137 client, |
136 for (; it != local_tracks_.end(); ++it) | 138 this, |
137 it->second->set_state(webrtc::MediaStreamTrackInterface::kEnded); | 139 dependency_factory_.get()); |
140 if (pc_handler) { | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
same here
Henrik Grunell
2012/03/27 07:22:05
Same as above.
| |
141 peer_connection_handlers_.push_back(pc_handler); | |
142 } else { | |
143 LOG(ERROR) << "Could not create PeerConnection handler"; | |
144 } | |
145 | |
146 return pc_handler; | |
147 } | |
148 | |
149 void MediaStreamImpl::ClosePeerConnection( | |
150 PeerConnectionHandlerBase* pc_handler) { | |
151 DCHECK(CalledOnValidThread()); | |
152 VideoRendererMap::iterator vr_it = video_renderers_.begin(); | |
153 while (vr_it != video_renderers_.end()) { | |
154 if (vr_it->second.second == pc_handler) { | |
155 video_renderers_.erase(vr_it++); | |
tommi (sloooow) - chröme
2012/03/26 12:34:45
ah, I see now that you're using the temporary from
Henrik Grunell
2012/03/27 07:22:05
It's a map, it doesn't have an iterator return val
| |
156 } else { | |
157 ++vr_it; | |
158 } | |
159 } | |
160 peer_connection_handlers_.remove(pc_handler); | |
138 } | 161 } |
139 | 162 |
140 webrtc::MediaStreamTrackInterface* MediaStreamImpl::GetLocalMediaStreamTrack( | 163 webrtc::MediaStreamTrackInterface* MediaStreamImpl::GetLocalMediaStreamTrack( |
141 const std::string& label) { | 164 const std::string& label) { |
142 DCHECK(CalledOnValidThread()); | 165 DCHECK(CalledOnValidThread()); |
143 MediaStreamTrackPtrMap::iterator it = local_tracks_.find(label); | 166 MediaStreamTrackPtrMap::iterator it = local_tracks_.find(label); |
144 if (it == local_tracks_.end()) | 167 if (it == local_tracks_.end()) |
145 return NULL; | 168 return NULL; |
146 MediaStreamTrackPtr stream = it->second; | 169 MediaStreamTrackPtr stream = it->second; |
147 return stream.get(); | 170 return stream.get(); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 capability.expected_capture_delay = 0; | 262 capability.expected_capture_delay = 0; |
240 capability.raw_type = media::VideoFrame::I420; | 263 capability.raw_type = media::VideoFrame::I420; |
241 capability.interlaced = false; | 264 capability.interlaced = false; |
242 decoder = new CaptureVideoDecoder( | 265 decoder = new CaptureVideoDecoder( |
243 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), | 266 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), |
244 video_session_id, | 267 video_session_id, |
245 vc_manager_.get(), | 268 vc_manager_.get(), |
246 capability); | 269 capability); |
247 } else { | 270 } else { |
248 // It's a remote stream. | 271 // It's a remote stream. |
249 if (!video_renderer_.get()) | 272 std::string desc_label = UTF16ToUTF8(descriptor.label()); |
250 video_renderer_ = new talk_base::RefCountedObject<VideoRendererWrapper>(); | 273 PeerConnectionHandlerBase* pc_handler = NULL; |
251 if (video_renderer_->renderer()) { | 274 std::list<PeerConnectionHandlerBase*>::iterator it; |
252 // The renderer is used by PeerConnection, release it first. | 275 for (it = peer_connection_handlers_.begin(); |
253 if (peer_connection_handler_) { | 276 it != peer_connection_handlers_.end(); ++it) { |
254 peer_connection_handler_->SetVideoRenderer( | 277 if ((*it)->HasStream(desc_label)) { |
255 UTF16ToUTF8(descriptor.label()), | 278 pc_handler = *it; |
256 NULL); | 279 break; |
257 } | 280 } |
258 video_renderer_->SetVideoDecoder(NULL); | |
259 } | 281 } |
282 DCHECK(it != peer_connection_handlers_.end()); | |
283 // TODO(grunell): We are not informed when a renderer should be deleted. | |
284 // When this has been fixed, ensure we delete it. For now, we hold on | |
285 // to all renderers until a PeerConnectionHandler is closed or we are | |
286 // deleted (then all renderers are deleted), so it sort of leaks. | |
287 // TODO(grunell): There is no support for multiple decoders per stream, this | |
288 // code will need to be updated when that is supported. | |
289 talk_base::scoped_refptr<VideoRendererWrapper> video_renderer = | |
290 new talk_base::RefCountedObject<VideoRendererWrapper>(); | |
260 RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder( | 291 RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder( |
261 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), | 292 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), |
262 url.spec()); | 293 url.spec()); |
263 decoder = rtc_video_decoder; | 294 decoder = rtc_video_decoder; |
264 video_renderer_->SetVideoDecoder(rtc_video_decoder); | 295 video_renderer->SetVideoDecoder(rtc_video_decoder); |
265 if (peer_connection_handler_) { | 296 pc_handler->SetVideoRenderer(desc_label, video_renderer); |
266 peer_connection_handler_->SetVideoRenderer( | 297 video_renderers_.erase(desc_label); // Remove old renderer if exists. |
267 UTF16ToUTF8(descriptor.label()), | 298 video_renderers_.insert( |
268 video_renderer_); | 299 std::make_pair(desc_label, std::make_pair(video_renderer, pc_handler))); |
269 } | |
270 } | 300 } |
271 return decoder; | 301 return decoder; |
272 } | 302 } |
273 | 303 |
274 void MediaStreamImpl::OnStreamGenerated( | 304 void MediaStreamImpl::OnStreamGenerated( |
275 int request_id, | 305 int request_id, |
276 const std::string& label, | 306 const std::string& label, |
277 const media_stream::StreamDeviceInfoArray& audio_array, | 307 const media_stream::StreamDeviceInfoArray& audio_array, |
278 const media_stream::StreamDeviceInfoArray& video_array) { | 308 const media_stream::StreamDeviceInfoArray& video_array) { |
279 DCHECK(CalledOnValidThread()); | 309 DCHECK(CalledOnValidThread()); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 } | 514 } |
485 | 515 |
486 MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper() {} | 516 MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper() {} |
487 | 517 |
488 MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() {} | 518 MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() {} |
489 | 519 |
490 void MediaStreamImpl::VideoRendererWrapper::SetVideoDecoder( | 520 void MediaStreamImpl::VideoRendererWrapper::SetVideoDecoder( |
491 RTCVideoDecoder* decoder) { | 521 RTCVideoDecoder* decoder) { |
492 rtc_video_decoder_ = decoder; | 522 rtc_video_decoder_ = decoder; |
493 } | 523 } |
OLD | NEW |