OLD | NEW |
---|---|
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 |
OLD | NEW |