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

Side by Side Diff: content/renderer/media/webmediaplayer_ms.cc

Issue 2529263004: Move passing of WebRTC rendering frames to IO thread (Closed)
Patch Set: Created 4 years 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/webmediaplayer_ms.h" 5 #include "content/renderer/media/webmediaplayer_ms.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <limits> 8 #include <limits>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 24 matching lines...) Expand all
35 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h" 35 #include "third_party/WebKit/public/platform/WebMediaPlayerSource.h"
36 #include "third_party/WebKit/public/platform/WebRect.h" 36 #include "third_party/WebKit/public/platform/WebRect.h"
37 #include "third_party/WebKit/public/platform/WebSize.h" 37 #include "third_party/WebKit/public/platform/WebSize.h"
38 38
39 namespace content { 39 namespace content {
40 40
41 // FrameDeliverer is responsible for delivering frames received on 41 // FrameDeliverer is responsible for delivering frames received on
42 // compositor thread by calling of EnqueueFrame() method of |compositor_|. 42 // compositor thread by calling of EnqueueFrame() method of |compositor_|.
43 // 43 //
44 // It is created on the main thread, but methods should be called and class 44 // It is created on the main thread, but methods should be called and class
45 // should be destructed on the compositor thread. 45 // should be destructed on the media thread.
46 class WebMediaPlayerMS::FrameDeliverer { 46 class WebMediaPlayerMS::FrameDeliverer {
47 public: 47 public:
48 typedef base::Callback<void(scoped_refptr<media::VideoFrame>)>
49 EnqueueFrameCallback;
50
51 FrameDeliverer(const base::WeakPtr<WebMediaPlayerMS>& player, 48 FrameDeliverer(const base::WeakPtr<WebMediaPlayerMS>& player,
52 const EnqueueFrameCallback& enqueue_frame_cb) 49 const MediaStreamVideoRenderer::RepaintCB& enqueue_frame_cb)
53 : last_frame_opaque_(true), 50 : last_frame_opaque_(true),
54 last_frame_rotation_(media::VIDEO_ROTATION_0), 51 last_frame_rotation_(media::VIDEO_ROTATION_0),
55 received_first_frame_(false), 52 received_first_frame_(false),
56 main_task_runner_(base::ThreadTaskRunnerHandle::Get()), 53 main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
57 player_(player), 54 player_(player),
58 enqueue_frame_cb_(enqueue_frame_cb), 55 enqueue_frame_cb_(enqueue_frame_cb),
59 weak_factory_for_compositor_(this) { 56 weak_factory_(this) {
60 compositor_thread_checker_.DetachFromThread(); 57 media_thread_checker_.DetachFromThread();
61 } 58 }
62 59
63 ~FrameDeliverer() { 60 ~FrameDeliverer() { DCHECK(media_thread_checker_.CalledOnValidThread()); }
64 DCHECK(compositor_thread_checker_.CalledOnValidThread());
65 }
66 61
67 void OnVideoFrame(scoped_refptr<media::VideoFrame> frame) { 62 void OnVideoFrame(scoped_refptr<media::VideoFrame> frame) {
68 DCHECK(compositor_thread_checker_.CalledOnValidThread()); 63 DCHECK(media_thread_checker_.CalledOnValidThread());
69 64
70 #if defined(OS_ANDROID) 65 #if defined(OS_ANDROID)
71 if (render_frame_suspended_) 66 if (render_frame_suspended_)
72 return; 67 return;
73 #endif // defined(OS_ANDROID) 68 #endif // defined(OS_ANDROID)
74 69
75 base::TimeTicks render_time; 70 base::TimeTicks render_time;
76 if (frame->metadata()->GetTimeTicks( 71 if (frame->metadata()->GetTimeTicks(
77 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) { 72 media::VideoFrameMetadata::REFERENCE_TIME, &render_time)) {
78 TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable", 73 TRACE_EVENT1("webrtc", "WebMediaPlayerMS::OnFrameAvailable",
(...skipping 27 matching lines...) Expand all
106 FROM_HERE, base::Bind(&WebMediaPlayerMS::OnRotationChanged, player_, 101 FROM_HERE, base::Bind(&WebMediaPlayerMS::OnRotationChanged, player_,
107 video_rotation, is_opaque)); 102 video_rotation, is_opaque));
108 } 103 }
109 } 104 }
110 105
111 enqueue_frame_cb_.Run(frame); 106 enqueue_frame_cb_.Run(frame);
112 } 107 }
113 108
114 #if defined(OS_ANDROID) 109 #if defined(OS_ANDROID)
115 void SetRenderFrameSuspended(bool render_frame_suspended) { 110 void SetRenderFrameSuspended(bool render_frame_suspended) {
116 DCHECK(compositor_thread_checker_.CalledOnValidThread()); 111 DCHECK(media_thread_checker_.CalledOnValidThread());
117 render_frame_suspended_ = render_frame_suspended; 112 render_frame_suspended_ = render_frame_suspended;
118 } 113 }
119 #endif // defined(OS_ANDROID) 114 #endif // defined(OS_ANDROID)
120 115
121 MediaStreamVideoRenderer::RepaintCB GetRepaintCallback() { 116 MediaStreamVideoRenderer::RepaintCB GetRepaintCallback() {
122 return base::Bind(&FrameDeliverer::OnVideoFrame, 117 return base::Bind(&FrameDeliverer::OnVideoFrame,
123 weak_factory_for_compositor_.GetWeakPtr()); 118 weak_factory_.GetWeakPtr());
124 } 119 }
125 120
126 private: 121 private:
127 bool last_frame_opaque_; 122 bool last_frame_opaque_;
128 media::VideoRotation last_frame_rotation_; 123 media::VideoRotation last_frame_rotation_;
129 bool received_first_frame_; 124 bool received_first_frame_;
130 125
131 #if defined(OS_ANDROID) 126 #if defined(OS_ANDROID)
132 bool render_frame_suspended_ = false; 127 bool render_frame_suspended_ = false;
133 #endif // defined(OS_ANDROID) 128 #endif // defined(OS_ANDROID)
134 129
135 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 130 const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
136 const base::WeakPtr<WebMediaPlayerMS> player_; 131 const base::WeakPtr<WebMediaPlayerMS> player_;
137 const EnqueueFrameCallback enqueue_frame_cb_; 132 const MediaStreamVideoRenderer::RepaintCB enqueue_frame_cb_;
138 133
139 // Used for DCHECKs to ensure method calls executed on the correct thread, 134 // Used for DCHECKs to ensure method calls executed on the correct thread,
140 // i.e. compositor thread. 135 // i.e. media thread.
141 base::ThreadChecker compositor_thread_checker_; 136 base::ThreadChecker media_thread_checker_;
142 137
143 base::WeakPtrFactory<FrameDeliverer> weak_factory_for_compositor_; 138 base::WeakPtrFactory<FrameDeliverer> weak_factory_;
144 139
145 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); 140 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
146 }; 141 };
147 142
148 WebMediaPlayerMS::WebMediaPlayerMS( 143 WebMediaPlayerMS::WebMediaPlayerMS(
149 blink::WebFrame* frame, 144 blink::WebFrame* frame,
150 blink::WebMediaPlayerClient* client, 145 blink::WebMediaPlayerClient* client,
151 base::WeakPtr<media::WebMediaPlayerDelegate> delegate, 146 base::WeakPtr<media::WebMediaPlayerDelegate> delegate,
152 media::MediaLog* media_log, 147 media::MediaLog* media_log,
153 std::unique_ptr<MediaStreamRendererFactory> factory, 148 std::unique_ptr<MediaStreamRendererFactory> factory,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 WebMediaPlayerMS::~WebMediaPlayerMS() { 186 WebMediaPlayerMS::~WebMediaPlayerMS() {
192 DVLOG(1) << __func__; 187 DVLOG(1) << __func__;
193 DCHECK(thread_checker_.CalledOnValidThread()); 188 DCHECK(thread_checker_.CalledOnValidThread());
194 189
195 // Destruct compositor resources in the proper order. 190 // Destruct compositor resources in the proper order.
196 get_client()->setWebLayer(nullptr); 191 get_client()->setWebLayer(nullptr);
197 if (video_weblayer_) 192 if (video_weblayer_)
198 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider(); 193 static_cast<cc::VideoLayer*>(video_weblayer_->layer())->StopUsingProvider();
199 194
200 if (frame_deliverer_) 195 if (frame_deliverer_)
201 compositor_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release()); 196 media_task_runner_->DeleteSoon(FROM_HERE, frame_deliverer_.release());
202 197
203 if (compositor_) 198 if (compositor_)
204 compositor_task_runner_->DeleteSoon(FROM_HERE, compositor_.release()); 199 compositor_->StopUsingProvider();
205 200
206 if (video_frame_provider_) 201 if (video_frame_provider_)
207 video_frame_provider_->Stop(); 202 video_frame_provider_->Stop();
208 203
209 if (audio_renderer_) 204 if (audio_renderer_)
210 audio_renderer_->Stop(); 205 audio_renderer_->Stop();
211 206
212 media_log_->AddEvent( 207 media_log_->AddEvent(
213 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED)); 208 media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_DESTROYED));
214 209
215 if (delegate_) { 210 if (delegate_) {
216 delegate_->PlayerGone(delegate_id_); 211 delegate_->PlayerGone(delegate_id_);
217 delegate_->RemoveObserver(delegate_id_); 212 delegate_->RemoveObserver(delegate_id_);
218 } 213 }
219 } 214 }
220 215
221 void WebMediaPlayerMS::load(LoadType load_type, 216 void WebMediaPlayerMS::load(LoadType load_type,
222 const blink::WebMediaPlayerSource& source, 217 const blink::WebMediaPlayerSource& source,
223 CORSMode /*cors_mode*/) { 218 CORSMode /*cors_mode*/) {
224 DVLOG(1) << __func__; 219 DVLOG(1) << __func__;
225 DCHECK(thread_checker_.CalledOnValidThread()); 220 DCHECK(thread_checker_.CalledOnValidThread());
226 221
227 // TODO(acolwell): Change this to DCHECK_EQ(load_type, LoadTypeMediaStream) 222 // TODO(acolwell): Change this to DCHECK_EQ(load_type, LoadTypeMediaStream)
228 // once Blink-side changes land. 223 // once Blink-side changes land.
229 DCHECK_NE(load_type, LoadTypeMediaSource); 224 DCHECK_NE(load_type, LoadTypeMediaSource);
230 blink::WebMediaStream web_stream = 225 blink::WebMediaStream web_stream =
231 GetWebMediaStreamFromWebMediaPlayerSource(source); 226 GetWebMediaStreamFromWebMediaPlayerSource(source);
232 227
233 compositor_.reset(new WebMediaPlayerMSCompositor(compositor_task_runner_, 228 compositor_ = new WebMediaPlayerMSCompositor(compositor_task_runner_,
234 web_stream, AsWeakPtr())); 229 web_stream, AsWeakPtr());
235 230
236 SetNetworkState(WebMediaPlayer::NetworkStateLoading); 231 SetNetworkState(WebMediaPlayer::NetworkStateLoading);
237 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing); 232 SetReadyState(WebMediaPlayer::ReadyStateHaveNothing);
238 std::string stream_id = 233 std::string stream_id =
239 web_stream.isNull() ? std::string() : web_stream.id().utf8(); 234 web_stream.isNull() ? std::string() : web_stream.id().utf8();
240 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id)); 235 media_log_->AddEvent(media_log_->CreateLoadEvent(stream_id));
241 236
242 // base::Unretained usage is safe here because |compositor_| is destroyed
243 // after |frame_deliverer_|.
244 frame_deliverer_.reset(new WebMediaPlayerMS::FrameDeliverer( 237 frame_deliverer_.reset(new WebMediaPlayerMS::FrameDeliverer(
245 AsWeakPtr(), base::Bind(&WebMediaPlayerMSCompositor::EnqueueFrame, 238 AsWeakPtr(),
246 base::Unretained(compositor_.get())))); 239 base::Bind(&WebMediaPlayerMSCompositor::EnqueueFrame, compositor_)));
247 video_frame_provider_ = renderer_factory_->GetVideoRenderer( 240 video_frame_provider_ = renderer_factory_->GetVideoRenderer(
248 web_stream, media::BindToCurrentLoop(base::Bind( 241 web_stream, media::BindToCurrentLoop(base::Bind(
249 &WebMediaPlayerMS::OnSourceError, AsWeakPtr())), 242 &WebMediaPlayerMS::OnSourceError, AsWeakPtr())),
250 frame_deliverer_->GetRepaintCallback(), compositor_task_runner_, 243 frame_deliverer_->GetRepaintCallback(), media_task_runner_,
251 media_task_runner_, worker_task_runner_, gpu_factories_); 244 worker_task_runner_, gpu_factories_);
252 245
253 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_); 246 RenderFrame* const frame = RenderFrame::FromWebFrame(frame_);
254 247
255 if (frame) { 248 if (frame) {
256 // Report UMA and RAPPOR metrics. 249 // Report UMA and RAPPOR metrics.
257 GURL url = source.isURL() ? GURL(source.getAsURL()) : GURL(); 250 GURL url = source.isURL() ? GURL(source.getAsURL()) : GURL();
258 media::ReportMetrics(load_type, url, frame_->getSecurityOrigin()); 251 media::ReportMetrics(load_type, url, frame_->getSecurityOrigin());
259 252
260 audio_renderer_ = renderer_factory_->GetAudioRenderer( 253 audio_renderer_ = renderer_factory_->GetAudioRenderer(
261 web_stream, frame->GetRoutingID(), initial_audio_output_device_id_, 254 web_stream, frame->GetRoutingID(), initial_audio_output_device_id_,
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 #if defined(OS_ANDROID) 505 #if defined(OS_ANDROID)
513 DCHECK(thread_checker_.CalledOnValidThread()); 506 DCHECK(thread_checker_.CalledOnValidThread());
514 507
515 // Method called when the RenderFrame is sent to background and suspended 508 // Method called when the RenderFrame is sent to background and suspended
516 // (android). Substitute the displayed VideoFrame with a copy to avoid 509 // (android). Substitute the displayed VideoFrame with a copy to avoid
517 // holding on to it unnecessarily. 510 // holding on to it unnecessarily.
518 // 511 //
519 // During undoable tab closures OnHidden() may be called back to back, so we 512 // During undoable tab closures OnHidden() may be called back to back, so we
520 // can't rely on |render_frame_suspended_| being false here. 513 // can't rely on |render_frame_suspended_| being false here.
521 if (frame_deliverer_) { 514 if (frame_deliverer_) {
522 compositor_task_runner_->PostTask( 515 media_task_runner_->PostTask(
523 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, 516 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended,
524 base::Unretained(frame_deliverer_.get()), true)); 517 base::Unretained(frame_deliverer_.get()), true));
525 } 518 }
526 519
527 if (!paused_) 520 if (!paused_)
528 compositor_->ReplaceCurrentFrameWithACopy(); 521 compositor_->ReplaceCurrentFrameWithACopy();
529 #endif // defined(OS_ANDROID) 522 #endif // defined(OS_ANDROID)
530 } 523 }
531 524
532 void WebMediaPlayerMS::OnShown() { 525 void WebMediaPlayerMS::OnShown() {
533 #if defined(OS_ANDROID) 526 #if defined(OS_ANDROID)
534 DCHECK(thread_checker_.CalledOnValidThread()); 527 DCHECK(thread_checker_.CalledOnValidThread());
535 528
536 if (frame_deliverer_) { 529 if (frame_deliverer_) {
537 compositor_task_runner_->PostTask( 530 media_task_runner_->PostTask(
538 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, 531 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended,
539 base::Unretained(frame_deliverer_.get()), false)); 532 base::Unretained(frame_deliverer_.get()), false));
540 } 533 }
541 534
542 // Resume playback on visibility. play() clears |should_play_upon_shown_|. 535 // Resume playback on visibility. play() clears |should_play_upon_shown_|.
543 if (should_play_upon_shown_) 536 if (should_play_upon_shown_)
544 play(); 537 play();
545 #endif // defined(OS_ANDROID) 538 #endif // defined(OS_ANDROID)
546 } 539 }
547 540
548 bool WebMediaPlayerMS::OnSuspendRequested(bool must_suspend) { 541 bool WebMediaPlayerMS::OnSuspendRequested(bool must_suspend) {
549 #if defined(OS_ANDROID) 542 #if defined(OS_ANDROID)
550 if (!must_suspend) 543 if (!must_suspend)
551 return false; 544 return false;
552 545
553 if (!paused_) { 546 if (!paused_) {
554 pause(); 547 pause();
555 should_play_upon_shown_ = true; 548 should_play_upon_shown_ = true;
556 } 549 }
557 550
558 if (delegate_) 551 if (delegate_)
559 delegate_->PlayerGone(delegate_id_); 552 delegate_->PlayerGone(delegate_id_);
560 553
561 if (frame_deliverer_) { 554 if (frame_deliverer_) {
562 compositor_task_runner_->PostTask( 555 media_task_runner_->PostTask(
563 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended, 556 FROM_HERE, base::Bind(&FrameDeliverer::SetRenderFrameSuspended,
564 base::Unretained(frame_deliverer_.get()), true)); 557 base::Unretained(frame_deliverer_.get()), true));
565 } 558 }
566 #endif // defined(OS_ANDROID) 559 #endif // defined(OS_ANDROID)
567 return true; 560 return true;
568 } 561 }
569 562
570 void WebMediaPlayerMS::OnPlay() { 563 void WebMediaPlayerMS::OnPlay() {
571 // TODO(perkj, magjed): It's not clear how WebRTC should work with an 564 // TODO(perkj, magjed): It's not clear how WebRTC should work with an
572 // MediaSession, until these issues are resolved, disable session controls. 565 // MediaSession, until these issues are resolved, disable session controls.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 void WebMediaPlayerMS::ResetCanvasCache() { 668 void WebMediaPlayerMS::ResetCanvasCache() {
676 DCHECK(thread_checker_.CalledOnValidThread()); 669 DCHECK(thread_checker_.CalledOnValidThread());
677 video_renderer_.ResetCache(); 670 video_renderer_.ResetCache();
678 } 671 }
679 672
680 void WebMediaPlayerMS::TriggerResize() { 673 void WebMediaPlayerMS::TriggerResize() {
681 get_client()->sizeChanged(); 674 get_client()->sizeChanged();
682 } 675 }
683 676
684 } // namespace content 677 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698