Cast: deliver video frames on the IO thread
[chromium-blink-merge.git] / content / renderer / media / media_stream_video_track.cc
blob32c19c9ece60f9100e8fcbbad34ea1d77ee1f40e
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
3 // found in the LICENSE file.
5 #include "content/renderer/media/media_stream_video_track.h"
7 #include "base/bind.h"
8 #include "content/renderer/media/video_frame_deliverer.h"
9 #include "media/base/bind_to_current_loop.h"
11 namespace content {
13 // Helper class used for delivering video frames to MediaStreamSinks on the
14 // IO-thread.
15 // Frames are delivered to an instance of this class from a
16 // MediaStreamVideoSource on the IO-thread to the method DeliverFrameOnIO.
17 // Frames are only delivered to the sinks if the track is enabled.
18 class MediaStreamVideoTrack::FrameDeliverer : public VideoFrameDeliverer {
19 public:
20 FrameDeliverer(
21 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
22 bool enabled)
23 : VideoFrameDeliverer(io_message_loop_proxy),
24 enabled_(enabled) {
27 // Add |sink| to receive state changes on the main render thread.
28 // Video frames will be delivered to |callback| on the IO thread.
29 void AddSink(MediaStreamVideoSink* sink,
30 const VideoCaptureDeliverFrameCB& callback) {
31 DCHECK(thread_checker().CalledOnValidThread());
32 DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end());
33 sinks_.push_back(sink);
34 AddCallback(sink, callback);
37 void RemoveSink(MediaStreamVideoSink* sink) {
38 DCHECK(thread_checker().CalledOnValidThread());
39 std::vector<MediaStreamVideoSink*>::iterator it =
40 std::find(sinks_.begin(), sinks_.end(), sink);
41 DCHECK(it != sinks_.end());
42 sinks_.erase(it);
43 RemoveCallback(sink);
46 void SetEnabled(bool enabled) {
47 DCHECK(thread_checker().CalledOnValidThread());
48 io_message_loop()->PostTask(
49 FROM_HERE,
50 base::Bind(&MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO,
51 this, enabled));
54 virtual void DeliverFrameOnIO(
55 const scoped_refptr<media::VideoFrame>& frame,
56 const media::VideoCaptureFormat& format) OVERRIDE {
57 DCHECK(io_message_loop()->BelongsToCurrentThread());
58 if (!enabled_)
59 return;
60 VideoFrameDeliverer::DeliverFrameOnIO(frame, format);
63 const std::vector<MediaStreamVideoSink*>& sinks() const { return sinks_; }
65 protected:
66 virtual ~FrameDeliverer() {
67 DCHECK(sinks_.empty());
70 void SetEnabledOnIO(bool enabled) {
71 DCHECK(io_message_loop()->BelongsToCurrentThread());
72 enabled_ = enabled;
75 private:
76 // The below members are used on the main render thread.
77 std::vector<MediaStreamVideoSink*> sinks_;
79 // The below parameters are used on the IO-thread.
80 bool enabled_;
82 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
85 // static
86 blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
87 MediaStreamVideoSource* source,
88 const blink::WebMediaConstraints& constraints,
89 const MediaStreamVideoSource::ConstraintsCallback& callback,
90 bool enabled) {
91 blink::WebMediaStreamTrack track;
92 track.initialize(source->owner());
93 track.setExtraData(new MediaStreamVideoTrack(source,
94 constraints,
95 callback,
96 enabled));
97 return track;
100 // static
101 MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack(
102 const blink::WebMediaStreamTrack& track) {
103 return static_cast<MediaStreamVideoTrack*>(track.extraData());
106 MediaStreamVideoTrack::MediaStreamVideoTrack(
107 MediaStreamVideoSource* source,
108 const blink::WebMediaConstraints& constraints,
109 const MediaStreamVideoSource::ConstraintsCallback& callback,
110 bool enabled)
111 : MediaStreamTrack(NULL, true),
112 frame_deliverer_(
113 new MediaStreamVideoTrack::FrameDeliverer(source->io_message_loop(),
114 enabled)),
115 constraints_(constraints),
116 source_(source) {
117 source->AddTrack(this,
118 base::Bind(
119 &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO,
120 frame_deliverer_),
121 constraints, callback);
124 MediaStreamVideoTrack::~MediaStreamVideoTrack() {
125 Stop();
126 DVLOG(3) << "~MediaStreamVideoTrack()";
129 void MediaStreamVideoTrack::AddSink(
130 MediaStreamVideoSink* sink, const VideoCaptureDeliverFrameCB& callback) {
131 DCHECK(thread_checker_.CalledOnValidThread());
132 frame_deliverer_->AddSink(sink, callback);
135 void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) {
136 DCHECK(thread_checker_.CalledOnValidThread());
137 frame_deliverer_->RemoveSink(sink);
140 void MediaStreamVideoTrack::SetEnabled(bool enabled) {
141 DCHECK(thread_checker_.CalledOnValidThread());
142 MediaStreamTrack::SetEnabled(enabled);
144 frame_deliverer_->SetEnabled(enabled);
145 const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
146 for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
147 it != sinks.end(); ++it) {
148 (*it)->OnEnabledChanged(enabled);
152 void MediaStreamVideoTrack::Stop() {
153 DCHECK(thread_checker_.CalledOnValidThread());
154 if (source_) {
155 source_->RemoveTrack(this);
156 source_ = NULL;
158 OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
161 void MediaStreamVideoTrack::OnReadyStateChanged(
162 blink::WebMediaStreamSource::ReadyState state) {
163 DCHECK(thread_checker_.CalledOnValidThread());
164 const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
165 for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
166 it != sinks.end(); ++it) {
167 (*it)->OnReadyStateChanged(state);
171 } // namespace content