Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1732)

Unified Diff: content/renderer/media/webrtc/webrtc_video_source.cc

Issue 129923002: Implements MediaStreamVideoSource. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/webrtc/webrtc_video_source.cc
diff --git a/content/renderer/media/webrtc/webrtc_video_source.cc b/content/renderer/media/webrtc/webrtc_video_source.cc
new file mode 100644
index 0000000000000000000000000000000000000000..05c03cd2b33e1b67fa5c4ac91d68abd0f4d63ada
--- /dev/null
+++ b/content/renderer/media/webrtc/webrtc_video_source.cc
@@ -0,0 +1,153 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
Jói 2014/01/09 11:18:13 2014
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/media/webrtc/webrtc_video_source.h"
+
+#include "content/renderer/media/media_stream_video_track.h"
+#include "third_party/libjingle/source/talk/app/webrtc/remotevideocapturer.h"
+#include "third_party/libjingle/source/talk/app/webrtc/videotrackrenderers.h"
+#include "third_party/libjingle/source/talk/media/base/videoframe.h"
+
+namespace {
+
+class FrameInputWrapper : public cricket::VideoRenderer {
+ public:
+ explicit FrameInputWrapper(cricket::VideoCapturer* capturer)
+ : capturer_(capturer) {
+ ASSERT(capturer_ != NULL);
+ }
+
+ virtual ~FrameInputWrapper() {}
+
+ // VideoRenderer implementation.
+ virtual bool SetSize(int width, int height, int reserved) OVERRIDE {
+ return true;
+ }
+
+ virtual bool RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
+ if (!capturer_->IsRunning()) {
+ return true;
+ }
+
+ // This signal will be made on media engine render thread. The clients
+ // of this signal should have no assumptions on what thread this signal
+ // come from.
+ capturer_->SignalVideoFrame(capturer_, frame);
+ return true;
+ }
+
+ private:
+ cricket::VideoCapturer* capturer_;
+ int width_;
+ int height_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameInputWrapper);
+};
+
+} // anonymous namespace
+
+namespace content {
+
+talk_base::scoped_refptr<WebRtcVideoSource> WebRtcVideoSource::Create() {
+ talk_base::scoped_refptr<WebRtcVideoSource> source(
+ new talk_base::RefCountedObject<WebRtcVideoSource>());
+ return source;
+}
+
+WebRtcVideoSource::WebRtcVideoSource()
+ : video_capturer_(new webrtc::RemoteVideoCapturer()),
+ // TODO(ronghuawu): Rename RemoteVideoCapturer to be more general purpose.
+ // RemoteVideoCapturer is basically a fake video capturer that wraps a
+ // video frame provider as a cricket::VideoCapturer.
+ frame_input_(new FrameInputWrapper(video_capturer_.get())) {
+ video_capturer_->SignalVideoFrame.connect(
+ this,
+ &WebRtcVideoSource::OnVideoFrame);
+}
+
+WebRtcVideoSource::~WebRtcVideoSource() {
+ // Since the signal we're connecting to is multi-threaded,
+ // disconnect_all() will block until all calls are serviced, meaning any
+ // outstanding calls to OnVideoFrame will be done when this is done, and no
+ // more calls will be serviced by this.
+ // We do this explicitly instead of just letting the has_slots<> destructor
+ // take care of it because we need to do this *before* sinks_ is
+ // cleared by the destructor; otherwise we could mess with it while
+ // OnVideoFrame is running.
+ // We *don't* take sinks_crit_ here since it could deadlock with the lock
+ // taken by the video frame signal.
+ disconnect_all();
+}
+
+cricket::VideoCapturer* WebRtcVideoSource::GetVideoCapturer() {
+ return video_capturer_.get();
+}
+
+void WebRtcVideoSource::AddSink(cricket::VideoRenderer* output) {
+ if (!output) {
+ return;
+ }
+
+ talk_base::CritScope cs(&sinks_crit_);
+ sinks_.push_back(VideoSinkInfo(output));
+}
+
+void WebRtcVideoSource::RemoveSink(cricket::VideoRenderer* output) {
+ if (!output) {
+ return;
+ }
+
+ talk_base::CritScope cs(&sinks_crit_);
+ for (VideoSinks::iterator iter = sinks_.begin();
+ iter != sinks_.end(); ++iter) {
+ if (output == iter->sink) {
+ sinks_.erase(iter);
+ break;
+ }
+ }
+}
+
+const cricket::VideoOptions* WebRtcVideoSource::options() const {
+ return &options_;
+}
+
+webrtc::MediaSourceInterface::SourceState WebRtcVideoSource::state() const {
+ // TODO(ronghuawu): Implement state.
+ return state_;
+}
+
+cricket::VideoRenderer* WebRtcVideoSource::FrameInput() {
+ return frame_input_.get();
+}
+
+void WebRtcVideoSource::OnVideoFrame(cricket::VideoCapturer* capturer,
+ const cricket::VideoFrame* video_frame) {
+ talk_base::CritScope cs(&sinks_crit_);
+ if (sinks_.empty()) {
+ return;
+ }
+ MaybeSetSize(video_frame);
+ for (VideoSinks::iterator iter = sinks_.begin();
+ iter != sinks_.end(); ++iter) {
+ cricket::VideoRenderer* sink = iter->sink;
+ sink->RenderFrame(video_frame);
+ }
+}
+
+void WebRtcVideoSource::MaybeSetSize(const cricket::VideoFrame* frame) {
+ for (VideoSinks::iterator iter = sinks_.begin();
+ iter != sinks_.end(); ++iter) {
+ const bool new_resolution = iter->width != frame->GetWidth() ||
+ iter->height != frame->GetHeight();
+ if (new_resolution) {
+ if (iter->sink->SetSize(static_cast<int>(frame->GetWidth()),
+ static_cast<int>(frame->GetHeight()), 0)) {
+ iter->width = frame->GetWidth();
+ iter->height = frame->GetHeight();
+ }
+ }
+ }
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698