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

Side by Side Diff: content/renderer/media/webrtc/webrtc_video_track_adapter.cc

Issue 299313011: Make sure webrtc::VideoSource is released when WebRtcVideoTrackAdapter is destroyed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/webrtc/webrtc_video_track_adapter.h" 5 #include "content/renderer/media/webrtc/webrtc_video_track_adapter.h"
6 6
7 #include "base/strings/utf_string_conversions.h" 7 #include "base/strings/utf_string_conversions.h"
8 #include "base/synchronization/lock.h"
8 #include "content/common/media/media_stream_options.h" 9 #include "content/common/media/media_stream_options.h"
9 #include "content/renderer/media/media_stream_video_source.h" 10 #include "content/renderer/media/media_stream_video_source.h"
10 #include "content/renderer/media/media_stream_video_track.h" 11 #include "content/renderer/media/media_stream_video_track.h"
11 12
12 namespace { 13 namespace {
13 14
14 bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints, 15 bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints,
15 const blink::WebString& name) { 16 const blink::WebString& name) {
16 blink::WebString value_str; 17 blink::WebString value_str;
17 return constraints.getMandatoryConstraintValue(name, value_str) || 18 return constraints.getMandatoryConstraintValue(name, value_str) ||
18 constraints.getOptionalConstraintValue(name, value_str); 19 constraints.getOptionalConstraintValue(name, value_str);
19 } 20 }
20 21
21 // Used to make sure |source| is released on the main render thread.
22 void ReleaseWebRtcSourceOnMainRenderThread(
23 webrtc::VideoSourceInterface* source) {
24 source->Release();
25 }
26
27 } // anonymouse namespace 22 } // anonymouse namespace
28 23
29 namespace content { 24 namespace content {
30 25
31 // Simple help class used for receiving video frames on the IO-thread from 26 // Simple help class used for receiving video frames on the IO-thread from
32 // a MediaStreamVideoTrack and forward the frames to a 27 // a MediaStreamVideoTrack and forward the frames to a
33 // WebRtcVideoCapturerAdapter on libjingle's worker thread. 28 // WebRtcVideoCapturerAdapter on libjingle's worker thread.
34 // WebRtcVideoCapturerAdapter implements a video capturer for libjingle. 29 // WebRtcVideoCapturerAdapter implements a video capturer for libjingle.
35 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter 30 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
36 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> { 31 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
37 public: 32 public:
38 WebRtcVideoSourceAdapter( 33 WebRtcVideoSourceAdapter(
39 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread, 34 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
40 const scoped_refptr<webrtc::VideoSourceInterface>& source, 35 const scoped_refptr<webrtc::VideoSourceInterface>& source,
41 WebRtcVideoCapturerAdapter* capture_adapter); 36 WebRtcVideoCapturerAdapter* capture_adapter);
42 37
38 void ReleaseSourceOnMainThread();
tommi (sloooow) - chröme 2014/05/30 11:15:22 Can you add some notes on why this is needed?
perkj_chrome 2014/05/30 12:16:33 Done.
39
43 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, 40 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
44 const media::VideoCaptureFormat& format); 41 const media::VideoCaptureFormat& format);
45 42
46 private: 43 private:
47 void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame, 44 void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame,
48 const media::VideoCaptureFormat& format); 45 const media::VideoCaptureFormat& format);
49 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>; 46 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
50 virtual ~WebRtcVideoSourceAdapter(); 47 virtual ~WebRtcVideoSourceAdapter();
51 48
52 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_; 49 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_;
53 50
51 // |render_thread_checker_| is bound to the main render thread.
52 base::ThreadChecker render_thread_checker_;
54 // Used to DCHECK that frames are called on the IO-thread. 53 // Used to DCHECK that frames are called on the IO-thread.
55 base::ThreadChecker io_thread_checker_; 54 base::ThreadChecker io_thread_checker_;
56 55
57 // Used for posting frames to libjingle's worker thread. Accessed on the 56 // Used for posting frames to libjingle's worker thread. Accessed on the
58 // IO-thread. 57 // IO-thread.
59 scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_; 58 scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_;
60 59
61 scoped_refptr<webrtc::VideoSourceInterface> video_source_; 60 scoped_refptr<webrtc::VideoSourceInterface> video_source_;
61
62 // Used to protect |capture_adapter_|. It is taken by libjingle's worker
63 // thread for each video frame that is delivered but only taken on the
64 // main render thread in ReleaseSourceOnMainThread() when
65 // the owning WebRtcVideoTrackAdapter is being destroyed.
66 base::Lock capture_adapter_stop_lock_;
62 // |capture_adapter_| is owned by |video_source_| 67 // |capture_adapter_| is owned by |video_source_|
63 WebRtcVideoCapturerAdapter* capture_adapter_; 68 WebRtcVideoCapturerAdapter* capture_adapter_;
64 }; 69 };
65 70
66 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( 71 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
67 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread, 72 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
68 const scoped_refptr<webrtc::VideoSourceInterface>& source, 73 const scoped_refptr<webrtc::VideoSourceInterface>& source,
69 WebRtcVideoCapturerAdapter* capture_adapter) 74 WebRtcVideoCapturerAdapter* capture_adapter)
70 : render_thread_message_loop_(base::MessageLoopProxy::current()), 75 : render_thread_message_loop_(base::MessageLoopProxy::current()),
71 libjingle_worker_thread_(libjingle_worker_thread), 76 libjingle_worker_thread_(libjingle_worker_thread),
72 video_source_(source), 77 video_source_(source),
73 capture_adapter_(capture_adapter) { 78 capture_adapter_(capture_adapter) {
74 io_thread_checker_.DetachFromThread(); 79 io_thread_checker_.DetachFromThread();
75 } 80 }
76 81
77 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() { 82 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
83 DVLOG(3) << "~WebRtcVideoSourceAdapter()";
84 DCHECK(!capture_adapter_);
85 // This object can be destroyed on the main render thread or libjingles
86 // worker thread since it posts video frames on that thread. But
87 // |video_source_| must be released on the main render thread before the
88 // PeerConnectionFactory has been destroyed. The only way to ensure that is
89 // to make sure |video_source_| is released when WebRtcVideoTrackAdapter() is
90 // destroyed.
91 }
92
93 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::
94 ReleaseSourceOnMainThread() {
95 DCHECK(render_thread_checker_.CalledOnValidThread());
78 // Since frames are posted to the worker thread, this object might be deleted 96 // Since frames are posted to the worker thread, this object might be deleted
79 // on that thread. However, since |video_source_| was created on the render 97 // on that thread. However, since |video_source_| was created on the render
80 // thread, it should be released on the render thread. 98 // thread, it should be released on the render thread.
81 if (!render_thread_message_loop_->BelongsToCurrentThread()) { 99 base::AutoLock auto_lock(capture_adapter_stop_lock_);
82 webrtc::VideoSourceInterface* source = video_source_.get(); 100 // |video_source| owns |capture_adapter_|.
83 source->AddRef(); 101 capture_adapter_ = NULL;
84 video_source_ = NULL; 102 video_source_ = NULL;
85 render_thread_message_loop_->PostTask(
86 FROM_HERE,
87 base::Bind(&ReleaseWebRtcSourceOnMainRenderThread,
88 base::Unretained(source)));
89 }
90 } 103 }
91 104
92 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( 105 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
93 const scoped_refptr<media::VideoFrame>& frame, 106 const scoped_refptr<media::VideoFrame>& frame,
94 const media::VideoCaptureFormat& format) { 107 const media::VideoCaptureFormat& format) {
95 DCHECK(io_thread_checker_.CalledOnValidThread()); 108 DCHECK(io_thread_checker_.CalledOnValidThread());
96 libjingle_worker_thread_->PostTask( 109 libjingle_worker_thread_->PostTask(
97 FROM_HERE, 110 FROM_HERE,
98 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread, 111 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread,
99 this, frame, format)); 112 this, frame, format));
100 } 113 }
101 114
102 void 115 void
103 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread( 116 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread(
104 const scoped_refptr<media::VideoFrame>& frame, 117 const scoped_refptr<media::VideoFrame>& frame,
105 const media::VideoCaptureFormat& format) { 118 const media::VideoCaptureFormat& format) {
106 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread()); 119 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread());
107 capture_adapter_->OnFrameCaptured(frame); 120 base::AutoLock auto_lock(capture_adapter_stop_lock_);
121 if (capture_adapter_)
122 capture_adapter_->OnFrameCaptured(frame);
108 } 123 }
109 124
110 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter( 125 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
111 const blink::WebMediaStreamTrack& track, 126 const blink::WebMediaStreamTrack& track,
112 PeerConnectionDependencyFactory* factory) 127 PeerConnectionDependencyFactory* factory)
113 : web_track_(track) { 128 : web_track_(track) {
114 const blink::WebMediaConstraints& constraints = 129 const blink::WebMediaConstraints& constraints =
115 MediaStreamVideoTrack::GetVideoTrack(track)->constraints(); 130 MediaStreamVideoTrack::GetVideoTrack(track)->constraints();
116 131
117 bool is_screencast = ConstraintKeyExists( 132 bool is_screencast = ConstraintKeyExists(
(...skipping 23 matching lines...) Expand all
141 web_track_); 156 web_track_);
142 157
143 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast " 158 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast "
144 << is_screencast; 159 << is_screencast;
145 } 160 }
146 161
147 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() { 162 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() {
148 DCHECK(thread_checker_.CalledOnValidThread()); 163 DCHECK(thread_checker_.CalledOnValidThread());
149 DVLOG(3) << "WebRtcVideoTrackAdapter dtor()."; 164 DVLOG(3) << "WebRtcVideoTrackAdapter dtor().";
150 RemoveFromVideoTrack(this, web_track_); 165 RemoveFromVideoTrack(this, web_track_);
166 source_adapter_->ReleaseSourceOnMainThread();
151 } 167 }
152 168
153 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) { 169 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) {
154 DCHECK(thread_checker_.CalledOnValidThread()); 170 DCHECK(thread_checker_.CalledOnValidThread());
155 video_track_->set_enabled(enabled); 171 video_track_->set_enabled(enabled);
156 } 172 }
157 173
158 } // namespace content 174 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698