summaryrefslogtreecommitdiffstats
path: root/chromium/content/renderer/media/media_stream_video_track.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/renderer/media/media_stream_video_track.cc')
-rw-r--r--chromium/content/renderer/media/media_stream_video_track.cc172
1 files changed, 150 insertions, 22 deletions
diff --git a/chromium/content/renderer/media/media_stream_video_track.cc b/chromium/content/renderer/media/media_stream_video_track.cc
index 44962445161..0ad7159255d 100644
--- a/chromium/content/renderer/media/media_stream_video_track.cc
+++ b/chromium/content/renderer/media/media_stream_video_track.cc
@@ -4,44 +4,172 @@
#include "content/renderer/media/media_stream_video_track.h"
-#include "content/renderer/media/webrtc/webrtc_video_sink_adapter.h"
+#include "base/bind.h"
+#include "content/renderer/media/video_frame_deliverer.h"
+#include "media/base/bind_to_current_loop.h"
namespace content {
-// Wrapper which allows to use std::find_if() when adding and removing
-// sinks to/from |sinks_|.
-struct SinkWrapper {
- explicit SinkWrapper(MediaStreamVideoSink* sink) : sink_(sink) {}
- bool operator()(
- const WebRtcVideoSinkAdapter* owner) {
- return owner->sink() == sink_;
+// Helper class used for delivering video frames to MediaStreamSinks on the
+// IO-thread.
+// Frames are delivered to an instance of this class from a
+// MediaStreamVideoSource on the IO-thread to the method DeliverFrameOnIO.
+// Frames are only delivered to the sinks if the track is enabled.
+class MediaStreamVideoTrack::FrameDeliverer : public VideoFrameDeliverer {
+ public:
+ FrameDeliverer(
+ const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
+ bool enabled)
+ : VideoFrameDeliverer(io_message_loop_proxy),
+ enabled_(enabled) {
}
- MediaStreamVideoSink* sink_;
+
+ // Add |sink| to receive state changes on the main render thread.
+ // Video frames will be delivered to |callback| on the IO thread.
+ void AddSink(MediaStreamVideoSink* sink,
+ const VideoCaptureDeliverFrameCB& callback) {
+ DCHECK(thread_checker().CalledOnValidThread());
+ DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end());
+ sinks_.push_back(sink);
+ AddCallback(sink, callback);
+ }
+
+ void RemoveSink(MediaStreamVideoSink* sink) {
+ DCHECK(thread_checker().CalledOnValidThread());
+ std::vector<MediaStreamVideoSink*>::iterator it =
+ std::find(sinks_.begin(), sinks_.end(), sink);
+ DCHECK(it != sinks_.end());
+ sinks_.erase(it);
+ RemoveCallback(sink);
+ }
+
+ void SetEnabled(bool enabled) {
+ DCHECK(thread_checker().CalledOnValidThread());
+ io_message_loop()->PostTask(
+ FROM_HERE,
+ base::Bind(&MediaStreamVideoTrack::FrameDeliverer::SetEnabledOnIO,
+ this, enabled));
+ }
+
+ virtual void DeliverFrameOnIO(
+ const scoped_refptr<media::VideoFrame>& frame,
+ const media::VideoCaptureFormat& format,
+ const base::TimeTicks& estimated_capture_time) OVERRIDE {
+ DCHECK(io_message_loop()->BelongsToCurrentThread());
+ if (!enabled_)
+ return;
+ VideoFrameDeliverer::DeliverFrameOnIO(frame, format,
+ estimated_capture_time);
+ }
+
+ const std::vector<MediaStreamVideoSink*>& sinks() const { return sinks_; }
+
+ protected:
+ virtual ~FrameDeliverer() {
+ DCHECK(sinks_.empty());
+ }
+
+ void SetEnabledOnIO(bool enabled) {
+ DCHECK(io_message_loop()->BelongsToCurrentThread());
+ enabled_ = enabled;
+ }
+
+ private:
+ // The below members are used on the main render thread.
+ std::vector<MediaStreamVideoSink*> sinks_;
+
+ // The below parameters are used on the IO-thread.
+ bool enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameDeliverer);
};
-MediaStreamVideoTrack::MediaStreamVideoTrack(webrtc::VideoTrackInterface* track,
- bool is_local_track)
- : MediaStreamTrackExtraData(track, is_local_track),
- video_track_(track) {
+// static
+blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
+ MediaStreamVideoSource* source,
+ const blink::WebMediaConstraints& constraints,
+ const MediaStreamVideoSource::ConstraintsCallback& callback,
+ bool enabled) {
+ blink::WebMediaStreamTrack track;
+ track.initialize(source->owner());
+ track.setExtraData(new MediaStreamVideoTrack(source,
+ constraints,
+ callback,
+ enabled));
+ return track;
+}
+
+// static
+MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack(
+ const blink::WebMediaStreamTrack& track) {
+ return static_cast<MediaStreamVideoTrack*>(track.extraData());
+}
+
+MediaStreamVideoTrack::MediaStreamVideoTrack(
+ MediaStreamVideoSource* source,
+ const blink::WebMediaConstraints& constraints,
+ const MediaStreamVideoSource::ConstraintsCallback& callback,
+ bool enabled)
+ : MediaStreamTrack(NULL, true),
+ frame_deliverer_(
+ new MediaStreamVideoTrack::FrameDeliverer(source->io_message_loop(),
+ enabled)),
+ constraints_(constraints),
+ source_(source) {
+ DCHECK(!constraints.isNull());
+ source->AddTrack(this,
+ base::Bind(
+ &MediaStreamVideoTrack::FrameDeliverer::DeliverFrameOnIO,
+ frame_deliverer_),
+ constraints, callback);
}
MediaStreamVideoTrack::~MediaStreamVideoTrack() {
- DCHECK(sinks_.empty());
+ DCHECK(thread_checker_.CalledOnValidThread());
+ Stop();
+ DVLOG(3) << "~MediaStreamVideoTrack()";
}
-void MediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink) {
+void MediaStreamVideoTrack::AddSink(
+ MediaStreamVideoSink* sink, const VideoCaptureDeliverFrameCB& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- DCHECK(std::find_if(sinks_.begin(), sinks_.end(),
- SinkWrapper(sink)) == sinks_.end());
- sinks_.push_back(new WebRtcVideoSinkAdapter(video_track_, sink));
+ frame_deliverer_->AddSink(sink, callback);
}
void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) {
DCHECK(thread_checker_.CalledOnValidThread());
- ScopedVector<WebRtcVideoSinkAdapter>::iterator it =
- std::find_if(sinks_.begin(), sinks_.end(), SinkWrapper(sink));
- DCHECK(it != sinks_.end());
- sinks_.erase(it);
+ frame_deliverer_->RemoveSink(sink);
+}
+
+void MediaStreamVideoTrack::SetEnabled(bool enabled) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ MediaStreamTrack::SetEnabled(enabled);
+
+ frame_deliverer_->SetEnabled(enabled);
+ const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
+ for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
+ it != sinks.end(); ++it) {
+ (*it)->OnEnabledChanged(enabled);
+ }
+}
+
+void MediaStreamVideoTrack::Stop() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (source_) {
+ source_->RemoveTrack(this);
+ source_ = NULL;
+ }
+ OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
+}
+
+void MediaStreamVideoTrack::OnReadyStateChanged(
+ blink::WebMediaStreamSource::ReadyState state) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ const std::vector<MediaStreamVideoSink*>& sinks = frame_deliverer_->sinks();
+ for (std::vector<MediaStreamVideoSink*>::const_iterator it = sinks.begin();
+ it != sinks.end(); ++it) {
+ (*it)->OnReadyStateChanged(state);
+ }
}
} // namespace content