OLD | NEW |
---|---|
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/media_stream_video_track.h" | 5 #include "content/renderer/media/media_stream_video_track.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" | 10 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
27 // VideoCaptureDeliverFrameCB on the main render thread to receive video frames | 27 // VideoCaptureDeliverFrameCB on the main render thread to receive video frames |
28 // on the IO-thread. | 28 // on the IO-thread. |
29 // Frames are only delivered to the sinks if the track is enabled. If the track | 29 // Frames are only delivered to the sinks if the track is enabled. If the track |
30 // is disabled, a black frame is instead forwarded to the sinks at the same | 30 // is disabled, a black frame is instead forwarded to the sinks at the same |
31 // frame rate. | 31 // frame rate. |
32 class MediaStreamVideoTrack::FrameDeliverer | 32 class MediaStreamVideoTrack::FrameDeliverer |
33 : public base::RefCountedThreadSafe<FrameDeliverer> { | 33 : public base::RefCountedThreadSafe<FrameDeliverer> { |
34 public: | 34 public: |
35 typedef MediaStreamVideoSink* VideoSinkId; | 35 typedef MediaStreamVideoSink* VideoSinkId; |
36 | 36 |
37 FrameDeliverer( | 37 FrameDeliverer(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
no sievers
2015/05/20 23:02:38
..
Sami
2015/05/21 11:39:49
Ditto.
| |
38 const scoped_refptr<base::MessageLoopProxy>& io_message_loop, | 38 bool enabled); |
39 bool enabled); | |
40 | 39 |
41 void SetEnabled(bool enabled); | 40 void SetEnabled(bool enabled); |
42 | 41 |
43 // Add |callback| to receive video frames on the IO-thread. | 42 // Add |callback| to receive video frames on the IO-thread. |
44 // Must be called on the main render thread. | 43 // Must be called on the main render thread. |
45 void AddCallback(VideoSinkId id, const VideoCaptureDeliverFrameCB& callback); | 44 void AddCallback(VideoSinkId id, const VideoCaptureDeliverFrameCB& callback); |
46 | 45 |
47 // Removes |callback| associated with |id| from receiving video frames if |id| | 46 // Removes |callback| associated with |id| from receiving video frames if |id| |
48 // has been added. It is ok to call RemoveCallback even if the |id| has not | 47 // has been added. It is ok to call RemoveCallback even if the |id| has not |
49 // been added. Note that the added callback will be reset on the main thread. | 48 // been added. Note that the added callback will be reset on the main thread. |
50 // Must be called on the main render thread. | 49 // Must be called on the main render thread. |
51 void RemoveCallback(VideoSinkId id); | 50 void RemoveCallback(VideoSinkId id); |
52 | 51 |
53 // Triggers all registered callbacks with |frame|, |format| and | 52 // Triggers all registered callbacks with |frame|, |format| and |
54 // |estimated_capture_time| as parameters. Must be called on the IO-thread. | 53 // |estimated_capture_time| as parameters. Must be called on the IO-thread. |
55 void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, | 54 void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, |
56 const base::TimeTicks& estimated_capture_time); | 55 const base::TimeTicks& estimated_capture_time); |
57 | 56 |
58 private: | 57 private: |
59 friend class base::RefCountedThreadSafe<FrameDeliverer>; | 58 friend class base::RefCountedThreadSafe<FrameDeliverer>; |
60 virtual ~FrameDeliverer(); | 59 virtual ~FrameDeliverer(); |
61 void AddCallbackOnIO(VideoSinkId id, | 60 void AddCallbackOnIO(VideoSinkId id, |
62 const VideoCaptureDeliverFrameCB& callback); | 61 const VideoCaptureDeliverFrameCB& callback); |
63 void RemoveCallbackOnIO( | 62 void RemoveCallbackOnIO( |
64 VideoSinkId id, | 63 VideoSinkId id, |
65 const scoped_refptr<base::MessageLoopProxy>& message_loop); | 64 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); |
66 | 65 |
67 void SetEnabledOnIO(bool enabled); | 66 void SetEnabledOnIO(bool enabled); |
68 // Returns a black frame where the size and time stamp is set to the same as | 67 // Returns a black frame where the size and time stamp is set to the same as |
69 // as in |reference_frame|. | 68 // as in |reference_frame|. |
70 scoped_refptr<media::VideoFrame> GetBlackFrame( | 69 scoped_refptr<media::VideoFrame> GetBlackFrame( |
71 const scoped_refptr<media::VideoFrame>& reference_frame); | 70 const scoped_refptr<media::VideoFrame>& reference_frame); |
72 | 71 |
73 // Used to DCHECK that AddCallback and RemoveCallback are called on the main | 72 // Used to DCHECK that AddCallback and RemoveCallback are called on the main |
74 // Render Thread. | 73 // Render Thread. |
75 base::ThreadChecker main_render_thread_checker_; | 74 base::ThreadChecker main_render_thread_checker_; |
76 const scoped_refptr<base::MessageLoopProxy> io_message_loop_; | 75 const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; |
77 | 76 |
78 bool enabled_; | 77 bool enabled_; |
79 scoped_refptr<media::VideoFrame> black_frame_; | 78 scoped_refptr<media::VideoFrame> black_frame_; |
80 | 79 |
81 typedef std::pair<VideoSinkId, VideoCaptureDeliverFrameCB> | 80 typedef std::pair<VideoSinkId, VideoCaptureDeliverFrameCB> |
82 VideoIdCallbackPair; | 81 VideoIdCallbackPair; |
83 std::vector<VideoIdCallbackPair> callbacks_; | 82 std::vector<VideoIdCallbackPair> callbacks_; |
84 | 83 |
85 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); | 84 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); |
86 }; | 85 }; |
87 | 86 |
88 MediaStreamVideoTrack::FrameDeliverer::FrameDeliverer( | 87 MediaStreamVideoTrack::FrameDeliverer::FrameDeliverer( |
89 const scoped_refptr<base::MessageLoopProxy>& io_message_loop, bool enabled) | 88 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner, |
90 : io_message_loop_(io_message_loop), | 89 bool enabled) |
91 enabled_(enabled) { | 90 : io_task_runner_(io_task_runner), enabled_(enabled) { |
92 DCHECK(io_message_loop_.get()); | 91 DCHECK(io_task_runner_.get()); |
93 } | 92 } |
94 | 93 |
95 MediaStreamVideoTrack::FrameDeliverer::~FrameDeliverer() { | 94 MediaStreamVideoTrack::FrameDeliverer::~FrameDeliverer() { |
96 DCHECK(callbacks_.empty()); | 95 DCHECK(callbacks_.empty()); |
97 } | 96 } |
98 | 97 |
99 void MediaStreamVideoTrack::FrameDeliverer::AddCallback( | 98 void MediaStreamVideoTrack::FrameDeliverer::AddCallback( |
100 VideoSinkId id, | 99 VideoSinkId id, |
101 const VideoCaptureDeliverFrameCB& callback) { | 100 const VideoCaptureDeliverFrameCB& callback) { |
102 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 101 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
103 io_message_loop_->PostTask( | 102 io_task_runner_->PostTask( |
104 FROM_HERE, | 103 FROM_HERE, |
105 base::Bind(&FrameDeliverer::AddCallbackOnIO, | 104 base::Bind(&FrameDeliverer::AddCallbackOnIO, this, id, callback)); |
106 this, id, callback)); | |
107 } | 105 } |
108 | 106 |
109 void MediaStreamVideoTrack::FrameDeliverer::AddCallbackOnIO( | 107 void MediaStreamVideoTrack::FrameDeliverer::AddCallbackOnIO( |
110 VideoSinkId id, | 108 VideoSinkId id, |
111 const VideoCaptureDeliverFrameCB& callback) { | 109 const VideoCaptureDeliverFrameCB& callback) { |
112 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 110 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
113 callbacks_.push_back(std::make_pair(id, callback)); | 111 callbacks_.push_back(std::make_pair(id, callback)); |
114 } | 112 } |
115 | 113 |
116 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallback(VideoSinkId id) { | 114 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallback(VideoSinkId id) { |
117 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 115 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
118 io_message_loop_->PostTask( | 116 io_task_runner_->PostTask( |
119 FROM_HERE, | 117 FROM_HERE, base::Bind(&FrameDeliverer::RemoveCallbackOnIO, this, id, |
120 base::Bind(&FrameDeliverer::RemoveCallbackOnIO, | 118 base::MessageLoopProxy::current())); |
121 this, id, base::MessageLoopProxy::current())); | |
122 } | 119 } |
123 | 120 |
124 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallbackOnIO( | 121 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallbackOnIO( |
125 VideoSinkId id, | 122 VideoSinkId id, |
126 const scoped_refptr<base::MessageLoopProxy>& message_loop) { | 123 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { |
127 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 124 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
128 std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin(); | 125 std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin(); |
129 for (; it != callbacks_.end(); ++it) { | 126 for (; it != callbacks_.end(); ++it) { |
130 if (it->first == id) { | 127 if (it->first == id) { |
131 // Callback is copied to heap and then deleted on the target thread. | 128 // Callback is copied to heap and then deleted on the target thread. |
132 scoped_ptr<VideoCaptureDeliverFrameCB> callback; | 129 scoped_ptr<VideoCaptureDeliverFrameCB> callback; |
133 callback.reset(new VideoCaptureDeliverFrameCB(it->second)); | 130 callback.reset(new VideoCaptureDeliverFrameCB(it->second)); |
134 callbacks_.erase(it); | 131 callbacks_.erase(it); |
135 message_loop->PostTask( | 132 task_runner->PostTask( |
136 FROM_HERE, base::Bind(&ResetCallback, base::Passed(&callback))); | 133 FROM_HERE, base::Bind(&ResetCallback, base::Passed(&callback))); |
137 return; | 134 return; |
138 } | 135 } |
139 } | 136 } |
140 } | 137 } |
141 | 138 |
142 void MediaStreamVideoTrack::FrameDeliverer::SetEnabled(bool enabled) { | 139 void MediaStreamVideoTrack::FrameDeliverer::SetEnabled(bool enabled) { |
143 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 140 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
144 io_message_loop_->PostTask( | 141 io_task_runner_->PostTask( |
145 FROM_HERE, | 142 FROM_HERE, base::Bind(&FrameDeliverer::SetEnabledOnIO, this, enabled)); |
146 base::Bind(&FrameDeliverer::SetEnabledOnIO, | |
147 this, enabled)); | |
148 } | 143 } |
149 | 144 |
150 void MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO(bool enabled) { | 145 void MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO(bool enabled) { |
151 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 146 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
152 enabled_ = enabled; | 147 enabled_ = enabled; |
153 if (enabled_) | 148 if (enabled_) |
154 black_frame_ = NULL; | 149 black_frame_ = NULL; |
155 } | 150 } |
156 | 151 |
157 void MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO( | 152 void MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO( |
158 const scoped_refptr<media::VideoFrame>& frame, | 153 const scoped_refptr<media::VideoFrame>& frame, |
159 const base::TimeTicks& estimated_capture_time) { | 154 const base::TimeTicks& estimated_capture_time) { |
160 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 155 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
161 const scoped_refptr<media::VideoFrame>& video_frame = | 156 const scoped_refptr<media::VideoFrame>& video_frame = |
162 enabled_ ? frame : GetBlackFrame(frame); | 157 enabled_ ? frame : GetBlackFrame(frame); |
163 for (const auto& entry : callbacks_) | 158 for (const auto& entry : callbacks_) |
164 entry.second.Run(video_frame, estimated_capture_time); | 159 entry.second.Run(video_frame, estimated_capture_time); |
165 } | 160 } |
166 | 161 |
167 scoped_refptr<media::VideoFrame> | 162 scoped_refptr<media::VideoFrame> |
168 MediaStreamVideoTrack::FrameDeliverer::GetBlackFrame( | 163 MediaStreamVideoTrack::FrameDeliverer::GetBlackFrame( |
169 const scoped_refptr<media::VideoFrame>& reference_frame) { | 164 const scoped_refptr<media::VideoFrame>& reference_frame) { |
170 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 165 DCHECK(io_task_runner_->BelongsToCurrentThread()); |
171 if (!black_frame_.get() || | 166 if (!black_frame_.get() || |
172 black_frame_->natural_size() != reference_frame->natural_size()) | 167 black_frame_->natural_size() != reference_frame->natural_size()) |
173 black_frame_ = | 168 black_frame_ = |
174 media::VideoFrame::CreateBlackFrame(reference_frame->natural_size()); | 169 media::VideoFrame::CreateBlackFrame(reference_frame->natural_size()); |
175 | 170 |
176 // Wrap |black_frame_| so we get a fresh timestamp we can modify. Frames | 171 // Wrap |black_frame_| so we get a fresh timestamp we can modify. Frames |
177 // returned from this function may still be in use. | 172 // returned from this function may still be in use. |
178 scoped_refptr<media::VideoFrame> wrapped_black_frame = | 173 scoped_refptr<media::VideoFrame> wrapped_black_frame = |
179 media::VideoFrame::WrapVideoFrame( | 174 media::VideoFrame::WrapVideoFrame( |
180 black_frame_, black_frame_->visible_rect(), | 175 black_frame_, black_frame_->visible_rect(), |
(...skipping 25 matching lines...) Expand all Loading... | |
206 return static_cast<MediaStreamVideoTrack*>(track.extraData()); | 201 return static_cast<MediaStreamVideoTrack*>(track.extraData()); |
207 } | 202 } |
208 | 203 |
209 MediaStreamVideoTrack::MediaStreamVideoTrack( | 204 MediaStreamVideoTrack::MediaStreamVideoTrack( |
210 MediaStreamVideoSource* source, | 205 MediaStreamVideoSource* source, |
211 const blink::WebMediaConstraints& constraints, | 206 const blink::WebMediaConstraints& constraints, |
212 const MediaStreamVideoSource::ConstraintsCallback& callback, | 207 const MediaStreamVideoSource::ConstraintsCallback& callback, |
213 bool enabled) | 208 bool enabled) |
214 : MediaStreamTrack(true), | 209 : MediaStreamTrack(true), |
215 frame_deliverer_( | 210 frame_deliverer_( |
216 new MediaStreamVideoTrack::FrameDeliverer(source->io_message_loop(), | 211 new MediaStreamVideoTrack::FrameDeliverer(source->io_task_runner(), |
217 enabled)), | 212 enabled)), |
218 constraints_(constraints), | 213 constraints_(constraints), |
219 source_(source) { | 214 source_(source) { |
220 DCHECK(!constraints.isNull()); | 215 DCHECK(!constraints.isNull()); |
221 source->AddTrack(this, | 216 source->AddTrack(this, |
222 base::Bind( | 217 base::Bind( |
223 &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, | 218 &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, |
224 frame_deliverer_), | 219 frame_deliverer_), |
225 constraints, callback); | 220 constraints, callback); |
226 } | 221 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 } | 261 } |
267 | 262 |
268 void MediaStreamVideoTrack::OnReadyStateChanged( | 263 void MediaStreamVideoTrack::OnReadyStateChanged( |
269 blink::WebMediaStreamSource::ReadyState state) { | 264 blink::WebMediaStreamSource::ReadyState state) { |
270 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 265 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
271 for (auto* sink : sinks_) | 266 for (auto* sink : sinks_) |
272 sink->OnReadyStateChanged(state); | 267 sink->OnReadyStateChanged(state); |
273 } | 268 } |
274 | 269 |
275 } // namespace content | 270 } // namespace content |
OLD | NEW |