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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
Jói 2014/01/09 11:18:13 2014
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/webrtc/webrtc_video_source.h"
6
7 #include "content/renderer/media/media_stream_video_track.h"
8 #include "third_party/libjingle/source/talk/app/webrtc/remotevideocapturer.h"
9 #include "third_party/libjingle/source/talk/app/webrtc/videotrackrenderers.h"
10 #include "third_party/libjingle/source/talk/media/base/videoframe.h"
11
12 namespace {
13
14 class FrameInputWrapper : public cricket::VideoRenderer {
15 public:
16 explicit FrameInputWrapper(cricket::VideoCapturer* capturer)
17 : capturer_(capturer) {
18 ASSERT(capturer_ != NULL);
19 }
20
21 virtual ~FrameInputWrapper() {}
22
23 // VideoRenderer implementation.
24 virtual bool SetSize(int width, int height, int reserved) OVERRIDE {
25 return true;
26 }
27
28 virtual bool RenderFrame(const cricket::VideoFrame* frame) OVERRIDE {
29 if (!capturer_->IsRunning()) {
30 return true;
31 }
32
33 // This signal will be made on media engine render thread. The clients
34 // of this signal should have no assumptions on what thread this signal
35 // come from.
36 capturer_->SignalVideoFrame(capturer_, frame);
37 return true;
38 }
39
40 private:
41 cricket::VideoCapturer* capturer_;
42 int width_;
43 int height_;
44
45 DISALLOW_COPY_AND_ASSIGN(FrameInputWrapper);
46 };
47
48 } // anonymous namespace
49
50 namespace content {
51
52 talk_base::scoped_refptr<WebRtcVideoSource> WebRtcVideoSource::Create() {
53 talk_base::scoped_refptr<WebRtcVideoSource> source(
54 new talk_base::RefCountedObject<WebRtcVideoSource>());
55 return source;
56 }
57
58 WebRtcVideoSource::WebRtcVideoSource()
59 : video_capturer_(new webrtc::RemoteVideoCapturer()),
60 // TODO(ronghuawu): Rename RemoteVideoCapturer to be more general purpose.
61 // RemoteVideoCapturer is basically a fake video capturer that wraps a
62 // video frame provider as a cricket::VideoCapturer.
63 frame_input_(new FrameInputWrapper(video_capturer_.get())) {
64 video_capturer_->SignalVideoFrame.connect(
65 this,
66 &WebRtcVideoSource::OnVideoFrame);
67 }
68
69 WebRtcVideoSource::~WebRtcVideoSource() {
70 // Since the signal we're connecting to is multi-threaded,
71 // disconnect_all() will block until all calls are serviced, meaning any
72 // outstanding calls to OnVideoFrame will be done when this is done, and no
73 // more calls will be serviced by this.
74 // We do this explicitly instead of just letting the has_slots<> destructor
75 // take care of it because we need to do this *before* sinks_ is
76 // cleared by the destructor; otherwise we could mess with it while
77 // OnVideoFrame is running.
78 // We *don't* take sinks_crit_ here since it could deadlock with the lock
79 // taken by the video frame signal.
80 disconnect_all();
81 }
82
83 cricket::VideoCapturer* WebRtcVideoSource::GetVideoCapturer() {
84 return video_capturer_.get();
85 }
86
87 void WebRtcVideoSource::AddSink(cricket::VideoRenderer* output) {
88 if (!output) {
89 return;
90 }
91
92 talk_base::CritScope cs(&sinks_crit_);
93 sinks_.push_back(VideoSinkInfo(output));
94 }
95
96 void WebRtcVideoSource::RemoveSink(cricket::VideoRenderer* output) {
97 if (!output) {
98 return;
99 }
100
101 talk_base::CritScope cs(&sinks_crit_);
102 for (VideoSinks::iterator iter = sinks_.begin();
103 iter != sinks_.end(); ++iter) {
104 if (output == iter->sink) {
105 sinks_.erase(iter);
106 break;
107 }
108 }
109 }
110
111 const cricket::VideoOptions* WebRtcVideoSource::options() const {
112 return &options_;
113 }
114
115 webrtc::MediaSourceInterface::SourceState WebRtcVideoSource::state() const {
116 // TODO(ronghuawu): Implement state.
117 return state_;
118 }
119
120 cricket::VideoRenderer* WebRtcVideoSource::FrameInput() {
121 return frame_input_.get();
122 }
123
124 void WebRtcVideoSource::OnVideoFrame(cricket::VideoCapturer* capturer,
125 const cricket::VideoFrame* video_frame) {
126 talk_base::CritScope cs(&sinks_crit_);
127 if (sinks_.empty()) {
128 return;
129 }
130 MaybeSetSize(video_frame);
131 for (VideoSinks::iterator iter = sinks_.begin();
132 iter != sinks_.end(); ++iter) {
133 cricket::VideoRenderer* sink = iter->sink;
134 sink->RenderFrame(video_frame);
135 }
136 }
137
138 void WebRtcVideoSource::MaybeSetSize(const cricket::VideoFrame* frame) {
139 for (VideoSinks::iterator iter = sinks_.begin();
140 iter != sinks_.end(); ++iter) {
141 const bool new_resolution = iter->width != frame->GetWidth() ||
142 iter->height != frame->GetHeight();
143 if (new_resolution) {
144 if (iter->sink->SetSize(static_cast<int>(frame->GetWidth()),
145 static_cast<int>(frame->GetHeight()), 0)) {
146 iter->width = frame->GetWidth();
147 iter->height = frame->GetHeight();
148 }
149 }
150 }
151 }
152
153 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698