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

Side by Side Diff: content/renderer/media/media_stream_video_track.cc

Issue 155853002: Chrome MediaStream VideoTrack implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Removed whitespaces... Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/media_stream_video_track.h" 5 #include "content/renderer/media/media_stream_video_track.h"
6 6
7 #include "content/renderer/media/media_stream_dependency_factory.h" 7 #include "content/renderer/media/media_stream_dependency_factory.h"
8 #include "content/renderer/media/media_stream_video_source.h"
9 #include "content/renderer/media/webrtc/webrtc_video_sink_adapter.h" 8 #include "content/renderer/media/webrtc/webrtc_video_sink_adapter.h"
10 9
11 namespace content { 10 namespace content {
12 11
13 // Wrapper which allows to use std::find_if() when adding and removing 12 // Empty method used for keeping a reference to the original media::VideoFrame
14 // sinks to/from |sinks_|. 13 // in RTCVideoRenderer::OnVideoFrame if a color conversion between I420 and
15 struct SinkWrapper { 14 // YV12 is needed.
16 explicit SinkWrapper(MediaStreamVideoSink* sink) : sink_(sink) {} 15 static void ReleaseOriginalFrame(
17 bool operator()( 16 const scoped_refptr<media::VideoFrame>& frame) {
18 const WebRtcVideoSinkAdapter* owner) { 17 }
19 return owner->sink() == sink_;
20 }
21 MediaStreamVideoSink* sink_;
22 };
23 18
24 MediaStreamVideoTrack::MediaStreamVideoTrack( 19 //static
25 webrtc::VideoTrackInterface* track) 20 blink::WebMediaStreamTrack MediaStreamVideoTrack::CreateVideoTrack(
26 : MediaStreamTrack(track, false), 21 MediaStreamVideoSource* source,
27 factory_(NULL) { 22 const blink::WebMediaConstraints& constraints,
23 const MediaStreamVideoSource::ConstraintsCallback& callback,
24 bool enabled,
25 MediaStreamDependencyFactory* factory) {
26 blink::WebMediaStreamTrack track;
27 track.initialize(source->owner());
28 track.setExtraData(new MediaStreamVideoTrack(source,
29 constraints,
30 callback,
31 enabled,
32 factory));
33 return track;
34 }
35
36 // static
37 MediaStreamVideoTrack* MediaStreamVideoTrack::GetVideoTrack(
38 const blink::WebMediaStreamTrack& track) {
39 return static_cast<MediaStreamVideoTrack*>(track.extraData());
28 } 40 }
29 41
30 MediaStreamVideoTrack::MediaStreamVideoTrack( 42 MediaStreamVideoTrack::MediaStreamVideoTrack(
43 MediaStreamVideoSource* source,
44 const blink::WebMediaConstraints& constraints,
45 const MediaStreamVideoSource::ConstraintsCallback& callback,
46 bool enabled,
31 MediaStreamDependencyFactory* factory) 47 MediaStreamDependencyFactory* factory)
32 : MediaStreamTrack(NULL, true), 48 : MediaStreamTrack(NULL, true),
49 enabled_(enabled),
50 source_(source),
33 factory_(factory) { 51 factory_(factory) {
34 DCHECK(factory_); 52 // TODO(perkj): source can be NULL if this is actually a remote video track.
53 // Remove as soon as we only have one implementation of video tracks.
54 if (source)
55 source->AddTrack(this, constraints, callback);
35 } 56 }
36 57
37 MediaStreamVideoTrack::~MediaStreamVideoTrack() { 58 MediaStreamVideoTrack::~MediaStreamVideoTrack() {
38 DCHECK(sinks_.empty()); 59 DCHECK(sinks_.empty());
60 // TODO(perkj): source can be NULL if this is actually a remote video track.
61 // Remove as soon as we only have one implementation of video tracks.
62 if (source_)
63 source_->RemoveTrack(this);
39 } 64 }
40 65
41 void MediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink) { 66 void MediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink) {
42 DCHECK(thread_checker_.CalledOnValidThread()); 67 DCHECK(thread_checker_.CalledOnValidThread());
43 DCHECK(std::find_if(sinks_.begin(), sinks_.end(), 68 DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end());
44 SinkWrapper(sink)) == sinks_.end()); 69 sinks_.push_back(sink);
45 sinks_.push_back(new WebRtcVideoSinkAdapter(GetVideoAdapter(), sink));
46 } 70 }
47 71
48 void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) { 72 void MediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) {
49 DCHECK(thread_checker_.CalledOnValidThread()); 73 DCHECK(thread_checker_.CalledOnValidThread());
50 ScopedVector<WebRtcVideoSinkAdapter>::iterator it = 74 std::vector<MediaStreamVideoSink*>::iterator it =
51 std::find_if(sinks_.begin(), sinks_.end(), SinkWrapper(sink)); 75 std::find(sinks_.begin(), sinks_.end(), sink);
52 DCHECK(it != sinks_.end()); 76 DCHECK(it != sinks_.end());
53 sinks_.erase(it); 77 sinks_.erase(it);
54 } 78 }
55 79
56 webrtc::VideoTrackInterface* MediaStreamVideoTrack::GetVideoAdapter() { 80 webrtc::VideoTrackInterface* MediaStreamVideoTrack::GetVideoAdapter() {
81 DCHECK(thread_checker_.CalledOnValidThread());
57 DCHECK_EQ(owner().source().type(), blink::WebMediaStreamSource::TypeVideo); 82 DCHECK_EQ(owner().source().type(), blink::WebMediaStreamSource::TypeVideo);
58 if (!track_.get()) { 83 if (!track_.get()) {
59 MediaStreamVideoSource* source = 84 MediaStreamVideoSource* source =
60 static_cast<MediaStreamVideoSource*>(owner().source().extraData()); 85 static_cast<MediaStreamVideoSource*>(owner().source().extraData());
61 scoped_refptr<webrtc::VideoTrackInterface> video_track( 86 scoped_refptr<webrtc::VideoTrackInterface> video_track(
62 factory_->CreateLocalVideoTrack(owner().id().utf8(), 87 factory_->CreateLocalVideoTrack(owner().id().utf8(),
63 source->GetAdapter())); 88 source->GetAdapter()));
64 video_track->set_enabled(owner().isEnabled()); 89 video_track->set_enabled(owner().isEnabled());
65 track_ = video_track; 90 track_ = video_track;
66 } 91 }
67 return static_cast<webrtc::VideoTrackInterface*>(track_.get()); 92 return static_cast<webrtc::VideoTrackInterface*>(track_.get());
68 } 93 }
69 94
95 void MediaStreamVideoTrack::SetEnabled(bool enabled) {
96 DCHECK(thread_checker_.CalledOnValidThread());
97 enabled_ = enabled;
98 MediaStreamTrack::SetEnabled(enabled);
99 for (std::vector<MediaStreamVideoSink*>::iterator it = sinks_.begin();
100 it != sinks_.end(); ++it) {
101 (*it)->OnEnabledChanged(enabled);
102 }
103 }
104
105 void MediaStreamVideoTrack::OnVideoFrame(
106 const scoped_refptr<media::VideoFrame>& frame) {
107 DCHECK(thread_checker_.CalledOnValidThread());
108 if (!enabled_)
109 return;
110
111 scoped_refptr<media::VideoFrame> video_frame = frame;
112 if (frame->format() == media::VideoFrame::I420) {
113 // Rendering do not support I420 but video capture use I420.
114 // The only difference between YV12 and I420 is the order of U and V plane.
115 // To solve that the I420 frame is simply wrapped in an YV12 video frame.
116 // crbug/341452.
117 video_frame = media::VideoFrame::WrapExternalYuvData(
118 media::VideoFrame::YV12,
119 frame->coded_size(),
120 frame->visible_rect(),
121 frame->natural_size(),
122 frame->stride(media::VideoFrame::kYPlane),
123 frame->stride(media::VideoFrame::kUPlane),
124 frame->stride(media::VideoFrame::kVPlane),
125 frame->data(media::VideoFrame::kYPlane),
126 frame->data(media::VideoFrame::kUPlane),
127 frame->data(media::VideoFrame::kVPlane),
128 frame->GetTimestamp(),
129 base::Bind(&ReleaseOriginalFrame, frame));
130 }
131
132 for (std::vector<MediaStreamVideoSink*>::iterator it = sinks_.begin();
133 it != sinks_.end(); ++it) {
134 (*it)->OnVideoFrame(video_frame);
135 }
136 }
137
138 void MediaStreamVideoTrack::OnReadyStateChanged(
139 blink::WebMediaStreamSource::ReadyState state) {
140 DCHECK(thread_checker_.CalledOnValidThread());
141 for (std::vector<MediaStreamVideoSink*>::iterator it = sinks_.begin();
142 it != sinks_.end(); ++it) {
143 (*it)->OnReadyStateChanged(state);
144 }
145 }
146
147 // Wrapper which allows to use std::find_if() when adding and removing
148 // sinks to/from |sinks_|.
149 struct SinkWrapper {
150 explicit SinkWrapper(MediaStreamVideoSink* sink) : sink_(sink) {}
151 bool operator()(
152 const WebRtcVideoSinkAdapter* owner) {
153 return owner->sink() == sink_;
154 }
155 MediaStreamVideoSink* sink_;
156 };
157
158 WebRtcMediaStreamVideoTrack::WebRtcMediaStreamVideoTrack(
159 webrtc::VideoTrackInterface* track)
160 : MediaStreamVideoTrack(NULL,
161 blink::WebMediaConstraints(),
162 MediaStreamVideoSource::ConstraintsCallback(),
163 track->enabled(),
164 NULL) {
165 track_ = track;
166 }
167
168 WebRtcMediaStreamVideoTrack::~WebRtcMediaStreamVideoTrack() {
169 }
170
171 void WebRtcMediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink) {
172 DCHECK(thread_checker_.CalledOnValidThread());
173 DCHECK(std::find_if(sinks_.begin(), sinks_.end(),
174 SinkWrapper(sink)) == sinks_.end());
175 sinks_.push_back(new WebRtcVideoSinkAdapter(GetVideoAdapter(), sink));
176 }
177
178 void WebRtcMediaStreamVideoTrack::RemoveSink(MediaStreamVideoSink* sink) {
179 DCHECK(thread_checker_.CalledOnValidThread());
180 ScopedVector<WebRtcVideoSinkAdapter>::iterator it =
181 std::find_if(sinks_.begin(), sinks_.end(), SinkWrapper(sink));
182 DCHECK(it != sinks_.end());
183 sinks_.erase(it);
184 }
185
70 } // namespace content 186 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_stream_video_track.h ('k') | content/renderer/media/media_stream_video_track_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698