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

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: Added comment 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 // WebRtcVideoTrackAdapter can be destroyed on the main render thread or
39 // libjingles worker thread since it posts video frames on that thread. But
40 // |video_source_| must be released on the main render thread before the
41 // PeerConnectionFactory has been destroyed. The only way to ensure that is
42 // to make sure |video_source_| is released when WebRtcVideoTrackAdapter() is
43 // destroyed.
44 void ReleaseSourceOnMainThread();
45
43 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, 46 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
44 const media::VideoCaptureFormat& format); 47 const media::VideoCaptureFormat& format);
45 48
46 private: 49 private:
47 void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame, 50 void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame,
48 const media::VideoCaptureFormat& format); 51 const media::VideoCaptureFormat& format);
49 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>; 52 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
50 virtual ~WebRtcVideoSourceAdapter(); 53 virtual ~WebRtcVideoSourceAdapter();
51 54
52 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_; 55 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_;
53 56
57 // |render_thread_checker_| is bound to the main render thread.
58 base::ThreadChecker render_thread_checker_;
54 // Used to DCHECK that frames are called on the IO-thread. 59 // Used to DCHECK that frames are called on the IO-thread.
55 base::ThreadChecker io_thread_checker_; 60 base::ThreadChecker io_thread_checker_;
56 61
57 // Used for posting frames to libjingle's worker thread. Accessed on the 62 // Used for posting frames to libjingle's worker thread. Accessed on the
58 // IO-thread. 63 // IO-thread.
59 scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_; 64 scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_;
60 65
61 scoped_refptr<webrtc::VideoSourceInterface> video_source_; 66 scoped_refptr<webrtc::VideoSourceInterface> video_source_;
67
68 // Used to protect |capture_adapter_|. It is taken by libjingle's worker
69 // thread for each video frame that is delivered but only taken on the
70 // main render thread in ReleaseSourceOnMainThread() when
71 // the owning WebRtcVideoTrackAdapter is being destroyed.
72 base::Lock capture_adapter_stop_lock_;
62 // |capture_adapter_| is owned by |video_source_| 73 // |capture_adapter_| is owned by |video_source_|
63 WebRtcVideoCapturerAdapter* capture_adapter_; 74 WebRtcVideoCapturerAdapter* capture_adapter_;
64 }; 75 };
65 76
66 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( 77 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
67 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread, 78 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
68 const scoped_refptr<webrtc::VideoSourceInterface>& source, 79 const scoped_refptr<webrtc::VideoSourceInterface>& source,
69 WebRtcVideoCapturerAdapter* capture_adapter) 80 WebRtcVideoCapturerAdapter* capture_adapter)
70 : render_thread_message_loop_(base::MessageLoopProxy::current()), 81 : render_thread_message_loop_(base::MessageLoopProxy::current()),
71 libjingle_worker_thread_(libjingle_worker_thread), 82 libjingle_worker_thread_(libjingle_worker_thread),
72 video_source_(source), 83 video_source_(source),
73 capture_adapter_(capture_adapter) { 84 capture_adapter_(capture_adapter) {
74 io_thread_checker_.DetachFromThread(); 85 io_thread_checker_.DetachFromThread();
75 } 86 }
76 87
77 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() { 88 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
89 DVLOG(3) << "~WebRtcVideoSourceAdapter()";
90 DCHECK(!capture_adapter_);
91 // This object can be destroyed on the main render thread or libjingles
92 // worker thread since it posts video frames on that thread. But
93 // |video_source_| must be released on the main render thread before the
94 // PeerConnectionFactory has been destroyed. The only way to ensure that is
95 // to make sure |video_source_| is released when WebRtcVideoTrackAdapter() is
96 // destroyed.
97 }
98
99 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::
100 ReleaseSourceOnMainThread() {
101 DCHECK(render_thread_checker_.CalledOnValidThread());
78 // Since frames are posted to the worker thread, this object might be deleted 102 // 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 103 // on that thread. However, since |video_source_| was created on the render
80 // thread, it should be released on the render thread. 104 // thread, it should be released on the render thread.
81 if (!render_thread_message_loop_->BelongsToCurrentThread()) { 105 base::AutoLock auto_lock(capture_adapter_stop_lock_);
82 webrtc::VideoSourceInterface* source = video_source_.get(); 106 // |video_source| owns |capture_adapter_|.
83 source->AddRef(); 107 capture_adapter_ = NULL;
84 video_source_ = NULL; 108 video_source_ = NULL;
85 render_thread_message_loop_->PostTask(
86 FROM_HERE,
87 base::Bind(&ReleaseWebRtcSourceOnMainRenderThread,
88 base::Unretained(source)));
89 }
90 } 109 }
91 110
92 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( 111 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
93 const scoped_refptr<media::VideoFrame>& frame, 112 const scoped_refptr<media::VideoFrame>& frame,
94 const media::VideoCaptureFormat& format) { 113 const media::VideoCaptureFormat& format) {
95 DCHECK(io_thread_checker_.CalledOnValidThread()); 114 DCHECK(io_thread_checker_.CalledOnValidThread());
96 libjingle_worker_thread_->PostTask( 115 libjingle_worker_thread_->PostTask(
97 FROM_HERE, 116 FROM_HERE,
98 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread, 117 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread,
99 this, frame, format)); 118 this, frame, format));
100 } 119 }
101 120
102 void 121 void
103 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread( 122 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread(
104 const scoped_refptr<media::VideoFrame>& frame, 123 const scoped_refptr<media::VideoFrame>& frame,
105 const media::VideoCaptureFormat& format) { 124 const media::VideoCaptureFormat& format) {
106 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread()); 125 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread());
107 capture_adapter_->OnFrameCaptured(frame); 126 base::AutoLock auto_lock(capture_adapter_stop_lock_);
127 if (capture_adapter_)
128 capture_adapter_->OnFrameCaptured(frame);
108 } 129 }
109 130
110 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter( 131 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
111 const blink::WebMediaStreamTrack& track, 132 const blink::WebMediaStreamTrack& track,
112 PeerConnectionDependencyFactory* factory) 133 PeerConnectionDependencyFactory* factory)
113 : web_track_(track) { 134 : web_track_(track) {
114 const blink::WebMediaConstraints& constraints = 135 const blink::WebMediaConstraints& constraints =
115 MediaStreamVideoTrack::GetVideoTrack(track)->constraints(); 136 MediaStreamVideoTrack::GetVideoTrack(track)->constraints();
116 137
117 bool is_screencast = ConstraintKeyExists( 138 bool is_screencast = ConstraintKeyExists(
(...skipping 23 matching lines...) Expand all
141 web_track_); 162 web_track_);
142 163
143 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast " 164 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast "
144 << is_screencast; 165 << is_screencast;
145 } 166 }
146 167
147 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() { 168 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() {
148 DCHECK(thread_checker_.CalledOnValidThread()); 169 DCHECK(thread_checker_.CalledOnValidThread());
149 DVLOG(3) << "WebRtcVideoTrackAdapter dtor()."; 170 DVLOG(3) << "WebRtcVideoTrackAdapter dtor().";
150 RemoveFromVideoTrack(this, web_track_); 171 RemoveFromVideoTrack(this, web_track_);
172 source_adapter_->ReleaseSourceOnMainThread();
151 } 173 }
152 174
153 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) { 175 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) {
154 DCHECK(thread_checker_.CalledOnValidThread()); 176 DCHECK(thread_checker_.CalledOnValidThread());
155 video_track_->set_enabled(enabled); 177 video_track_->set_enabled(enabled);
156 } 178 }
157 179
158 } // namespace content 180 } // 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