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

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

Issue 2356663002: Implement and use VideoTrackSource directly. (Closed)
Patch Set: avoid instantiating PeerConnection in tests Created 4 years, 3 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
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/media_stream_video_webrtc_sink.h" 5 #include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h"
6 6
7 #include "base/location.h" 7 #include "base/location.h"
8 #include "base/numerics/safe_conversions.h" 8 #include "base/numerics/safe_conversions.h"
9 #include "base/single_thread_task_runner.h" 9 #include "base/single_thread_task_runner.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "base/synchronization/lock.h" 11 #include "base/synchronization/lock.h"
12 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
13 #include "base/timer/timer.h" 13 #include "base/timer/timer.h"
14 #include "content/common/media/media_stream_options.h" 14 #include "content/common/media/media_stream_options.h"
15 #include "content/public/renderer/media_stream_utils.h" 15 #include "content/public/renderer/media_stream_utils.h"
16 #include "content/renderer/media/media_stream_constraints_util.h" 16 #include "content/renderer/media/media_stream_constraints_util.h"
17 #include "content/renderer/media/media_stream_video_track.h" 17 #include "content/renderer/media/media_stream_video_track.h"
18 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" 18 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
19 #include "media/base/limits.h" 19 #include "media/base/limits.h"
20 #include "third_party/webrtc/api/videosourceproxy.h"
21 #include "third_party/webrtc/api/videotracksource.h"
20 22
21 namespace content { 23 namespace content {
22 24
25 class MediaStreamVideoWebRtcSink::WebRtcVideoSource
26 : public webrtc::VideoTrackSource {
27 public:
28 WebRtcVideoSource(WebRtcVideoCapturerAdapter* capture_adapter,
29 bool is_screencast,
30 rtc::Optional<bool> needs_denoising)
31 : VideoTrackSource(capture_adapter, false),
32 capture_adapter_(capture_adapter),
33 is_screencast_(is_screencast),
34 needs_denoising_(needs_denoising) {}
35
36 WebRtcVideoCapturerAdapter* capture_adapter() const {
37 return capture_adapter_.get();
38 }
39
40 bool is_screencast() const override { return is_screencast_; }
41 rtc::Optional<bool> needs_denoising() const override {
42 return needs_denoising_;
hta - Chromium 2016/09/20 16:33:43 Can we get the API in place to change needs_denois
pbos 2016/09/20 17:13:47 I'll defer that because it affects threading, as t
43 }
44
45 private:
46 std::unique_ptr<WebRtcVideoCapturerAdapter> const capture_adapter_;
47 const bool is_screencast_;
48 const rtc::Optional<bool> needs_denoising_;
49 };
50
23 namespace { 51 namespace {
24 52
25 // The default number of microseconds that should elapse since the last video 53 // The default number of microseconds that should elapse since the last video
26 // frame was received, before requesting a refresh frame. 54 // frame was received, before requesting a refresh frame.
27 const int64_t kDefaultRefreshIntervalMicros = 55 const int64_t kDefaultRefreshIntervalMicros =
28 base::Time::kMicrosecondsPerSecond; 56 base::Time::kMicrosecondsPerSecond;
29 57
30 // A lower-bound for the refresh interval. 58 // A lower-bound for the refresh interval.
31 const int64_t kLowerBoundRefreshIntervalMicros = 59 const int64_t kLowerBoundRefreshIntervalMicros =
32 base::Time::kMicrosecondsPerSecond / media::limits::kMaxFramesPerSecond; 60 base::Time::kMicrosecondsPerSecond / media::limits::kMaxFramesPerSecond;
33 61
34 } // namespace 62 } // namespace
35 63
36 // Simple help class used for receiving video frames on the IO-thread from a 64 // Simple help class used for receiving video frames on the IO-thread from a
37 // MediaStreamVideoTrack and forward the frames to a WebRtcVideoCapturerAdapter 65 // MediaStreamVideoTrack and forward the frames to a WebRtcVideoCapturerAdapter
38 // on libjingle's worker thread. WebRtcVideoCapturerAdapter implements a video 66 // on libjingle's worker thread. WebRtcVideoCapturerAdapter implements a video
39 // capturer for libjingle. 67 // capturer for libjingle.
40 class MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter 68 class MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter
41 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> { 69 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
42 public: 70 public:
43 WebRtcVideoSourceAdapter( 71 WebRtcVideoSourceAdapter(const scoped_refptr<base::SingleThreadTaskRunner>&
44 const scoped_refptr<base::SingleThreadTaskRunner>& 72 libjingle_worker_thread,
45 libjingle_worker_thread, 73 const scoped_refptr<WebRtcVideoSource>& source,
46 const scoped_refptr<webrtc::VideoTrackSourceInterface>& source, 74 base::TimeDelta refresh_interval,
47 WebRtcVideoCapturerAdapter* capture_adapter, 75 const base::Closure& refresh_callback);
48 base::TimeDelta refresh_interval,
49 const base::Closure& refresh_callback);
50 76
51 // MediaStreamVideoWebRtcSink can be destroyed on the main render thread or 77 // MediaStreamVideoWebRtcSink can be destroyed on the main render thread or
52 // libjingles worker thread since it posts video frames on that thread. But 78 // libjingles worker thread since it posts video frames on that thread. But
53 // |video_source_| must be released on the main render thread before the 79 // |video_source_| must be released on the main render thread before the
54 // PeerConnectionFactory has been destroyed. The only way to ensure that is to 80 // PeerConnectionFactory has been destroyed. The only way to ensure that is to
55 // make sure |video_source_| is released when MediaStreamVideoWebRtcSink() is 81 // make sure |video_source_| is released when MediaStreamVideoWebRtcSink() is
56 // destroyed. 82 // destroyed.
57 void ReleaseSourceOnMainThread(); 83 void ReleaseSourceOnMainThread();
58 84
59 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, 85 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 // remote clients that join a distributed session receive a first video frame 127 // remote clients that join a distributed session receive a first video frame
102 // in a timely manner. Second, it will allow WebRTC's internal bandwidth 128 // in a timely manner. Second, it will allow WebRTC's internal bandwidth
103 // estimation logic to maintain a more optimal state, since sending a video 129 // estimation logic to maintain a more optimal state, since sending a video
104 // frame will "prime it." Third, it allows lossy encoders to clean up 130 // frame will "prime it." Third, it allows lossy encoders to clean up
105 // artifacts in a still image. http://crbug.com/486274 131 // artifacts in a still image. http://crbug.com/486274
106 base::RepeatingTimer refresh_timer_; 132 base::RepeatingTimer refresh_timer_;
107 }; 133 };
108 134
109 MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( 135 MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
110 const scoped_refptr<base::SingleThreadTaskRunner>& libjingle_worker_thread, 136 const scoped_refptr<base::SingleThreadTaskRunner>& libjingle_worker_thread,
111 const scoped_refptr<webrtc::VideoTrackSourceInterface>& source, 137 const scoped_refptr<WebRtcVideoSource>& source,
112 WebRtcVideoCapturerAdapter* capture_adapter,
113 base::TimeDelta refresh_interval, 138 base::TimeDelta refresh_interval,
114 const base::Closure& refresh_callback) 139 const base::Closure& refresh_callback)
115 : render_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()), 140 : render_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
116 libjingle_worker_thread_(libjingle_worker_thread), 141 libjingle_worker_thread_(libjingle_worker_thread),
117 video_source_(source), 142 video_source_(source),
118 capture_adapter_(capture_adapter) { 143 capture_adapter_(source->capture_adapter()) {
119 io_thread_checker_.DetachFromThread(); 144 io_thread_checker_.DetachFromThread();
120 if (!refresh_interval.is_zero()) { 145 if (!refresh_interval.is_zero()) {
121 VLOG(1) << "Starting frame refresh timer with interval " 146 VLOG(1) << "Starting frame refresh timer with interval "
122 << refresh_interval.InMillisecondsF() << " ms."; 147 << refresh_interval.InMillisecondsF() << " ms.";
123 refresh_timer_.Start(FROM_HERE, refresh_interval, refresh_callback); 148 refresh_timer_.Start(FROM_HERE, refresh_interval, refresh_callback);
124 } 149 }
125 } 150 }
126 151
127 MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter:: 152 MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
128 ~WebRtcVideoSourceAdapter() { 153 ~WebRtcVideoSourceAdapter() {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 : weak_factory_(this) { 208 : weak_factory_(this) {
184 const blink::WebMediaConstraints& constraints = 209 const blink::WebMediaConstraints& constraints =
185 MediaStreamVideoTrack::GetVideoTrack(track)->constraints(); 210 MediaStreamVideoTrack::GetVideoTrack(track)->constraints();
186 211
187 // Check for presence of mediaStreamSource constraint. The value is ignored. 212 // Check for presence of mediaStreamSource constraint. The value is ignored.
188 std::string value; 213 std::string value;
189 bool is_screencast = GetConstraintValueAsString( 214 bool is_screencast = GetConstraintValueAsString(
190 constraints, &blink::WebMediaTrackConstraintSet::mediaStreamSource, 215 constraints, &blink::WebMediaTrackConstraintSet::mediaStreamSource,
191 &value); 216 &value);
192 217
218 // Extract denoising preference, if no value is set this currently falls back
219 // to a codec-specific default inside webrtc, hence the tri-state of {on, off
220 // unset}.
221 rtc::Optional<bool> needs_denoising;
222 bool denoising_value;
223 if (GetConstraintValueAsBoolean(
224 constraints, &blink::WebMediaTrackConstraintSet::googNoiseReduction,
225 &denoising_value)) {
226 needs_denoising = rtc::Optional<bool>(denoising_value);
227 }
228
193 // Enable automatic frame refreshes for the screen capture sources, which will 229 // Enable automatic frame refreshes for the screen capture sources, which will
194 // stop producing frames whenever screen content is not changing. Check the 230 // stop producing frames whenever screen content is not changing. Check the
195 // frameRate constraint to determine the rate of refreshes. If a minimum 231 // frameRate constraint to determine the rate of refreshes. If a minimum
196 // frameRate is provided, use that. Otherwise, use the maximum frameRate if it 232 // frameRate is provided, use that. Otherwise, use the maximum frameRate if it
197 // happens to be less than the default. 233 // happens to be less than the default.
198 base::TimeDelta refresh_interval = base::TimeDelta::FromMicroseconds(0); 234 base::TimeDelta refresh_interval = base::TimeDelta::FromMicroseconds(0);
199 if (is_screencast) { 235 if (is_screencast) {
200 // Start with the default refresh interval, and refine based on constraints. 236 // Start with the default refresh interval, and refine based on constraints.
201 refresh_interval = 237 refresh_interval =
202 base::TimeDelta::FromMicroseconds(kDefaultRefreshIntervalMicros); 238 base::TimeDelta::FromMicroseconds(kDefaultRefreshIntervalMicros);
(...skipping 14 matching lines...) Expand all
217 base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>( 253 base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>(
218 base::Time::kMicrosecondsPerSecond / value)); 254 base::Time::kMicrosecondsPerSecond / value));
219 refresh_interval = std::max(refresh_interval, alternate_refresh_interval); 255 refresh_interval = std::max(refresh_interval, alternate_refresh_interval);
220 } 256 }
221 if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) { 257 if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) {
222 refresh_interval = 258 refresh_interval =
223 base::TimeDelta::FromMicroseconds(kLowerBoundRefreshIntervalMicros); 259 base::TimeDelta::FromMicroseconds(kLowerBoundRefreshIntervalMicros);
224 } 260 }
225 } 261 }
226 262
227 WebRtcVideoCapturerAdapter* capture_adapter = 263 // TODO(pbos): Consolidate WebRtcVideoCapturerAdapter into WebRtcVideoSource
228 factory->CreateVideoCapturer(is_screencast); 264 // by removing the need for and dependency on a circket::VideoCapturer.
hta - Chromium 2016/09/20 16:33:43 spelling: circket -> cricket
pbos 2016/09/20 17:13:47 Done.
265 video_source_ = scoped_refptr<WebRtcVideoSource>(
266 new rtc::RefCountedObject<WebRtcVideoSource>(
267 new WebRtcVideoCapturerAdapter(is_screencast), is_screencast,
268 needs_denoising));
229 269
230 // |video_source| owns |capture_adapter| 270 // TODO(pbos): Consolidate the local video track with the source proxy and
231 scoped_refptr<webrtc::VideoTrackSourceInterface> video_source( 271 // move into PeerConnectionDependencyFactory. This now separately holds on a
232 factory->CreateVideoSource(capture_adapter)); 272 // reference to the proxy object because
233 273 // PeerConnectionFactory::CreateVideoTrack doesn't do reference counting.
274 video_source_proxy_ =
275 factory->CreateVideoTrackSourceProxy(video_source_.get());
234 video_track_ = factory->CreateLocalVideoTrack(track.id().utf8(), 276 video_track_ = factory->CreateLocalVideoTrack(track.id().utf8(),
235 video_source.get()); 277 video_source_proxy_.get());
236 278
237 video_track_->set_enabled(track.isEnabled()); 279 video_track_->set_enabled(track.isEnabled());
238 280
239 source_adapter_ = new WebRtcVideoSourceAdapter( 281 source_adapter_ = new WebRtcVideoSourceAdapter(
240 factory->GetWebRtcWorkerThread(), 282 factory->GetWebRtcWorkerThread(), video_source_.get(), refresh_interval,
241 video_source,
242 capture_adapter,
243 refresh_interval,
244 base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame, 283 base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame,
245 weak_factory_.GetWeakPtr())); 284 weak_factory_.GetWeakPtr()));
246 285
247 MediaStreamVideoSink::ConnectToTrack( 286 MediaStreamVideoSink::ConnectToTrack(
248 track, 287 track,
249 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_), 288 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_),
250 false); 289 false);
251 290
252 DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast " 291 DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast "
253 << is_screencast; 292 << is_screencast;
(...skipping 11 matching lines...) Expand all
265 DCHECK(thread_checker_.CalledOnValidThread()); 304 DCHECK(thread_checker_.CalledOnValidThread());
266 video_track_->set_enabled(enabled); 305 video_track_->set_enabled(enabled);
267 } 306 }
268 307
269 void MediaStreamVideoWebRtcSink::RequestRefreshFrame() { 308 void MediaStreamVideoWebRtcSink::RequestRefreshFrame() {
270 DCHECK(thread_checker_.CalledOnValidThread()); 309 DCHECK(thread_checker_.CalledOnValidThread());
271 content::RequestRefreshFrameFromVideoTrack(connected_track()); 310 content::RequestRefreshFrameFromVideoTrack(connected_track());
272 } 311 }
273 312
274 } // namespace content 313 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698