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"
8 #include "content/renderer/media/video_frame_deliverer.h"
9 #include "media/base/bind_to_current_loop.h"
13 // Helper class used for delivering video frames to MediaStreamSinks on the
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 {
21 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
23 : VideoFrameDeliverer(io_message_loop_proxy),
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());
46 void SetEnabled(bool enabled) {
47 DCHECK(thread_checker().CalledOnValidThread());
48 io_message_loop()->PostTask(
50 base::Bind(&MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO,
54 virtual void DeliverFrameOnIO(
55 const scoped_refptr<media::VideoFrame>& frame,
56 const media::VideoCaptureFormat& format) OVERRIDE {
57 DCHECK(io_message_loop()->BelongsToCurrentThread());
60 VideoFrameDeliverer::DeliverFrameOnIO(frame, format);
63 const std::vector<MediaStreamVideoSink*>& sinks() const { return sinks_; }
66 virtual ~FrameDeliverer() {
67 DCHECK(sinks_.empty());
70 void SetEnabledOnIO(bool enabled) {
71 DCHECK(io_message_loop()->BelongsToCurrentThread());
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.
82 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
86 blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
87 MediaStreamVideoSource* source,
88 const blink::WebMediaConstraints& constraints,
89 const MediaStreamVideoSource::ConstraintsCallback& callback,
91 blink::WebMediaStreamTrack track;
92 track.initialize(source->owner());
93 track.setExtraData(new MediaStreamVideoTrack(source,
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,
111 : MediaStreamTrack(NULL, true),
113 new MediaStreamVideoTrack::FrameDeliverer(source->io_message_loop(),
115 constraints_(constraints),
117 source->AddTrack(this,
119 &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO,
121 constraints, callback);
124 MediaStreamVideoTrack::~MediaStreamVideoTrack() {
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());
155 source_->RemoveTrack(this);
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