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

Unified Diff: content/renderer/media/media_stream_impl.cc

Issue 9543001: Support for multiple PeerConnections (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 10 months 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/media_stream_impl.cc
diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
index 76e3384a307e546c67d2066634b4f4c2a9765862..39d6bc8e3574a3c134ab99d613481e42bf6a748b 100644
--- a/content/renderer/media/media_stream_impl.cc
+++ b/content/renderer/media/media_stream_impl.cc
@@ -80,15 +80,13 @@ MediaStreamImpl::MediaStreamImpl(
p2p_socket_dispatcher_(p2p_socket_dispatcher),
network_manager_(NULL),
vc_manager_(vc_manager),
- peer_connection_handler_(NULL),
- message_loop_proxy_(base::MessageLoopProxy::current()),
signaling_thread_(NULL),
worker_thread_(NULL),
chrome_worker_thread_("Chrome_libJingle_WorkerThread") {
}
MediaStreamImpl::~MediaStreamImpl() {
- DCHECK(!peer_connection_handler_);
+ DCHECK(peer_connection_handlers_.empty());
if (dependency_factory_.get())
dependency_factory_->ReleasePeerConnectionFactory();
if (network_manager_) {
@@ -111,30 +109,39 @@ MediaStreamImpl::~MediaStreamImpl() {
WebKit::WebPeerConnectionHandler* MediaStreamImpl::CreatePeerConnectionHandler(
WebKit::WebPeerConnectionHandlerClient* client) {
DCHECK(CalledOnValidThread());
- if (peer_connection_handler_) {
- DVLOG(1) << "A PeerConnection already exists";
- return NULL;
- }
if (!EnsurePeerConnectionFactory())
return NULL;
- peer_connection_handler_ = new PeerConnectionHandler(
+ PeerConnectionHandler* pc_handler = new PeerConnectionHandler(
client,
this,
dependency_factory_.get());
+ peer_connection_handlers_.push_back(pc_handler);
tommi (sloooow) - chröme 2012/02/29 13:37:00 maybe we should put a CHECK(pc_handler) here first
Henrik Grunell 2012/03/23 12:51:56 Crashing is not necessary at all actually. We won'
- return peer_connection_handler_;
+ return pc_handler;
}
-void MediaStreamImpl::ClosePeerConnection() {
+void MediaStreamImpl::ClosePeerConnection(PeerConnectionHandler* pc_handler) {
DCHECK(CalledOnValidThread());
- video_renderer_ = NULL;
- peer_connection_handler_ = NULL;
+ VideoRendererMap::iterator vr_it = video_renderers_.begin();
+ while (vr_it != video_renderers_.end()) {
+ if (vr_it->second.second == pc_handler) {
+ video_renderers_.erase(vr_it++);
tommi (sloooow) - chröme 2012/02/29 13:37:00 hmm... is it safe to continue using the iterator a
Henrik Grunell 2012/03/23 12:51:56 It is safe; post increment will be evaluated befor
+ } else {
+ ++vr_it;
+ }
+ }
+ peer_connection_handlers_.remove(pc_handler);
// TODO(grunell): This is a temporary workaround for an error in native
// PeerConnection where added live tracks are not seen on the remote side.
- MediaStreamTrackPtrMap::const_iterator it = local_tracks_.begin();
- for (; it != local_tracks_.end(); ++it)
+ // If several PeerConnections are used, the tracks will be ended when the
+ // first PeerConnection is closed, which is an issue. The alternative (skip
+ // this workaround) would mean that only one call could be made properly.
+ // When JSEP support is added this will be fixed in native PeerConnection.
+ for (MediaStreamTrackPtrMap::const_iterator it = local_tracks_.begin();
+ it != local_tracks_.end(); ++it) {
it->second->set_state(webrtc::MediaStreamTrackInterface::kEnded);
+ }
}
webrtc::MediaStreamTrackInterface* MediaStreamImpl::GetLocalMediaStreamTrack(
@@ -246,27 +253,35 @@ scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder(
capability);
} else {
// It's a remote stream.
- if (!video_renderer_.get())
- video_renderer_ = new talk_base::RefCountedObject<VideoRendererWrapper>();
- if (video_renderer_->renderer()) {
- // The renderer is used by PeerConnection, release it first.
- if (peer_connection_handler_) {
- peer_connection_handler_->SetVideoRenderer(
- UTF16ToUTF8(descriptor.label()),
- NULL);
+ std::string desc_label = UTF16ToUTF8(descriptor.label());
+ PeerConnectionHandler* pc_handler = NULL;
+ std::list<PeerConnectionHandler*>::iterator it;
+ for (it = peer_connection_handlers_.begin();
+ it != peer_connection_handlers_.end(); ++it) {
+ if ((*it)->HasStream(desc_label)) {
+ pc_handler = *it;
+ break;
}
- video_renderer_->SetVideoDecoder(NULL);
}
+ // TODO(grunell): We are not informed when a renderer should be deleted.
tommi (sloooow) - chröme 2012/02/29 13:37:00 after the for loop, what about adding: DCHECK_NE(i
Henrik Grunell 2012/03/23 12:51:56 We can't assume that. See comment below.
+ // When this has been fixed, ensure we delete it. For now, we hold on
+ // to all renderers until a PeerConnectionHandler is closed or we are
+ // deleted (then all renderers are deleted), so it sort of leaks.
+ // TODO(grunell): There is no support for multiple renderers per stream in
+ // native PeerConnection, this code may need to be updated when that is
+ // supported.
+ talk_base::scoped_refptr<VideoRendererWrapper> video_renderer =
+ new talk_base::RefCountedObject<VideoRendererWrapper>();
RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder(
message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"),
url.spec());
decoder = rtc_video_decoder;
- video_renderer_->SetVideoDecoder(rtc_video_decoder);
- if (peer_connection_handler_) {
- peer_connection_handler_->SetVideoRenderer(
- UTF16ToUTF8(descriptor.label()),
- video_renderer_);
- }
+ video_renderer->SetVideoDecoder(rtc_video_decoder);
+ if (pc_handler)
tommi (sloooow) - chröme 2012/02/29 13:37:00 in what situation will pc_handler be NULL?
Henrik Grunell 2012/03/23 12:51:56 It can be if a PeerConnection is closed and the js
Henrik Grunell 2012/03/26 05:04:26 Verified OK to return null ptr.
+ pc_handler->SetVideoRenderer(desc_label, video_renderer);
+ video_renderers_.erase(desc_label); // Remove old renderer if exists.
tommi (sloooow) - chröme 2012/02/29 13:37:00 is it conceivable that more than one renderer can
Henrik Grunell 2012/03/23 12:51:56 At the moment no, there shall be zero or one rende
+ video_renderers_.insert(
+ std::make_pair(desc_label, std::make_pair(video_renderer, pc_handler)));
}
return decoder;
}

Powered by Google App Engine
This is Rietveld 408576698