Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / media_stream_video_track.cc
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.
4
5 #include "content/renderer/media/media_stream_video_track.h"
6
7 #include "base/bind.h"
8 #include "content/renderer/media/video_frame_deliverer.h"
9 #include "media/base/bind_to_current_loop.h"
10
11 namespace content {
12
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) {
25   }
26
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);
35   }
36
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);
44   }
45
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));
52   }
53
54   virtual void DeliverFrameOnIO(
55       const scoped_refptr<media::VideoFrame>& frame,
56       const media::VideoCaptureFormat& format,
57       const base::TimeTicks& estimated_capture_time) OVERRIDE {
58     DCHECK(io_message_loop()->BelongsToCurrentThread());
59     if (!enabled_)
60       return;
61     VideoFrameDeliverer::DeliverFrameOnIO(frame, format,
62                                           estimated_capture_time);
63   }
64
65   const std::vector<MediaStreamVideoSink*>& sinks() const { return sinks_; }
66
67  protected:
68   virtual ~FrameDeliverer() {
69     DCHECK(sinks_.empty());
70   }
71
72   void SetEnabledOnIO(bool enabled) {
73     DCHECK(io_message_loop()->BelongsToCurrentThread());
74     enabled_ = enabled;
75   }
76
77  private:
78   // The below members are used on the main render thread.
79   std::vector<MediaStreamVideoSink*> sinks_;
80
81   // The below parameters are used on the IO-thread.
82   bool enabled_;
83
84   DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
85 };
86
87 // static
88 blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
89     MediaStreamVideoSource* source,
90     const blink::WebMediaConstraints& constraints,
91     const MediaStreamVideoSource::ConstraintsCallback& callback,
92     bool enabled) {
93   blink::WebMediaStreamTrack track;
94   track.initialize(source->owner());
95   track.setExtraData(new MediaStreamVideoTrack(source,
96                                                constraints,
97                                                callback,
98                                                enabled));
99   return track;
100 }
101
102 // static
103 MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack(
104      const blink::WebMediaStreamTrack& track) {
105   return static_cast<MediaStreamVideoTrack*>(track.extraData());
106 }
107
108 MediaStreamVideoTrack::MediaStreamVideoTrack(
109     MediaStreamVideoSource* source,
110     const blink::WebMediaConstraints& constraints,
111     const MediaStreamVideoSource::ConstraintsCallback& callback,
112     bool enabled)
113     : MediaStreamTrack(NULL, true),
114       frame_deliverer_(
115           new MediaStreamVideoTrack::FrameDeliverer(source->io_message_loop(),
116                                                     enabled)),
117       constraints_(constraints),
118       source_(source) {
119   DCHECK(!constraints.isNull());
120   source->AddTrack(this,
121                    base::Bind(
122                        &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO,
123                        frame_deliverer_),
124                    constraints, callback);
125 }
126
127 MediaStreamVideoTrack::~MediaStreamVideoTrack() {
128   DCHECK(thread_checker_.CalledOnValidThread());
129   Stop();
130   DVLOG(3) << "~MediaStreamVideoTrack()";
131 }
132
133 void MediaStreamVideoTrack::AddSink(
134     MediaStreamVideoSink* sink, const VideoCaptureDeliverFrameCB& callback) {
135   DCHECK(thread_checker_.CalledOnValidThread());
136   frame_deliverer_->AddSink(sink, callback);
137 }
138
139 void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) {
140   DCHECK(thread_checker_.CalledOnValidThread());
141   frame_deliverer_->RemoveSink(sink);
142 }
143
144 void MediaStreamVideoTrack::SetEnabled(bool enabled) {
145   DCHECK(thread_checker_.CalledOnValidThread());
146   MediaStreamTrack::SetEnabled(enabled);
147
148   frame_deliverer_->SetEnabled(enabled);
149   const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
150   for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
151        it != sinks.end(); ++it) {
152     (*it)->OnEnabledChanged(enabled);
153   }
154 }
155
156 void MediaStreamVideoTrack::Stop() {
157   DCHECK(thread_checker_.CalledOnValidThread());
158   if (source_) {
159     source_->RemoveTrack(this);
160     source_ = NULL;
161   }
162   OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
163 }
164
165 void MediaStreamVideoTrack::OnReadyStateChanged(
166     blink::WebMediaStreamSource::ReadyState state) {
167   DCHECK(thread_checker_.CalledOnValidThread());
168   const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
169   for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
170        it != sinks.end(); ++it) {
171     (*it)->OnReadyStateChanged(state);
172   }
173 }
174
175 }  // namespace content