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" |
11 | 11 |
12 namespace content { | 12 namespace content { |
13 | 13 |
14 namespace { | 14 namespace { |
15 void ResetCallback(scoped_ptr<VideoCaptureDeliverFrameCB> callback) { | 15 void ResetCallback(scoped_ptr<VideoCaptureDeliverFrameCB> callback) { |
16 // |callback| will be deleted when this exits. | 16 // |callback| will be deleted when this exits. |
17 } | 17 } |
18 } // namespace | 18 } // namespace |
19 | 19 |
20 // MediaStreamVideoTrack::FrameDeliverer is a helper class used for registering | 20 // MediaStreamVideoTrack::FrameDeliverer is a helper class used for registering |
21 // VideoCaptureDeliverFrameCB on the main render thread to receive video frames | 21 // VideoCaptureDeliverFrameCB on the main render thread to receive video frames |
22 // on the IO-thread. | 22 // on the IO-thread. |
23 // Frames are only delivered to the sinks if the track is enabled. If the track | 23 // Frames are only delivered to the sinks if the track is enabled. If the track |
24 // is disabled, a black frame is instead forwarded to the sinks at the same | 24 // is disabled, a black frame is instead forwarded to the sinks at the same |
25 // frame rate. | 25 // frame rate. |
26 class MediaStreamVideoTrack::FrameDeliverer | 26 class MediaStreamVideoTrack::FrameDeliverer |
27 : public base::RefCountedThreadSafe<FrameDeliverer> { | 27 : public base::RefCountedThreadSafe<FrameDeliverer> { |
28 public: | 28 public: |
| 29 typedef MediaStreamVideoSink* VideoSinkId; |
| 30 |
29 FrameDeliverer( | 31 FrameDeliverer( |
30 const scoped_refptr<base::MessageLoopProxy>& io_message_loop, | 32 const scoped_refptr<base::MessageLoopProxy>& io_message_loop, |
31 bool enabled); | 33 bool enabled); |
32 | 34 |
33 void SetEnabled(bool enabled); | 35 void SetEnabled(bool enabled); |
34 | 36 |
35 // Add |callback| to receive video frames on the IO-thread. | 37 // Add |callback| to receive video frames on the IO-thread. |
36 // Must be called on the main render thread. | 38 // Must be called on the main render thread. |
37 void AddCallback(void* id, const VideoCaptureDeliverFrameCB& callback); | 39 void AddCallback(VideoSinkId id, const VideoCaptureDeliverFrameCB& callback); |
38 | 40 |
39 // Removes |callback| associated with |id| from receiving video frames if |id| | 41 // Removes |callback| associated with |id| from receiving video frames if |id| |
40 // has been added. It is ok to call RemoveCallback even if the |id| has not | 42 // has been added. It is ok to call RemoveCallback even if the |id| has not |
41 // been added. Note that the added callback will be reset on the main thread. | 43 // been added. Note that the added callback will be reset on the main thread. |
42 // Must be called on the main render thread. | 44 // Must be called on the main render thread. |
43 void RemoveCallback(void* id); | 45 void RemoveCallback(VideoSinkId id); |
44 | 46 |
45 // Triggers all registered callbacks with |frame|, |format| and | 47 // Triggers all registered callbacks with |frame|, |format| and |
46 // |estimated_capture_time| as parameters. Must be called on the IO-thread. | 48 // |estimated_capture_time| as parameters. Must be called on the IO-thread. |
47 void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, | 49 void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, |
48 const base::TimeTicks& estimated_capture_time); | 50 const base::TimeTicks& estimated_capture_time); |
49 | 51 |
50 private: | 52 private: |
51 friend class base::RefCountedThreadSafe<FrameDeliverer>; | 53 friend class base::RefCountedThreadSafe<FrameDeliverer>; |
52 virtual ~FrameDeliverer(); | 54 virtual ~FrameDeliverer(); |
53 void AddCallbackOnIO(void* id, const VideoCaptureDeliverFrameCB& callback); | 55 void AddCallbackOnIO(VideoSinkId id, |
| 56 const VideoCaptureDeliverFrameCB& callback); |
54 void RemoveCallbackOnIO( | 57 void RemoveCallbackOnIO( |
55 void* id, const scoped_refptr<base::MessageLoopProxy>& message_loop); | 58 VideoSinkId id, |
| 59 const scoped_refptr<base::MessageLoopProxy>& message_loop); |
56 | 60 |
57 void SetEnabledOnIO(bool enabled); | 61 void SetEnabledOnIO(bool enabled); |
58 // Returns |black_frame_| where the size and time stamp is set to the same as | 62 // Returns |black_frame_| where the size and time stamp is set to the same as |
59 // as in |reference_frame|. | 63 // as in |reference_frame|. |
60 const scoped_refptr<media::VideoFrame>& GetBlackFrame( | 64 const scoped_refptr<media::VideoFrame>& GetBlackFrame( |
61 const scoped_refptr<media::VideoFrame>& reference_frame); | 65 const scoped_refptr<media::VideoFrame>& reference_frame); |
62 | 66 |
63 // Used to DCHECK that AddCallback and RemoveCallback are called on the main | 67 // Used to DCHECK that AddCallback and RemoveCallback are called on the main |
64 // render thread. | 68 // Render Thread. |
65 base::ThreadChecker thread_checker_; | 69 base::ThreadChecker main_render_thread_checker_; |
66 scoped_refptr<base::MessageLoopProxy> io_message_loop_; | 70 const scoped_refptr<base::MessageLoopProxy> io_message_loop_; |
67 | 71 |
68 bool enabled_; | 72 bool enabled_; |
69 scoped_refptr<media::VideoFrame> black_frame_; | 73 scoped_refptr<media::VideoFrame> black_frame_; |
70 | 74 |
71 typedef std::pair<void*, VideoCaptureDeliverFrameCB> VideoIdCallbackPair; | 75 typedef std::pair<VideoSinkId, VideoCaptureDeliverFrameCB> |
| 76 VideoIdCallbackPair; |
72 std::vector<VideoIdCallbackPair> callbacks_; | 77 std::vector<VideoIdCallbackPair> callbacks_; |
73 | 78 |
74 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); | 79 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); |
75 }; | 80 }; |
76 | 81 |
77 MediaStreamVideoTrack::FrameDeliverer::FrameDeliverer( | 82 MediaStreamVideoTrack::FrameDeliverer::FrameDeliverer( |
78 const scoped_refptr<base::MessageLoopProxy>& io_message_loop, bool enabled) | 83 const scoped_refptr<base::MessageLoopProxy>& io_message_loop, bool enabled) |
79 : io_message_loop_(io_message_loop), | 84 : io_message_loop_(io_message_loop), |
80 enabled_(enabled) { | 85 enabled_(enabled) { |
81 DCHECK(io_message_loop_.get()); | 86 DCHECK(io_message_loop_.get()); |
82 } | 87 } |
83 | 88 |
84 MediaStreamVideoTrack::FrameDeliverer::~FrameDeliverer() { | 89 MediaStreamVideoTrack::FrameDeliverer::~FrameDeliverer() { |
85 DCHECK(callbacks_.empty()); | 90 DCHECK(callbacks_.empty()); |
86 } | 91 } |
87 | 92 |
88 void MediaStreamVideoTrack::FrameDeliverer::AddCallback( | 93 void MediaStreamVideoTrack::FrameDeliverer::AddCallback( |
89 void* id, | 94 VideoSinkId id, |
90 const VideoCaptureDeliverFrameCB& callback) { | 95 const VideoCaptureDeliverFrameCB& callback) { |
91 DCHECK(thread_checker_.CalledOnValidThread()); | 96 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
92 io_message_loop_->PostTask( | 97 io_message_loop_->PostTask( |
93 FROM_HERE, | 98 FROM_HERE, |
94 base::Bind(&FrameDeliverer::AddCallbackOnIO, | 99 base::Bind(&FrameDeliverer::AddCallbackOnIO, |
95 this, id, callback)); | 100 this, id, callback)); |
96 } | 101 } |
97 | 102 |
98 void MediaStreamVideoTrack::FrameDeliverer::AddCallbackOnIO( | 103 void MediaStreamVideoTrack::FrameDeliverer::AddCallbackOnIO( |
99 void* id, | 104 VideoSinkId id, |
100 const VideoCaptureDeliverFrameCB& callback) { | 105 const VideoCaptureDeliverFrameCB& callback) { |
101 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 106 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
102 callbacks_.push_back(std::make_pair(id, callback)); | 107 callbacks_.push_back(std::make_pair(id, callback)); |
103 } | 108 } |
104 | 109 |
105 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallback(void* id) { | 110 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallback(VideoSinkId id) { |
106 DCHECK(thread_checker_.CalledOnValidThread()); | 111 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
107 io_message_loop_->PostTask( | 112 io_message_loop_->PostTask( |
108 FROM_HERE, | 113 FROM_HERE, |
109 base::Bind(&FrameDeliverer::RemoveCallbackOnIO, | 114 base::Bind(&FrameDeliverer::RemoveCallbackOnIO, |
110 this, id, base::MessageLoopProxy::current())); | 115 this, id, base::MessageLoopProxy::current())); |
111 } | 116 } |
112 | 117 |
113 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallbackOnIO( | 118 void MediaStreamVideoTrack::FrameDeliverer::RemoveCallbackOnIO( |
114 void* id, const scoped_refptr<base::MessageLoopProxy>& message_loop) { | 119 VideoSinkId id, |
| 120 const scoped_refptr<base::MessageLoopProxy>& message_loop) { |
115 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 121 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
116 std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin(); | 122 std::vector<VideoIdCallbackPair>::iterator it = callbacks_.begin(); |
117 for (; it != callbacks_.end(); ++it) { | 123 for (; it != callbacks_.end(); ++it) { |
118 if (it->first == id) { | 124 if (it->first == id) { |
119 // Callback is copied to heap and then deleted on the target thread. | 125 // Callback is copied to heap and then deleted on the target thread. |
120 scoped_ptr<VideoCaptureDeliverFrameCB> callback; | 126 scoped_ptr<VideoCaptureDeliverFrameCB> callback; |
121 callback.reset(new VideoCaptureDeliverFrameCB(it->second)); | 127 callback.reset(new VideoCaptureDeliverFrameCB(it->second)); |
122 callbacks_.erase(it); | 128 callbacks_.erase(it); |
123 message_loop->PostTask( | 129 message_loop->PostTask( |
124 FROM_HERE, base::Bind(&ResetCallback, base::Passed(&callback))); | 130 FROM_HERE, base::Bind(&ResetCallback, base::Passed(&callback))); |
125 return; | 131 return; |
126 } | 132 } |
127 } | 133 } |
128 } | 134 } |
129 | 135 |
130 void MediaStreamVideoTrack::FrameDeliverer::SetEnabled(bool enabled) { | 136 void MediaStreamVideoTrack::FrameDeliverer::SetEnabled(bool enabled) { |
131 DCHECK(thread_checker_.CalledOnValidThread()); | 137 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
132 io_message_loop_->PostTask( | 138 io_message_loop_->PostTask( |
133 FROM_HERE, | 139 FROM_HERE, |
134 base::Bind(&FrameDeliverer::SetEnabledOnIO, | 140 base::Bind(&FrameDeliverer::SetEnabledOnIO, |
135 this, enabled)); | 141 this, enabled)); |
136 } | 142 } |
137 | 143 |
138 void MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO(bool enabled) { | 144 void MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO(bool enabled) { |
139 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 145 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
140 enabled_ = enabled; | 146 enabled_ = enabled; |
141 if (enabled_) | 147 if (enabled_) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 source_(source) { | 205 source_(source) { |
200 DCHECK(!constraints.isNull()); | 206 DCHECK(!constraints.isNull()); |
201 source->AddTrack(this, | 207 source->AddTrack(this, |
202 base::Bind( | 208 base::Bind( |
203 &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, | 209 &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO, |
204 frame_deliverer_), | 210 frame_deliverer_), |
205 constraints, callback); | 211 constraints, callback); |
206 } | 212 } |
207 | 213 |
208 MediaStreamVideoTrack::~MediaStreamVideoTrack() { | 214 MediaStreamVideoTrack::~MediaStreamVideoTrack() { |
209 DCHECK(thread_checker_.CalledOnValidThread()); | 215 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
210 DCHECK(sinks_.empty()); | 216 DCHECK(sinks_.empty()); |
211 Stop(); | 217 Stop(); |
212 DVLOG(3) << "~MediaStreamVideoTrack()"; | 218 DVLOG(3) << "~MediaStreamVideoTrack()"; |
213 } | 219 } |
214 | 220 |
215 void MediaStreamVideoTrack::AddSink( | 221 void MediaStreamVideoTrack::AddSink( |
216 MediaStreamVideoSink* sink, const VideoCaptureDeliverFrameCB& callback) { | 222 MediaStreamVideoSink* sink, const VideoCaptureDeliverFrameCB& callback) { |
217 DCHECK(thread_checker_.CalledOnValidThread()); | 223 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
218 DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end()); | 224 DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end()); |
219 sinks_.push_back(sink); | 225 sinks_.push_back(sink); |
220 frame_deliverer_->AddCallback(sink, callback); | 226 frame_deliverer_->AddCallback(sink, callback); |
221 } | 227 } |
222 | 228 |
223 void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) { | 229 void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) { |
224 DCHECK(thread_checker_.CalledOnValidThread()); | 230 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
225 std::vector<MediaStreamVideoSink*>::iterator it = | 231 std::vector<MediaStreamVideoSink*>::iterator it = |
226 std::find(sinks_.begin(), sinks_.end(), sink); | 232 std::find(sinks_.begin(), sinks_.end(), sink); |
227 DCHECK(it != sinks_.end()); | 233 DCHECK(it != sinks_.end()); |
228 sinks_.erase(it); | 234 sinks_.erase(it); |
229 frame_deliverer_->RemoveCallback(sink); | 235 frame_deliverer_->RemoveCallback(sink); |
230 } | 236 } |
231 | 237 |
232 void MediaStreamVideoTrack::SetEnabled(bool enabled) { | 238 void MediaStreamVideoTrack::SetEnabled(bool enabled) { |
233 DCHECK(thread_checker_.CalledOnValidThread()); | 239 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
234 frame_deliverer_->SetEnabled(enabled); | 240 frame_deliverer_->SetEnabled(enabled); |
235 for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks_.begin(); | 241 for (auto* sink : sinks_) |
236 it != sinks_.end(); ++it) { | 242 sink->OnEnabledChanged(enabled); |
237 (*it)->OnEnabledChanged(enabled); | |
238 } | |
239 } | 243 } |
240 | 244 |
241 void MediaStreamVideoTrack::Stop() { | 245 void MediaStreamVideoTrack::Stop() { |
242 DCHECK(thread_checker_.CalledOnValidThread()); | 246 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
243 if (source_) { | 247 if (source_) { |
244 source_->RemoveTrack(this); | 248 source_->RemoveTrack(this); |
245 source_ = NULL; | 249 source_ = NULL; |
246 } | 250 } |
247 OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); | 251 OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); |
248 } | 252 } |
249 | 253 |
250 void MediaStreamVideoTrack::OnReadyStateChanged( | 254 void MediaStreamVideoTrack::OnReadyStateChanged( |
251 blink::WebMediaStreamSource::ReadyState state) { | 255 blink::WebMediaStreamSource::ReadyState state) { |
252 DCHECK(thread_checker_.CalledOnValidThread()); | 256 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
253 for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks_.begin(); | 257 for (auto* sink : sinks_) |
254 it != sinks_.end(); ++it) { | 258 sink->OnReadyStateChanged(state); |
255 (*it)->OnReadyStateChanged(state); | |
256 } | |
257 } | 259 } |
258 | 260 |
259 } // namespace content | 261 } // namespace content |
OLD | NEW |