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

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

Issue 282523003: Deliver video frames on libjingle worker thread to WebRtcVideoCapturerAdapter. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed Tommis comments. Created 6 years, 7 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
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 "content/common/media/media_stream_options.h" 8 #include "content/common/media/media_stream_options.h"
9 #include "content/renderer/media/media_stream_video_source.h" 9 #include "content/renderer/media/media_stream_video_source.h"
10 #include "content/renderer/media/media_stream_video_track.h" 10 #include "content/renderer/media/media_stream_video_track.h"
11 11
12 namespace { 12 namespace {
13 13
14 bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints, 14 bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints,
15 const blink::WebString& name) { 15 const blink::WebString& name) {
16 blink::WebString value_str; 16 blink::WebString value_str;
17 return constraints.getMandatoryConstraintValue(name, value_str) || 17 return constraints.getMandatoryConstraintValue(name, value_str) ||
18 constraints.getOptionalConstraintValue(name, value_str); 18 constraints.getOptionalConstraintValue(name, value_str);
19 } 19 }
20 20
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
21 } // anonymouse namespace 27 } // anonymouse namespace
22 28
23 namespace content { 29 namespace content {
24 30
25 // Simple help class used for receiving video frames on the IO-thread from 31 // Simple help class used for receiving video frames on the IO-thread from
26 // a MediaStreamVideoTrack and forward the frames to a 32 // a MediaStreamVideoTrack and forward the frames to a
27 // WebRtcVideoCapturerAdapter that implements a video capturer for libjingle. 33 // WebRtcVideoCapturerAdapter on libjingle's worker thread.
34 // WebRtcVideoCapturerAdapter implements a video capturer for libjingle.
28 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter 35 class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
29 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> { 36 : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
30 public: 37 public:
31 WebRtcVideoSourceAdapter( 38 WebRtcVideoSourceAdapter(
39 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
32 const scoped_refptr<webrtc::VideoSourceInterface>& source, 40 const scoped_refptr<webrtc::VideoSourceInterface>& source,
33 WebRtcVideoCapturerAdapter* capture_adapter); 41 WebRtcVideoCapturerAdapter* capture_adapter);
34 42
35 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, 43 void OnVideoFrameOnIO(const scoped_refptr<media::VideoFrame>& frame,
36 const media::VideoCaptureFormat& format); 44 const media::VideoCaptureFormat& format);
37 45
38 private: 46 private:
47 void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame,
48 const media::VideoCaptureFormat& format);
39 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>; 49 friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
40 virtual ~WebRtcVideoSourceAdapter(); 50 virtual ~WebRtcVideoSourceAdapter();
41 51
52 scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_;
53
42 // Used to DCHECK that frames are called on the IO-thread. 54 // Used to DCHECK that frames are called on the IO-thread.
43 base::ThreadChecker io_thread_checker_; 55 base::ThreadChecker io_thread_checker_;
56
57 // Used for posting frames to libjingle's worker thread. Accessed on the
58 // IO-thread.
59 scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_;
Ronghua Wu (Left Chromium) 2014/05/12 16:09:12 call this target_thread_? and call io_thread_check
Ami GONE FROM CHROMIUM 2014/05/12 18:13:33 FWIW I weakly prefer io/worker/signaling/rendering
perkj_chrome 2014/05/12 19:28:26 I would prefer to leave as it is.
60
44 scoped_refptr<webrtc::VideoSourceInterface> video_source_; 61 scoped_refptr<webrtc::VideoSourceInterface> video_source_;
45 // |capture_adapter_| is owned by |video_source_| 62 // |capture_adapter_| is owned by |video_source_|
46 WebRtcVideoCapturerAdapter* capture_adapter_; 63 WebRtcVideoCapturerAdapter* capture_adapter_;
47 }; 64 };
48 65
49 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter( 66 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
67 const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
50 const scoped_refptr<webrtc::VideoSourceInterface>& source, 68 const scoped_refptr<webrtc::VideoSourceInterface>& source,
51 WebRtcVideoCapturerAdapter* capture_adapter) 69 WebRtcVideoCapturerAdapter* capture_adapter)
52 : video_source_(source), 70 : render_thread_message_loop_(base::MessageLoopProxy::current()),
71 libjingle_worker_thread_(libjingle_worker_thread),
72 video_source_(source),
53 capture_adapter_(capture_adapter) { 73 capture_adapter_(capture_adapter) {
54 io_thread_checker_.DetachFromThread(); 74 io_thread_checker_.DetachFromThread();
55 } 75 }
56 76
57 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() { 77 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
78 // 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
80 // thread, it should be released on the render thread.
81 if (!render_thread_message_loop_->BelongsToCurrentThread()) {
82 webrtc::VideoSourceInterface* source = video_source_.get();
83 source->AddRef();
84 video_source_ = NULL;
85 render_thread_message_loop_->PostTask(
wuchengli 2014/05/12 15:45:56 You can just use render_thread_message_loop_->Rele
perkj_chrome 2014/05/12 16:07:09 Nice to know. But this is not a Chrome class so th
wuchengli 2014/05/12 16:36:50 I see.
86 FROM_HERE,
87 base::Bind(&ReleaseWebRtcSourceOnMainRenderThread,
Ami GONE FROM CHROMIUM 2014/05/12 18:13:33 FWIW, base::Bind(&talk_base::RefCountedInterface:
perkj_chrome 2014/05/12 19:28:26 Good idea, but talk_base::RefCountInterface::Relea
Ami GONE FROM CHROMIUM 2014/05/12 19:46:27 It sounds like you're saying that base::Bind() can
perkj_chrome 2014/05/12 20:35:11 Humm, Can it be that Release returns an int in lib
Ami GONE FROM CHROMIUM 2014/05/12 21:24:38 Yeah; that'd do it.
88 base::Unretained(source)));
89 }
58 } 90 }
59 91
60 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO( 92 void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
61 const scoped_refptr<media::VideoFrame>& frame, 93 const scoped_refptr<media::VideoFrame>& frame,
62 const media::VideoCaptureFormat& format) { 94 const media::VideoCaptureFormat& format) {
63 DCHECK(io_thread_checker_.CalledOnValidThread()); 95 DCHECK(io_thread_checker_.CalledOnValidThread());
96 libjingle_worker_thread_->PostTask(
97 FROM_HERE,
98 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread,
99 this, frame, format));
100 }
101
102 void
103 WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread(
104 const scoped_refptr<media::VideoFrame>& frame,
105 const media::VideoCaptureFormat& format) {
106 DCHECK(libjingle_worker_thread_->BelongsToCurrentThread());
64 capture_adapter_->OnFrameCaptured(frame); 107 capture_adapter_->OnFrameCaptured(frame);
65 } 108 }
66 109
67 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter( 110 WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
68 const blink::WebMediaStreamTrack& track, 111 const blink::WebMediaStreamTrack& track,
69 MediaStreamDependencyFactory* factory) 112 MediaStreamDependencyFactory* factory)
70 : web_track_(track) { 113 : web_track_(track) {
71 const blink::WebMediaConstraints& constraints = 114 const blink::WebMediaConstraints& constraints =
72 MediaStreamVideoTrack::GetVideoTrack(track)->constraints(); 115 MediaStreamVideoTrack::GetVideoTrack(track)->constraints();
73 116
74 bool is_screencast = ConstraintKeyExists( 117 bool is_screencast = ConstraintKeyExists(
75 constraints, base::UTF8ToUTF16(kMediaStreamSource)); 118 constraints, base::UTF8ToUTF16(kMediaStreamSource));
76 WebRtcVideoCapturerAdapter* capture_adapter = 119 WebRtcVideoCapturerAdapter* capture_adapter =
77 factory->CreateVideoCapturer(is_screencast); 120 factory->CreateVideoCapturer(is_screencast);
78 121
79 // |video_source| owns |capture_adapter| 122 // |video_source| owns |capture_adapter|
80 scoped_refptr<webrtc::VideoSourceInterface> video_source( 123 scoped_refptr<webrtc::VideoSourceInterface> video_source(
81 factory->CreateVideoSource(capture_adapter, 124 factory->CreateVideoSource(capture_adapter,
82 track.source().constraints())); 125 track.source().constraints()));
83 126
84 video_track_ = factory->CreateLocalVideoTrack(web_track_.id().utf8(), 127 video_track_ = factory->CreateLocalVideoTrack(web_track_.id().utf8(),
85 video_source.get()); 128 video_source.get());
86 129
87 video_track_->set_enabled(web_track_.isEnabled()); 130 video_track_->set_enabled(web_track_.isEnabled());
88 131
89 source_adapter_ = new WebRtcVideoSourceAdapter(video_source, 132 source_adapter_ = new WebRtcVideoSourceAdapter(
90 capture_adapter); 133 factory->GetWebRtcWorkerThread(),
Ronghua Wu (Left Chromium) 2014/05/12 16:09:12 I think we should expose this interface on |captur
perkj_chrome 2014/05/12 19:28:26 MediaStreamDependencyFactory (terrible name now by
Ronghua Wu (Left Chromium) 2014/05/12 21:45:46 In that case it makes sense to keep it in MediaStr
134 video_source,
135 capture_adapter);
91 136
92 AddToVideoTrack( 137 AddToVideoTrack(
93 this, 138 this,
94 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, 139 base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO,
95 source_adapter_), 140 source_adapter_),
96 web_track_); 141 web_track_);
97 142
98 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast " 143 DVLOG(3) << "WebRtcVideoTrackAdapter ctor() : is_screencast "
99 << is_screencast; 144 << is_screencast;
100 } 145 }
101 146
102 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() { 147 WebRtcVideoTrackAdapter::~WebRtcVideoTrackAdapter() {
103 DCHECK(thread_checker_.CalledOnValidThread()); 148 DCHECK(thread_checker_.CalledOnValidThread());
104 DVLOG(3) << "WebRtcVideoTrackAdapter dtor()."; 149 DVLOG(3) << "WebRtcVideoTrackAdapter dtor().";
105 RemoveFromVideoTrack(this, web_track_); 150 RemoveFromVideoTrack(this, web_track_);
106 } 151 }
107 152
108 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) { 153 void WebRtcVideoTrackAdapter::OnEnabledChanged(bool enabled) {
109 DCHECK(thread_checker_.CalledOnValidThread()); 154 DCHECK(thread_checker_.CalledOnValidThread());
110 video_track_->set_enabled(enabled); 155 video_track_->set_enabled(enabled);
111 } 156 }
112 157
113 } // namespace content 158 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698