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

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

Issue 2356663002: Implement and use VideoTrackSource directly. (Closed)
Patch Set: add test TODO 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_;
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 // TODO(pbos): Add tests that make sure that googNoiseReduction has properly
perkj_chrome 2016/09/26 07:09:04 This class is currently tested in rtc_peer_connect
pbos 2016/09/26 17:11:44 Would like to do it in a follow-up, won't close th
222 // propagated from getUserMedia down to a VideoTrackSource.
223 rtc::Optional<bool> needs_denoising;
224 bool denoising_value;
225 if (GetConstraintValueAsBoolean(
226 constraints, &blink::WebMediaTrackConstraintSet::googNoiseReduction,
227 &denoising_value)) {
228 needs_denoising = rtc::Optional<bool>(denoising_value);
nisse-chromium (ooo August 14) 2016/09/26 06:51:01 Maybe move this logic closer to where needs_denois
pbos 2016/09/26 17:11:44 Done this way to keep constraint extraction in one
229 }
230
193 // Enable automatic frame refreshes for the screen capture sources, which will 231 // Enable automatic frame refreshes for the screen capture sources, which will
194 // stop producing frames whenever screen content is not changing. Check the 232 // stop producing frames whenever screen content is not changing. Check the
195 // frameRate constraint to determine the rate of refreshes. If a minimum 233 // frameRate constraint to determine the rate of refreshes. If a minimum
196 // frameRate is provided, use that. Otherwise, use the maximum frameRate if it 234 // frameRate is provided, use that. Otherwise, use the maximum frameRate if it
197 // happens to be less than the default. 235 // happens to be less than the default.
198 base::TimeDelta refresh_interval = base::TimeDelta::FromMicroseconds(0); 236 base::TimeDelta refresh_interval = base::TimeDelta::FromMicroseconds(0);
199 if (is_screencast) { 237 if (is_screencast) {
200 // Start with the default refresh interval, and refine based on constraints. 238 // Start with the default refresh interval, and refine based on constraints.
201 refresh_interval = 239 refresh_interval =
202 base::TimeDelta::FromMicroseconds(kDefaultRefreshIntervalMicros); 240 base::TimeDelta::FromMicroseconds(kDefaultRefreshIntervalMicros);
(...skipping 14 matching lines...) Expand all
217 base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>( 255 base::TimeDelta::FromMicroseconds(base::saturated_cast<int64_t>(
218 base::Time::kMicrosecondsPerSecond / value)); 256 base::Time::kMicrosecondsPerSecond / value));
219 refresh_interval = std::max(refresh_interval, alternate_refresh_interval); 257 refresh_interval = std::max(refresh_interval, alternate_refresh_interval);
220 } 258 }
221 if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) { 259 if (refresh_interval.InMicroseconds() < kLowerBoundRefreshIntervalMicros) {
222 refresh_interval = 260 refresh_interval =
223 base::TimeDelta::FromMicroseconds(kLowerBoundRefreshIntervalMicros); 261 base::TimeDelta::FromMicroseconds(kLowerBoundRefreshIntervalMicros);
224 } 262 }
225 } 263 }
226 264
227 WebRtcVideoCapturerAdapter* capture_adapter = 265 // TODO(pbos): Consolidate WebRtcVideoCapturerAdapter into WebRtcVideoSource
228 factory->CreateVideoCapturer(is_screencast); 266 // by removing the need for and dependency on a cricket::VideoCapturer.
267 video_source_ = scoped_refptr<WebRtcVideoSource>(
268 new rtc::RefCountedObject<WebRtcVideoSource>(
269 new WebRtcVideoCapturerAdapter(is_screencast), is_screencast,
270 needs_denoising));
229 271
230 // |video_source| owns |capture_adapter| 272 // TODO(pbos): Consolidate the local video track with the source proxy and
231 scoped_refptr<webrtc::VideoTrackSourceInterface> video_source( 273 // move into PeerConnectionDependencyFactory. This now separately holds on a
232 factory->CreateVideoSource(capture_adapter)); 274 // reference to the proxy object because
233 275 // PeerConnectionFactory::CreateVideoTrack doesn't do reference counting.
276 video_source_proxy_ =
277 factory->CreateVideoTrackSourceProxy(video_source_.get());
234 video_track_ = factory->CreateLocalVideoTrack(track.id().utf8(), 278 video_track_ = factory->CreateLocalVideoTrack(track.id().utf8(),
235 video_source.get()); 279 video_source_proxy_.get());
236 280
237 video_track_->set_enabled(track.isEnabled()); 281 video_track_->set_enabled(track.isEnabled());
238 282
239 source_adapter_ = new WebRtcVideoSourceAdapter( 283 source_adapter_ = new WebRtcVideoSourceAdapter(
240 factory->GetWebRtcWorkerThread(), 284 factory->GetWebRtcWorkerThread(), video_source_.get(), refresh_interval,
241 video_source,
242 capture_adapter,
243 refresh_interval,
244 base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame, 285 base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame,
245 weak_factory_.GetWeakPtr())); 286 weak_factory_.GetWeakPtr()));
246 287
247 MediaStreamVideoSink::ConnectToTrack( 288 MediaStreamVideoSink::ConnectToTrack(
248 track, 289 track,
249 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_), 290 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_),
250 false); 291 false);
251 292
252 DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast " 293 DVLOG(3) << "MediaStreamVideoWebRtcSink ctor() : is_screencast "
253 << is_screencast; 294 << is_screencast;
(...skipping 11 matching lines...) Expand all
265 DCHECK(thread_checker_.CalledOnValidThread()); 306 DCHECK(thread_checker_.CalledOnValidThread());
266 video_track_->set_enabled(enabled); 307 video_track_->set_enabled(enabled);
267 } 308 }
268 309
269 void MediaStreamVideoWebRtcSink::RequestRefreshFrame() { 310 void MediaStreamVideoWebRtcSink::RequestRefreshFrame() {
270 DCHECK(thread_checker_.CalledOnValidThread()); 311 DCHECK(thread_checker_.CalledOnValidThread());
271 content::RequestRefreshFrameFromVideoTrack(connected_track()); 312 content::RequestRefreshFrameFromVideoTrack(connected_track());
272 } 313 }
273 314
274 } // namespace content 315 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698