summaryrefslogtreecommitdiffstats
path: root/content/renderer/media
diff options
context:
space:
mode:
authorvrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-09 21:16:52 +0000
committervrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-09 21:16:52 +0000
commitc6d743ef45ab10d0e014dd07b81de10a9aaa3e0c (patch)
tree9b3f3ea6407dd07ae3bb1cdbbed129e3f528283b /content/renderer/media
parent23bb07d9ff721a6a716294f2d54b5af3493557c2 (diff)
downloadchromium_src-c6d743ef45ab10d0e014dd07b81de10a9aaa3e0c.zip
chromium_src-c6d743ef45ab10d0e014dd07b81de10a9aaa3e0c.tar.gz
chromium_src-c6d743ef45ab10d0e014dd07b81de10a9aaa3e0c.tar.bz2
Revert 262050 "Implement a source for remote video tracks."
> Implement a source for remote video tracks. > MediaStreamRemoteVideoSource implements the MediaStreamVideoSource interface > for video tracks received on a PeerConnection. The purpose of the class is > to make sure there is no difference between a video track where the source is > a local source and a video track where the source is a remote video track. > > BUG=334243 > > Review URL: https://codereview.chromium.org/201583003 This caused remote video to appear unexpectedly zoomed and cropped. BUG=334243,361770 TBR=perkj@chromium.org Review URL: https://codereview.chromium.org/231963002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262819 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/media')
-rw-r--r--content/renderer/media/media_stream_center.cc7
-rw-r--r--content/renderer/media/media_stream_dependency_factory.cc20
-rw-r--r--content/renderer/media/media_stream_dependency_factory.h2
-rw-r--r--content/renderer/media/media_stream_video_source.cc1
-rw-r--r--content/renderer/media/media_stream_video_source.h4
-rw-r--r--content/renderer/media/media_stream_video_track.cc50
-rw-r--r--content/renderer/media/media_stream_video_track.h21
-rw-r--r--content/renderer/media/mock_media_stream_dependency_factory.cc43
-rw-r--r--content/renderer/media/mock_media_stream_dependency_factory.h7
-rw-r--r--content/renderer/media/remote_media_stream_impl.cc163
-rw-r--r--content/renderer/media/remote_media_stream_impl.h6
-rw-r--r--content/renderer/media/rtc_peer_connection_handler_unittest.cc38
-rw-r--r--content/renderer/media/webrtc/media_stream_remote_video_source.cc157
-rw-r--r--content/renderer/media/webrtc/media_stream_remote_video_source.h74
-rw-r--r--content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc160
-rw-r--r--content/renderer/media/webrtc/webrtc_video_sink_adapter.cc118
-rw-r--r--content/renderer/media/webrtc/webrtc_video_sink_adapter.h60
17 files changed, 365 insertions, 566 deletions
diff --git a/content/renderer/media/media_stream_center.cc b/content/renderer/media/media_stream_center.cc
index e568567..dea0f92a 100644
--- a/content/renderer/media/media_stream_center.cc
+++ b/content/renderer/media/media_stream_center.cc
@@ -52,7 +52,12 @@ void CreateNativeVideoMediaStreamTrack(
DCHECK_EQ(source.type(), blink::WebMediaStreamSource::TypeVideo);
MediaStreamVideoSource* native_source =
MediaStreamVideoSource::GetVideoSource(source);
- DCHECK(native_source);
+ if (!native_source) {
+ // TODO(perkj): Implement support for sources from
+ // remote MediaStreams.
+ NOTIMPLEMENTED();
+ return;
+ }
blink::WebMediaStreamTrack writable_track(track);
writable_track.setExtraData(
new MediaStreamVideoTrack(native_source, source.constraints(),
diff --git a/content/renderer/media/media_stream_dependency_factory.cc b/content/renderer/media/media_stream_dependency_factory.cc
index 70f3d06..fef5308 100644
--- a/content/renderer/media/media_stream_dependency_factory.cc
+++ b/content/renderer/media/media_stream_dependency_factory.cc
@@ -678,20 +678,24 @@ MediaStreamDependencyFactory::CreateAudioCapturer(
GetWebRtcAudioDevice());
}
-void MediaStreamDependencyFactory::AddNativeAudioTrackToBlinkTrack(
+void MediaStreamDependencyFactory::AddNativeTrackToBlinkTrack(
webrtc::MediaStreamTrackInterface* native_track,
const blink::WebMediaStreamTrack& webkit_track,
bool is_local_track) {
DCHECK(!webkit_track.isNull() && !webkit_track.extraData());
- DCHECK_EQ(blink::WebMediaStreamSource::TypeAudio,
- webkit_track.source().type());
blink::WebMediaStreamTrack track = webkit_track;
- DVLOG(1) << "AddNativeTrackToBlinkTrack() audio";
- track.setExtraData(
- new MediaStreamTrack(
- static_cast<webrtc::AudioTrackInterface*>(native_track),
- is_local_track));
+ if (track.source().type() == blink::WebMediaStreamSource::TypeVideo) {
+ DVLOG(1) << "AddNativeTrackToBlinkTrack() video";
+ track.setExtraData(new WebRtcMediaStreamVideoTrack(
+ static_cast<webrtc::VideoTrackInterface*>(native_track)));
+ } else {
+ DVLOG(1) << "AddNativeTrackToBlinkTrack() audio";
+ track.setExtraData(
+ new MediaStreamTrack(
+ static_cast<webrtc::AudioTrackInterface*>(native_track),
+ is_local_track));
+ }
}
bool MediaStreamDependencyFactory::OnControlMessageReceived(
diff --git a/content/renderer/media/media_stream_dependency_factory.h b/content/renderer/media/media_stream_dependency_factory.h
index 5986abb..accac97 100644
--- a/content/renderer/media/media_stream_dependency_factory.h
+++ b/content/renderer/media/media_stream_dependency_factory.h
@@ -136,7 +136,7 @@ class CONTENT_EXPORT MediaStreamDependencyFactory
WebRtcAudioDeviceImpl* GetWebRtcAudioDevice();
- static void AddNativeAudioTrackToBlinkTrack(
+ static void AddNativeTrackToBlinkTrack(
webrtc::MediaStreamTrackInterface* native_track,
const blink::WebMediaStreamTrack& webkit_track,
bool is_local_track);
diff --git a/content/renderer/media/media_stream_video_source.cc b/content/renderer/media/media_stream_video_source.cc
index 51da6bb..6091726 100644
--- a/content/renderer/media/media_stream_video_source.cc
+++ b/content/renderer/media/media_stream_video_source.cc
@@ -308,6 +308,7 @@ MediaStreamVideoSource::MediaStreamVideoSource(
: state_(NEW),
factory_(factory),
capture_adapter_(NULL) {
+ DCHECK(factory_);
}
MediaStreamVideoSource::~MediaStreamVideoSource() {
diff --git a/content/renderer/media/media_stream_video_source.h b/content/renderer/media/media_stream_video_source.h
index af33b4e..b080a47 100644
--- a/content/renderer/media/media_stream_video_source.h
+++ b/content/renderer/media/media_stream_video_source.h
@@ -64,7 +64,7 @@ class CONTENT_EXPORT MediaStreamVideoSource
// interface of this class.
// This creates a VideoSourceInterface implementation if it does not already
// exist.
- virtual webrtc::VideoSourceInterface* GetAdapter();
+ webrtc::VideoSourceInterface* GetAdapter();
// Return true if |name| is a constraint supported by MediaStreamVideoSource.
static bool IsConstraintSupported(const std::string& name);
@@ -130,7 +130,7 @@ class CONTENT_EXPORT MediaStreamVideoSource
STARTED,
ENDED
};
- State state() const { return state_; }
+ State state() { return state_; }
private:
// Creates a webrtc::VideoSourceInterface used by libjingle.
diff --git a/content/renderer/media/media_stream_video_track.cc b/content/renderer/media/media_stream_video_track.cc
index 8d4b83d..3cf98cd 100644
--- a/content/renderer/media/media_stream_video_track.cc
+++ b/content/renderer/media/media_stream_video_track.cc
@@ -5,6 +5,7 @@
#include "content/renderer/media/media_stream_video_track.h"
#include "content/renderer/media/media_stream_dependency_factory.h"
+#include "content/renderer/media/webrtc/webrtc_video_sink_adapter.h"
namespace content {
@@ -41,12 +42,18 @@ MediaStreamVideoTrack::MediaStreamVideoTrack(
enabled_(enabled),
source_(source),
factory_(factory) {
- source->AddTrack(this, constraints, callback);
+ // TODO(perkj): source can be NULL if this is actually a remote video track.
+ // Remove as soon as we only have one implementation of video tracks.
+ if (source)
+ source->AddTrack(this, constraints, callback);
}
MediaStreamVideoTrack::~MediaStreamVideoTrack() {
DCHECK(sinks_.empty());
- source_->RemoveTrack(this);
+ // TODO(perkj): source can be NULL if this is actually a remote video track.
+ // Remove as soon as we only have one implementation of video tracks.
+ if (source_)
+ source_->RemoveTrack(this);
}
void MediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink) {
@@ -109,4 +116,43 @@ void MediaStreamVideoTrack::OnReadyStateChanged(
}
}
+// 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_;
+ }
+ MediaStreamVideoSink* sink_;
+};
+
+WebRtcMediaStreamVideoTrack::WebRtcMediaStreamVideoTrack(
+ webrtc::VideoTrackInterface* track)
+ : MediaStreamVideoTrack(NULL,
+ blink::WebMediaConstraints(),
+ MediaStreamVideoSource::ConstraintsCallback(),
+ track->enabled(),
+ NULL) {
+ track_ = track;
+}
+
+WebRtcMediaStreamVideoTrack::~WebRtcMediaStreamVideoTrack() {
+}
+
+void WebRtcMediaStreamVideoTrack::AddSink(MediaStreamVideoSink* sink) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(std::find_if(sinks_.begin(), sinks_.end(),
+ SinkWrapper(sink)) == sinks_.end());
+ sinks_.push_back(new WebRtcVideoSinkAdapter(GetVideoAdapter(), sink));
+}
+
+void WebRtcMediaStreamVideoTrack::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);
+}
+
} // namespace content
diff --git a/content/renderer/media/media_stream_video_track.h b/content/renderer/media/media_stream_video_track.h
index 07307ae..16c0a91 100644
--- a/content/renderer/media/media_stream_video_track.h
+++ b/content/renderer/media/media_stream_video_track.h
@@ -22,6 +22,7 @@ class VideoTrackInterface;
namespace content {
class MediaStreamDependencyFactory;
+class WebRtcVideoSinkAdapter;
// MediaStreamVideoTrack is a video specific representation of a
// blink::WebMediaStreamTrack in content. It is owned by the blink object
@@ -86,6 +87,26 @@ class CONTENT_EXPORT MediaStreamVideoTrack : public MediaStreamTrack {
DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoTrack);
};
+// WebRtcMediaStreamVideoTrack is a content representation of a video track.
+// received on a PeerConnection.
+// TODO(perkj): Replace WebRtcMediaStreamVideoTrack with a remote
+// MediaStreamVideoSource class so that all tracks are MediaStreamVideoTracks
+// and new tracks can be cloned from the original remote video track.
+// crbug/334243.
+class CONTENT_EXPORT WebRtcMediaStreamVideoTrack
+ : public MediaStreamVideoTrack {
+ public:
+ explicit WebRtcMediaStreamVideoTrack(webrtc::VideoTrackInterface* track);
+ virtual ~WebRtcMediaStreamVideoTrack();
+ virtual void AddSink(MediaStreamVideoSink* sink) OVERRIDE;
+ virtual void RemoveSink(MediaStreamVideoSink* sink) OVERRIDE;
+
+ private:
+ ScopedVector<WebRtcVideoSinkAdapter> sinks_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcMediaStreamVideoTrack);
+};
+
} // namespace content
#endif // CONTENT_RENDERER_MEDIA_MEDIA_STREAM_VIDEO_TRACK_H_
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.cc b/content/renderer/media/mock_media_stream_dependency_factory.cc
index d07cb3a..1441d32 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.cc
+++ b/content/renderer/media/mock_media_stream_dependency_factory.cc
@@ -283,64 +283,60 @@ int MockVideoSource::GetFrameNum() const {
return static_cast<MockRtcVideoCapturer*>(capturer_.get())->GetFrameNum();
}
-MockWebRtcVideoTrack::MockWebRtcVideoTrack(
- std::string id,
- webrtc::VideoSourceInterface* source)
+MockLocalVideoTrack::MockLocalVideoTrack(std::string id,
+ webrtc::VideoSourceInterface* source)
: enabled_(false),
id_(id),
state_(MediaStreamTrackInterface::kLive),
source_(source),
- observer_(NULL),
- renderer_(NULL) {
+ observer_(NULL) {
}
-MockWebRtcVideoTrack::~MockWebRtcVideoTrack() {}
+MockLocalVideoTrack::~MockLocalVideoTrack() {}
-void MockWebRtcVideoTrack::AddRenderer(VideoRendererInterface* renderer) {
- DCHECK(!renderer_);
- renderer_ = renderer;
+void MockLocalVideoTrack::AddRenderer(VideoRendererInterface* renderer) {
+ NOTIMPLEMENTED();
}
-void MockWebRtcVideoTrack::RemoveRenderer(VideoRendererInterface* renderer) {
- DCHECK_EQ(renderer_, renderer);
- renderer_ = NULL;
+void MockLocalVideoTrack::RemoveRenderer(VideoRendererInterface* renderer) {
+ NOTIMPLEMENTED();
}
-std::string MockWebRtcVideoTrack::kind() const {
+std::string MockLocalVideoTrack::kind() const {
NOTIMPLEMENTED();
return std::string();
}
-std::string MockWebRtcVideoTrack::id() const { return id_; }
+std::string MockLocalVideoTrack::id() const { return id_; }
-bool MockWebRtcVideoTrack::enabled() const { return enabled_; }
+bool MockLocalVideoTrack::enabled() const { return enabled_; }
-MockWebRtcVideoTrack::TrackState MockWebRtcVideoTrack::state() const {
+MockLocalVideoTrack::TrackState MockLocalVideoTrack::state() const {
return state_;
}
-bool MockWebRtcVideoTrack::set_enabled(bool enable) {
+bool MockLocalVideoTrack::set_enabled(bool enable) {
enabled_ = enable;
return true;
}
-bool MockWebRtcVideoTrack::set_state(TrackState new_state) {
+bool MockLocalVideoTrack::set_state(TrackState new_state) {
state_ = new_state;
if (observer_)
observer_->OnChanged();
return true;
}
-void MockWebRtcVideoTrack::RegisterObserver(ObserverInterface* observer) {
+void MockLocalVideoTrack::RegisterObserver(ObserverInterface* observer) {
observer_ = observer;
}
-void MockWebRtcVideoTrack::UnregisterObserver(ObserverInterface* observer) {
+void MockLocalVideoTrack::UnregisterObserver(ObserverInterface* observer) {
DCHECK(observer_ == observer);
observer_ = NULL;
}
-VideoSourceInterface* MockWebRtcVideoTrack::GetSource() const {
+VideoSourceInterface* MockLocalVideoTrack::GetSource() const {
return source_.get();
}
@@ -484,7 +480,7 @@ MockMediaStreamDependencyFactory::CreateLocalVideoTrack(
const std::string& id,
webrtc::VideoSourceInterface* source) {
scoped_refptr<webrtc::VideoTrackInterface> track(
- new talk_base::RefCountedObject<MockWebRtcVideoTrack>(
+ new talk_base::RefCountedObject<MockLocalVideoTrack>(
id, source));
return track;
}
@@ -497,8 +493,7 @@ MockMediaStreamDependencyFactory::CreateLocalVideoTrack(
new talk_base::RefCountedObject<MockVideoSource>();
source->SetVideoCapturer(capturer);
- return
- new talk_base::RefCountedObject<MockWebRtcVideoTrack>(id, source.get());
+ return new talk_base::RefCountedObject<MockLocalVideoTrack>(id, source.get());
}
SessionDescriptionInterface*
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.h b/content/renderer/media/mock_media_stream_dependency_factory.h
index a2cce87..05cd5c7 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.h
+++ b/content/renderer/media/mock_media_stream_dependency_factory.h
@@ -104,9 +104,9 @@ class MockAudioSource : public webrtc::AudioSourceInterface {
webrtc::MediaConstraintsInterface::Constraints mandatory_constraints_;
};
-class MockWebRtcVideoTrack : public webrtc::VideoTrackInterface {
+class MockLocalVideoTrack : public webrtc::VideoTrackInterface {
public:
- MockWebRtcVideoTrack(std::string id,
+ MockLocalVideoTrack(std::string id,
webrtc::VideoSourceInterface* source);
virtual void AddRenderer(webrtc::VideoRendererInterface* renderer) OVERRIDE;
virtual void RemoveRenderer(
@@ -122,7 +122,7 @@ class MockWebRtcVideoTrack : public webrtc::VideoTrackInterface {
virtual webrtc::VideoSourceInterface* GetSource() const OVERRIDE;
protected:
- virtual ~MockWebRtcVideoTrack();
+ virtual ~MockLocalVideoTrack();
private:
bool enabled_;
@@ -130,7 +130,6 @@ class MockWebRtcVideoTrack : public webrtc::VideoTrackInterface {
TrackState state_;
scoped_refptr<webrtc::VideoSourceInterface> source_;
webrtc::ObserverInterface* observer_;
- webrtc::VideoRendererInterface* renderer_;
};
class MockMediaStream : public webrtc::MediaStreamInterface {
diff --git a/content/renderer/media/remote_media_stream_impl.cc b/content/renderer/media/remote_media_stream_impl.cc
index 1510607b..66bdb60 100644
--- a/content/renderer/media/remote_media_stream_impl.cc
+++ b/content/renderer/media/remote_media_stream_impl.cc
@@ -10,131 +10,86 @@
#include "base/strings/utf_string_conversions.h"
#include "content/renderer/media/media_stream.h"
#include "content/renderer/media/media_stream_dependency_factory.h"
-#include "content/renderer/media/media_stream_video_track.h"
-#include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
-#include "content/renderer/render_thread_impl.h"
#include "third_party/WebKit/public/platform/WebString.h"
namespace content {
-namespace {
-
-void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track,
- blink::WebMediaStreamTrack* webkit_track,
- blink::WebMediaStreamSource::Type type) {
- blink::WebMediaStreamSource webkit_source;
- blink::WebString webkit_track_id(base::UTF8ToUTF16(track->id()));
-
- webkit_source.initialize(webkit_track_id, type, webkit_track_id);
- webkit_track->initialize(webkit_track_id, webkit_source);
-
- MediaStreamDependencyFactory* factory = NULL;
- // RenderThreadImpl::current() may be NULL in unit tests.
- RenderThreadImpl* render_thread = RenderThreadImpl::current();
- if (render_thread)
- factory = render_thread->GetMediaStreamDependencyFactory();
-
- if (type == blink::WebMediaStreamSource::TypeVideo) {
- MediaStreamRemoteVideoSource* video_source =
- new MediaStreamRemoteVideoSource(
- static_cast<webrtc::VideoTrackInterface*>(track));
- webkit_source.setExtraData(video_source);
- // Initial constraints must be provided to a MediaStreamVideoTrack. But
- // no constraints are available initially on a remote video track.
- blink::WebMediaConstraints constraints;
- constraints.initialize();
- webkit_track->setExtraData(
- new MediaStreamVideoTrack(video_source, constraints,
- MediaStreamVideoSource::ConstraintsCallback(),
- track->enabled(), factory));
- } else {
- DCHECK(type == blink::WebMediaStreamSource::TypeAudio);
- content::MediaStreamDependencyFactory::AddNativeAudioTrackToBlinkTrack(
- track, *webkit_track, false);
- }
-}
-
-} // namespace
-
-// Base class used for mapping between webrtc and blink MediaStream tracks.
-// An instance of a RemoteMediaStreamTrackAdapter is stored in
-// RemoteMediaStreamImpl per remote audio and video track.
-class RemoteMediaStreamTrackAdapter {
+// RemoteMediaStreamTrackObserver is responsible for listening on change
+// notification on a remote webrtc MediaStreamTrack and notify WebKit.
+class RemoteMediaStreamTrackObserver
+ : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
+ NON_EXPORTED_BASE(public base::NonThreadSafe) {
public:
- RemoteMediaStreamTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track,
- const blink::WebMediaStreamTrack& webkit_track)
- : webrtc_track_(webrtc_track),
- webkit_track_(webkit_track) {
- }
-
- virtual ~RemoteMediaStreamTrackAdapter() {
- }
+ RemoteMediaStreamTrackObserver(
+ webrtc::MediaStreamTrackInterface* webrtc_track,
+ const blink::WebMediaStreamTrack& webkit_track);
+ virtual ~RemoteMediaStreamTrackObserver();
- webrtc::MediaStreamTrackInterface* observed_track() {
+ webrtc::MediaStreamTrackInterface* observered_track() {
return webrtc_track_.get();
}
-
const blink::WebMediaStreamTrack& webkit_track() { return webkit_track_; }
private:
+ // webrtc::ObserverInterface implementation.
+ virtual void OnChanged() OVERRIDE;
+
+ webrtc::MediaStreamTrackInterface::TrackState state_;
scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
blink::WebMediaStreamTrack webkit_track_;
- bool sent_ended_message_;
- DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter);
+ DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackObserver);
};
-static content::RemoteMediaStreamTrackAdapter* FindTrackObserver(
- webrtc::MediaStreamTrackInterface* track,
- const ScopedVector<content::RemoteMediaStreamTrackAdapter>& observers) {
- ScopedVector<content::RemoteMediaStreamTrackAdapter>::const_iterator it =
+} // namespace content
+
+namespace {
+
+void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track,
+ blink::WebMediaStreamTrack* webkit_track,
+ blink::WebMediaStreamSource::Type type) {
+ blink::WebMediaStreamSource webkit_source;
+ blink::WebString webkit_track_id(base::UTF8ToUTF16(track->id()));
+
+ webkit_source.initialize(webkit_track_id, type, webkit_track_id);
+ webkit_track->initialize(webkit_track_id, webkit_source);
+ content::MediaStreamDependencyFactory::AddNativeTrackToBlinkTrack(
+ track, *webkit_track, false);
+}
+
+content::RemoteMediaStreamTrackObserver* FindTrackObserver(
+ webrtc::MediaStreamTrackInterface* track,
+ const ScopedVector<content::RemoteMediaStreamTrackObserver>& observers) {
+ ScopedVector<content::RemoteMediaStreamTrackObserver>::const_iterator it =
observers.begin();
for (; it != observers.end(); ++it) {
- if ((*it)->observed_track() == track)
+ if ((*it)->observered_track() == track)
return *it;
}
return NULL;
}
-// RemoteAudioMediaStreamTrackAdapter is responsible for listening on state
-// change notifications on a remote webrtc audio MediaStreamTracks and notify
-// WebKit.
-class RemoteAudioMediaStreamTrackAdapter
- : public RemoteMediaStreamTrackAdapter,
- public webrtc::ObserverInterface,
- public base::NonThreadSafe {
- public:
- RemoteAudioMediaStreamTrackAdapter(
- webrtc::MediaStreamTrackInterface* webrtc_track,
- const blink::WebMediaStreamTrack& webkit_track);
- virtual ~RemoteAudioMediaStreamTrackAdapter();
-
- private:
- // webrtc::ObserverInterface implementation.
- virtual void OnChanged() OVERRIDE;
-
- webrtc::MediaStreamTrackInterface::TrackState state_;
+} // namespace anonymous
- DISALLOW_COPY_AND_ASSIGN(RemoteAudioMediaStreamTrackAdapter);
-};
+namespace content {
-RemoteAudioMediaStreamTrackAdapter::RemoteAudioMediaStreamTrackAdapter(
+RemoteMediaStreamTrackObserver::RemoteMediaStreamTrackObserver(
webrtc::MediaStreamTrackInterface* webrtc_track,
const blink::WebMediaStreamTrack& webkit_track)
- : RemoteMediaStreamTrackAdapter(webrtc_track, webkit_track),
- state_(observed_track()->state()) {
- observed_track()->RegisterObserver(this);
+ : state_(webrtc_track->state()),
+ webrtc_track_(webrtc_track),
+ webkit_track_(webkit_track) {
+ webrtc_track->RegisterObserver(this);
}
-RemoteAudioMediaStreamTrackAdapter::~RemoteAudioMediaStreamTrackAdapter() {
- observed_track()->UnregisterObserver(this);
+RemoteMediaStreamTrackObserver::~RemoteMediaStreamTrackObserver() {
+ webrtc_track_->UnregisterObserver(this);
}
-void RemoteAudioMediaStreamTrackAdapter::OnChanged() {
+void RemoteMediaStreamTrackObserver::OnChanged() {
DCHECK(CalledOnValidThread());
- webrtc::MediaStreamTrackInterface::TrackState state =
- observed_track()->state();
+ webrtc::MediaStreamTrackInterface::TrackState state = webrtc_track_->state();
if (state == state_)
return;
@@ -145,11 +100,11 @@ void RemoteAudioMediaStreamTrackAdapter::OnChanged() {
// WebMediaStreamSource::ReadyState.
break;
case webrtc::MediaStreamTrackInterface::kLive:
- webkit_track().source().setReadyState(
+ webkit_track_.source().setReadyState(
blink::WebMediaStreamSource::ReadyStateLive);
break;
case webrtc::MediaStreamTrackInterface::kEnded:
- webkit_track().source().setReadyState(
+ webkit_track_.source().setReadyState(
blink::WebMediaStreamSource::ReadyStateEnded);
break;
default:
@@ -176,8 +131,8 @@ RemoteMediaStreamImpl::RemoteMediaStreamImpl(
InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i],
blink::WebMediaStreamSource::TypeAudio);
audio_track_observers_.push_back(
- new RemoteAudioMediaStreamTrackAdapter(audio_track,
- webkit_audio_tracks[i]));
+ new RemoteMediaStreamTrackObserver(audio_track,
+ webkit_audio_tracks[i]));
}
// Initialize WebKit video tracks.
@@ -191,8 +146,8 @@ RemoteMediaStreamImpl::RemoteMediaStreamImpl(
InitializeWebkitTrack(video_track, &webkit_video_tracks[i],
blink::WebMediaStreamSource::TypeVideo);
video_track_observers_.push_back(
- new RemoteMediaStreamTrackAdapter(video_track,
- webkit_video_tracks[i]));
+ new RemoteMediaStreamTrackObserver(video_track,
+ webkit_video_tracks[i]));
}
webkit_stream_.initialize(base::UTF8ToUTF16(webrtc_stream->label()),
@@ -206,10 +161,10 @@ RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
void RemoteMediaStreamImpl::OnChanged() {
// Find removed audio tracks.
- ScopedVector<RemoteMediaStreamTrackAdapter>::iterator audio_it =
+ ScopedVector<RemoteMediaStreamTrackObserver>::iterator audio_it =
audio_track_observers_.begin();
while (audio_it != audio_track_observers_.end()) {
- std::string track_id = (*audio_it)->observed_track()->id();
+ std::string track_id = (*audio_it)->observered_track()->id();
if (webrtc_stream_->FindAudioTrack(track_id) == NULL) {
webkit_stream_.removeTrack((*audio_it)->webkit_track());
audio_it = audio_track_observers_.erase(audio_it);
@@ -219,10 +174,10 @@ void RemoteMediaStreamImpl::OnChanged() {
}
// Find removed video tracks.
- ScopedVector<RemoteMediaStreamTrackAdapter>::iterator video_it =
+ ScopedVector<RemoteMediaStreamTrackObserver>::iterator video_it =
video_track_observers_.begin();
while (video_it != video_track_observers_.end()) {
- std::string track_id = (*video_it)->observed_track()->id();
+ std::string track_id = (*video_it)->observered_track()->id();
if (webrtc_stream_->FindVideoTrack(track_id) == NULL) {
webkit_stream_.removeTrack((*video_it)->webkit_track());
video_it = video_track_observers_.erase(video_it);
@@ -241,7 +196,7 @@ void RemoteMediaStreamImpl::OnChanged() {
InitializeWebkitTrack(*it, &new_track,
blink::WebMediaStreamSource::TypeAudio);
audio_track_observers_.push_back(
- new RemoteAudioMediaStreamTrackAdapter(*it, new_track));
+ new RemoteMediaStreamTrackObserver(*it, new_track));
webkit_stream_.addTrack(new_track);
}
}
@@ -256,7 +211,7 @@ void RemoteMediaStreamImpl::OnChanged() {
InitializeWebkitTrack(*it, &new_track,
blink::WebMediaStreamSource::TypeVideo);
video_track_observers_.push_back(
- new RemoteMediaStreamTrackAdapter(*it, new_track));
+ new RemoteMediaStreamTrackObserver(*it, new_track));
webkit_stream_.addTrack(new_track);
}
}
diff --git a/content/renderer/media/remote_media_stream_impl.h b/content/renderer/media/remote_media_stream_impl.h
index 6b1554a..3263ed4 100644
--- a/content/renderer/media/remote_media_stream_impl.h
+++ b/content/renderer/media/remote_media_stream_impl.h
@@ -18,7 +18,7 @@
namespace content {
-class RemoteMediaStreamTrackAdapter;
+class RemoteMediaStreamTrackObserver;
// RemoteMediaStreamImpl serves as a container and glue between remote webrtc
// MediaStreams and WebKit MediaStreams. For each remote MediaStream received
@@ -39,8 +39,8 @@ class CONTENT_EXPORT RemoteMediaStreamImpl
virtual void OnChanged() OVERRIDE;
scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream_;
- ScopedVector<RemoteMediaStreamTrackAdapter> video_track_observers_;
- ScopedVector<RemoteMediaStreamTrackAdapter> audio_track_observers_;
+ ScopedVector<RemoteMediaStreamTrackObserver> audio_track_observers_;
+ ScopedVector<RemoteMediaStreamTrackObserver> video_track_observers_;
blink::WebMediaStream webkit_stream_;
DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamImpl);
diff --git a/content/renderer/media/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
index 17cf4e8..c2b21dc 100644
--- a/content/renderer/media/rtc_peer_connection_handler_unittest.cc
+++ b/content/renderer/media/rtc_peer_connection_handler_unittest.cc
@@ -288,7 +288,6 @@ class RTCPeerConnectionHandlerTest : public ::testing::Test {
return stream;
}
- base::MessageLoop message_loop_;
scoped_ptr<MockWebRTCPeerConnectionHandlerClient> mock_client_;
scoped_ptr<MockMediaStreamDependencyFactory> mock_dependency_factory_;
scoped_ptr<NiceMock<MockPeerConnectionTracker> > mock_tracker_;
@@ -740,24 +739,17 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddAudioTrackFromRemoteStream) {
pc_handler_->OnAddStream(remote_stream.get());
const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();
- {
- // Test in a small scope so that |audio_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
- webkit_stream.audioTracks(audio_tracks);
- EXPECT_EQ(1u, audio_tracks.size());
- }
+ blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
+ webkit_stream.audioTracks(audio_tracks);
+ EXPECT_EQ(1u, audio_tracks.size());
// Remove the Webrtc audio track from the Webrtc MediaStream.
scoped_refptr<webrtc::AudioTrackInterface> webrtc_track =
remote_stream->GetAudioTracks()[0].get();
remote_stream->RemoveTrack(webrtc_track.get());
-
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks1;
- webkit_stream.audioTracks(modified_audio_tracks1);
- EXPECT_EQ(0u, modified_audio_tracks1.size());
- }
+ blink::WebVector<blink::WebMediaStreamTrack> modified_audio_tracks1;
+ webkit_stream.audioTracks(modified_audio_tracks1);
+ EXPECT_EQ(0u, modified_audio_tracks1.size());
// Add the WebRtc audio track again.
remote_stream->AddTrack(webrtc_track.get());
@@ -777,23 +769,17 @@ TEST_F(RTCPeerConnectionHandlerTest, RemoveAndAddVideoTrackFromRemoteStream) {
pc_handler_->OnAddStream(remote_stream.get());
const blink::WebMediaStream& webkit_stream = mock_client_->remote_stream();
- {
- // Test in a small scope so that |video_tracks| don't hold on to destroyed
- // source later.
- blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
- webkit_stream.videoTracks(video_tracks);
- EXPECT_EQ(1u, video_tracks.size());
- }
+ blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
+ webkit_stream.videoTracks(video_tracks);
+ EXPECT_EQ(1u, video_tracks.size());
// Remove the Webrtc video track from the Webrtc MediaStream.
scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
remote_stream->GetVideoTracks()[0].get();
remote_stream->RemoveTrack(webrtc_track.get());
- {
- blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks1;
- webkit_stream.videoTracks(modified_video_tracks1);
- EXPECT_EQ(0u, modified_video_tracks1.size());
- }
+ blink::WebVector<blink::WebMediaStreamTrack> modified_video_tracks1;
+ webkit_stream.videoTracks(modified_video_tracks1);
+ EXPECT_EQ(0u, modified_video_tracks1.size());
// Add the WebRtc video track again.
remote_stream->AddTrack(webrtc_track.get());
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
deleted file mode 100644
index 50468af..0000000
--- a/content/renderer/media/webrtc/media_stream_remote_video_source.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// 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/media_stream_remote_video_source.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "content/renderer/media/native_handle_impl.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_util.h"
-#include "third_party/libjingle/source/talk/media/base/videoframe.h"
-
-namespace content {
-
-MediaStreamRemoteVideoSource::MediaStreamRemoteVideoSource(
- webrtc::VideoTrackInterface* remote_track)
- : MediaStreamVideoSource(NULL),
- message_loop_proxy_(base::MessageLoopProxy::current()),
- remote_track_(remote_track),
- last_state_(remote_track_->state()),
- first_frame_received_(false) {
- remote_track_->AddRenderer(this);
- remote_track_->RegisterObserver(this);
-}
-
-MediaStreamRemoteVideoSource::~MediaStreamRemoteVideoSource() {
- StopSourceImpl();
-}
-
-void MediaStreamRemoteVideoSource::GetCurrentSupportedFormats(
- int max_requested_width,
- int max_requested_height) {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- if (format_.IsValid()) {
- media::VideoCaptureFormats formats;
- formats.push_back(format_);
- OnSupportedFormats(formats);
- }
-}
-
-void MediaStreamRemoteVideoSource::StartSourceImpl(
- const media::VideoCaptureParams& params) {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- OnStartDone(true);
-}
-
-void MediaStreamRemoteVideoSource::StopSourceImpl() {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- remote_track_->RemoveRenderer(this);
- remote_track_->UnregisterObserver(this);
-}
-
-webrtc::VideoSourceInterface* MediaStreamRemoteVideoSource::GetAdapter() {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- return remote_track_->GetSource();
-}
-
-void MediaStreamRemoteVideoSource::SetSize(int width, int height) {
-}
-
-void MediaStreamRemoteVideoSource::RenderFrame(
- const cricket::VideoFrame* frame) {
- base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(
- frame->GetTimeStamp() / talk_base::kNumNanosecsPerMillisec);
-
- scoped_refptr<media::VideoFrame> video_frame;
- if (frame->GetNativeHandle() != NULL) {
- NativeHandleImpl* handle =
- static_cast<NativeHandleImpl*>(frame->GetNativeHandle());
- video_frame = static_cast<media::VideoFrame*>(handle->GetHandle());
- video_frame->SetTimestamp(timestamp);
- } else {
- gfx::Size size(frame->GetWidth(), frame->GetHeight());
- video_frame = frame_pool_.CreateFrame(
- media::VideoFrame::I420, size, gfx::Rect(size), size, timestamp);
-
- // Non-square pixels are unsupported.
- DCHECK_EQ(frame->GetPixelWidth(), 1u);
- DCHECK_EQ(frame->GetPixelHeight(), 1u);
-
- int y_rows = frame->GetHeight();
- int uv_rows = frame->GetChromaHeight();
- CopyYPlane(
- frame->GetYPlane(), frame->GetYPitch(), y_rows, video_frame.get());
- CopyUPlane(
- frame->GetUPlane(), frame->GetUPitch(), uv_rows, video_frame.get());
- CopyVPlane(
- frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame.get());
- }
-
- if (!first_frame_received_) {
- first_frame_received_ = true;
- media::VideoPixelFormat pixel_format = (
- video_frame->format() == media::VideoFrame::I420) ?
- media::PIXEL_FORMAT_I420 : media::PIXEL_FORMAT_TEXTURE;
- media::VideoCaptureFormat format(
- gfx::Size(video_frame->natural_size().width(),
- video_frame->natural_size().height()),
- MediaStreamVideoSource::kDefaultFrameRate,
- pixel_format);
- message_loop_proxy_->PostTask(
- FROM_HERE,
- base::Bind(&MediaStreamRemoteVideoSource::FrameFormatOnMainThread,
- AsWeakPtr(), format));
- }
-
- // TODO(perkj): Consider delivering the frame on whatever thread the frame is
- // delivered on once crbug/335327 is fixed.
- message_loop_proxy_->PostTask(
- FROM_HERE,
- base::Bind(&MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread,
- AsWeakPtr(), video_frame));
-}
-
-void MediaStreamRemoteVideoSource::OnChanged() {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- webrtc::MediaStreamTrackInterface::TrackState state = remote_track_->state();
- if (state != last_state_) {
- last_state_ = state;
- switch (state) {
- case webrtc::MediaStreamTrackInterface::kInitializing:
- // Ignore the kInitializing state since there is no match in
- // WebMediaStreamSource::ReadyState.
- break;
- case webrtc::MediaStreamTrackInterface::kLive:
- SetReadyState(blink::WebMediaStreamSource::ReadyStateLive);
- break;
- case webrtc::MediaStreamTrackInterface::kEnded:
- SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded);
- break;
- default:
- NOTREACHED();
- break;
- }
- }
-}
-
-void MediaStreamRemoteVideoSource::FrameFormatOnMainThread(
- const media::VideoCaptureFormat& format) {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- format_ = format;
- if (state() == RETRIEVING_CAPABILITIES) {
- media::VideoCaptureFormats formats;
- formats.push_back(format);
- OnSupportedFormats(formats);
- }
-}
-
-void MediaStreamRemoteVideoSource::DoRenderFrameOnMainThread(
- scoped_refptr<media::VideoFrame> video_frame) {
- DCHECK(message_loop_proxy_->BelongsToCurrentThread());
- if (state() == STARTED)
- DeliverVideoFrame(video_frame);
-}
-
-} // namespace content
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.h b/content/renderer/media/webrtc/media_stream_remote_video_source.h
deleted file mode 100644
index 2d5be61..0000000
--- a/content/renderer/media/webrtc/media_stream_remote_video_source.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_MEDIA_STREAM_REMOTE_VIDEO_SOURCE_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_MEDIA_STREAM_REMOTE_VIDEO_SOURCE_H_
-
-#include "base/memory/weak_ptr.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/media_stream_video_source.h"
-#include "media/base/video_frame_pool.h"
-#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
-#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
-
-namespace content {
-
-// MediaStreamRemoteVideoSource implements the MediaStreamVideoSource interface
-// for video tracks received on a PeerConnection. The purpose of the class is
-// to make sure there is no difference between a video track where the source is
-// a local source and a video track where the source is a remote video track.
-class CONTENT_EXPORT MediaStreamRemoteVideoSource
- : public MediaStreamVideoSource,
- NON_EXPORTED_BASE(public webrtc::VideoRendererInterface),
- NON_EXPORTED_BASE(public webrtc::ObserverInterface),
- public base::SupportsWeakPtr<MediaStreamRemoteVideoSource> {
- public:
- explicit MediaStreamRemoteVideoSource(
- webrtc::VideoTrackInterface* remote_track);
- virtual ~MediaStreamRemoteVideoSource();
-
- protected:
- // Implements MediaStreamVideoSource.
- virtual void GetCurrentSupportedFormats(
- int max_requested_width,
- int max_requested_height) OVERRIDE;
-
- virtual void StartSourceImpl(
- const media::VideoCaptureParams& params) OVERRIDE;
-
- virtual void StopSourceImpl() OVERRIDE;
-
- virtual webrtc::VideoSourceInterface* GetAdapter() OVERRIDE;
-
- // Implements webrtc::VideoRendererInterface used for receiving video frames
- // from the PeerConnection video track. May be called on
- // a different thread.
- virtual void SetSize(int width, int height) OVERRIDE;
- virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE;
-
- // webrtc::ObserverInterface implementation.
- virtual void OnChanged() OVERRIDE;
-
- private:
- void FrameFormatOnMainThread(const media::VideoCaptureFormat& format);
- void DoRenderFrameOnMainThread(scoped_refptr<media::VideoFrame> video_frame);
-
- scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
- scoped_refptr<webrtc::VideoTrackInterface> remote_track_;
- webrtc::MediaStreamTrackInterface::TrackState last_state_;
-
- // |first_frame_received_| and |frame_pool_| are only accessed on whatever
- // thread webrtc::VideoRendererInterface::RenderFrame is called on.
- bool first_frame_received_;
- media::VideoFramePool frame_pool_;
-
- // |format_| is the format currently received by this source.
- media::VideoCaptureFormat format_;
-
- DISALLOW_COPY_AND_ASSIGN(MediaStreamRemoteVideoSource);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_WEBRTC_MEDIA_STREAM_REMOTE_VIDEO_SOURCE_H_
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc b/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
deleted file mode 100644
index 068320f..0000000
--- a/content/renderer/media/webrtc/media_stream_remote_video_source_unittest.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/strings/utf_string_conversions.h"
-#include "content/public/renderer/media_stream_video_sink.h"
-#include "content/renderer/media/media_stream_video_track.h"
-#include "content/renderer/media/mock_media_stream_dependency_factory.h"
-#include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
-#include "media/base/video_frame.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/libjingle/source/talk/media/webrtc/webrtcvideoframe.h"
-
-namespace content {
-
-class MockVideoSink : public MediaStreamVideoSink {
- public:
- MockVideoSink()
- : number_of_frames_(0),
- state_(blink::WebMediaStreamSource::ReadyStateLive) {
- }
-
- virtual void OnVideoFrame(
- const scoped_refptr<media::VideoFrame>& frame) OVERRIDE {
- ++number_of_frames_;
- }
-
- virtual void OnReadyStateChanged(
- blink::WebMediaStreamSource::ReadyState state) OVERRIDE {
- state_ = state;
- }
-
- int number_of_frames() const { return number_of_frames_; }
- blink::WebMediaStreamSource::ReadyState state() const { return state_; }
-
- private:
- int number_of_frames_;
- blink::WebMediaStreamSource::ReadyState state_;
-};
-
-class MediaStreamRemoteVideoSourceUnderTest
- : public MediaStreamRemoteVideoSource {
- public:
- MediaStreamRemoteVideoSourceUnderTest(webrtc::VideoTrackInterface* track)
- : MediaStreamRemoteVideoSource(track) {
- }
- using MediaStreamRemoteVideoSource::RenderFrame;
-};
-
-class MediaStreamRemoteVideoSourceTest
- : public ::testing::Test {
- public:
- MediaStreamRemoteVideoSourceTest()
- : mock_factory_(new MockMediaStreamDependencyFactory()),
- webrtc_video_track_(
- mock_factory_->CreateLocalVideoTrack(
- "test",
- static_cast<cricket::VideoCapturer*>(NULL))),
- remote_source_(
- new MediaStreamRemoteVideoSourceUnderTest(webrtc_video_track_)),
- number_of_successful_constraints_applied_(0),
- number_of_failed_constraints_applied_(0) {
- webkit_source_.initialize(base::UTF8ToUTF16("dummy_source_id"),
- blink::WebMediaStreamSource::TypeVideo,
- base::UTF8ToUTF16("dummy_source_name"));
- webkit_source_.setExtraData(remote_source_);
- }
- virtual ~MediaStreamRemoteVideoSourceTest() {}
-
- MediaStreamRemoteVideoSourceUnderTest* source() {
- return remote_source_;
- }
-
- MediaStreamVideoTrack* CreateTrack() {
- bool enabled = true;
- blink::WebMediaConstraints constraints;
- constraints.initialize();
- MediaStreamDependencyFactory* factory = NULL;
- return new MediaStreamVideoTrack(
- source(),
- constraints,
- base::Bind(
- &MediaStreamRemoteVideoSourceTest::OnConstraintsApplied,
- base::Unretained(this)),
- enabled, factory);
- }
-
- int NumberOfSuccessConstraintsCallbacks() const {
- return number_of_successful_constraints_applied_;
- }
-
- int NumberOfFailedConstraintsCallbacks() const {
- return number_of_failed_constraints_applied_;
- }
-
- void StopWebRtcTrack() {
- static_cast<MockWebRtcVideoTrack*>(webrtc_video_track_.get())->set_state(
- webrtc::MediaStreamTrackInterface::kEnded);
- }
-
- base::MessageLoop* message_loop() { return &message_loop_; }
-
- const blink::WebMediaStreamSource& webkit_source() const {
- return webkit_source_;
- }
-
- private:
- void OnConstraintsApplied(MediaStreamSource* source, bool success) {
- ASSERT_EQ(source, remote_source_);
- if (success)
- ++number_of_successful_constraints_applied_;
- else
- ++number_of_failed_constraints_applied_;
- }
-
- base::MessageLoop message_loop_;
- scoped_ptr<MockMediaStreamDependencyFactory> mock_factory_;
- scoped_refptr<webrtc::VideoTrackInterface> webrtc_video_track_;
- // |remote_source_| is owned by |webkit_source_|.
- MediaStreamRemoteVideoSourceUnderTest* remote_source_;
- blink::WebMediaStreamSource webkit_source_;
- int number_of_successful_constraints_applied_;
- int number_of_failed_constraints_applied_;
-};
-
-TEST_F(MediaStreamRemoteVideoSourceTest, StartTrack) {
- scoped_ptr<MediaStreamVideoTrack> track(CreateTrack());
- EXPECT_EQ(0, NumberOfSuccessConstraintsCallbacks());
-
- MockVideoSink sink;
- track->AddSink(&sink);
-
- cricket::WebRtcVideoFrame webrtc_frame;
- webrtc_frame.InitToBlack(320, 240, 1, 1, 0, 1);
- source()->RenderFrame(&webrtc_frame);
- message_loop()->RunUntilIdle();
-
- EXPECT_EQ(1, NumberOfSuccessConstraintsCallbacks());
- EXPECT_EQ(1, sink.number_of_frames());
- track->RemoveSink(&sink);
-}
-
-TEST_F(MediaStreamRemoteVideoSourceTest, RemoteTrackStop) {
- scoped_ptr<MediaStreamVideoTrack> track(CreateTrack());
-
- MockVideoSink sink;
- track->AddSink(&sink);
-
- EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive, sink.state());
- EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateLive,
- webkit_source().readyState());
- StopWebRtcTrack();
- EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded,
- webkit_source().readyState());
- EXPECT_EQ(blink::WebMediaStreamSource::ReadyStateEnded, sink.state());
-
- track->RemoveSink(&sink);
-}
-
-} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_video_sink_adapter.cc b/content/renderer/media/webrtc/webrtc_video_sink_adapter.cc
new file mode 100644
index 0000000..587ecfe
--- /dev/null
+++ b/content/renderer/media/webrtc/webrtc_video_sink_adapter.cc
@@ -0,0 +1,118 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// 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_sink_adapter.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "content/renderer/media/native_handle_impl.h"
+#include "media/base/video_frame.h"
+#include "media/base/video_util.h"
+#include "third_party/libjingle/source/talk/media/base/videoframe.h"
+#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
+#include "ui/gfx/size.h"
+
+using media::CopyYPlane;
+using media::CopyUPlane;
+using media::CopyVPlane;
+
+namespace content {
+
+WebRtcVideoSinkAdapter::WebRtcVideoSinkAdapter(
+ webrtc::VideoTrackInterface* video_track,
+ MediaStreamVideoSink* sink)
+ : message_loop_proxy_(base::MessageLoopProxy::current()),
+ sink_(sink),
+ video_track_(video_track),
+ state_(video_track->state()),
+ track_enabled_(video_track->enabled()) {
+ DCHECK(sink);
+ video_track_->AddRenderer(this);
+ video_track_->RegisterObserver(this);
+ DVLOG(1) << "WebRtcVideoSinkAdapter";
+}
+
+WebRtcVideoSinkAdapter::~WebRtcVideoSinkAdapter() {
+ video_track_->RemoveRenderer(this);
+ video_track_->UnregisterObserver(this);
+ DVLOG(1) << "~WebRtcVideoSinkAdapter";
+}
+
+void WebRtcVideoSinkAdapter::SetSize(int width, int height) {
+}
+
+void WebRtcVideoSinkAdapter::RenderFrame(const cricket::VideoFrame* frame) {
+ base::TimeDelta timestamp = base::TimeDelta::FromMilliseconds(
+ frame->GetTimeStamp() / talk_base::kNumNanosecsPerMillisec);
+
+ scoped_refptr<media::VideoFrame> video_frame;
+ if (frame->GetNativeHandle() != NULL) {
+ NativeHandleImpl* handle =
+ static_cast<NativeHandleImpl*>(frame->GetNativeHandle());
+ video_frame = static_cast<media::VideoFrame*>(handle->GetHandle());
+ video_frame->SetTimestamp(timestamp);
+ } else {
+ gfx::Size size(frame->GetWidth(), frame->GetHeight());
+ video_frame = media::VideoFrame::CreateFrame(
+ media::VideoFrame::YV12, size, gfx::Rect(size), size, timestamp);
+
+ // Aspect ratio unsupported; DCHECK when there are non-square pixels.
+ DCHECK_EQ(frame->GetPixelWidth(), 1u);
+ DCHECK_EQ(frame->GetPixelHeight(), 1u);
+
+ int y_rows = frame->GetHeight();
+ int uv_rows = frame->GetChromaHeight();
+ CopyYPlane(
+ frame->GetYPlane(), frame->GetYPitch(), y_rows, video_frame.get());
+ CopyUPlane(
+ frame->GetUPlane(), frame->GetUPitch(), uv_rows, video_frame.get());
+ CopyVPlane(
+ frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame.get());
+ }
+
+ message_loop_proxy_->PostTask(
+ FROM_HERE, base::Bind(&WebRtcVideoSinkAdapter::DoRenderFrameOnMainThread,
+ AsWeakPtr(), video_frame));
+}
+
+void WebRtcVideoSinkAdapter::OnChanged() {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+
+ // TODO(perkj): OnChanged belongs to the base class of WebRtcVideoSinkAdapter
+ // common for both webrtc audio and video.
+ webrtc::MediaStreamTrackInterface::TrackState state = video_track_->state();
+ if (state != state_) {
+ state_ = state;
+ switch (state) {
+ case webrtc::MediaStreamTrackInterface::kInitializing:
+ // Ignore the kInitializing state since there is no match in
+ // WebMediaStreamSource::ReadyState.
+ break;
+ case webrtc::MediaStreamTrackInterface::kLive:
+ sink_->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateLive);
+ break;
+ case webrtc::MediaStreamTrackInterface::kEnded:
+ sink_->OnReadyStateChanged(
+ blink::WebMediaStreamSource::ReadyStateEnded);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+ if (track_enabled_ != video_track_->enabled()) {
+ track_enabled_ = video_track_->enabled();
+ sink_->OnEnabledChanged(track_enabled_);
+ }
+}
+
+void WebRtcVideoSinkAdapter::DoRenderFrameOnMainThread(
+ scoped_refptr<media::VideoFrame> video_frame) {
+ DCHECK(message_loop_proxy_->BelongsToCurrentThread());
+ sink_->OnVideoFrame(video_frame);
+}
+
+} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_video_sink_adapter.h b/content/renderer/media/webrtc/webrtc_video_sink_adapter.h
new file mode 100644
index 0000000..2f75a95
--- /dev/null
+++ b/content/renderer/media/webrtc/webrtc_video_sink_adapter.h
@@ -0,0 +1,60 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_SINK_ADAPTER_H_
+#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_SINK_ADAPTER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "content/public/renderer/media_stream_video_sink.h"
+#include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h"
+
+namespace base {
+class MessageLoopProxy;
+}
+
+namespace content {
+
+// WebRtcVideoSinkAdapter acts as the middle man between a
+// webrtc:::VideoTrackInterface and a content::MediaStreamVideoSink.
+// It is responsible for translating video data from a libjingle video type
+// to a chrome video type.
+class CONTENT_EXPORT WebRtcVideoSinkAdapter
+ : NON_EXPORTED_BASE(public webrtc::VideoRendererInterface),
+ NON_EXPORTED_BASE(public webrtc::ObserverInterface),
+ public base::SupportsWeakPtr<WebRtcVideoSinkAdapter> {
+ public:
+ WebRtcVideoSinkAdapter(webrtc::VideoTrackInterface* video_track,
+ MediaStreamVideoSink* sink);
+ virtual ~WebRtcVideoSinkAdapter();
+
+ MediaStreamVideoSink* sink() const { return sink_; }
+
+ protected:
+ // webrtc::VideoRendererInterface implementation. May be called on
+ // a different thread.
+ virtual void SetSize(int width, int height) OVERRIDE;
+ virtual void RenderFrame(const cricket::VideoFrame* frame) OVERRIDE;
+
+ // webrtc::ObserverInterface implementation.
+ // TODO(perkj): OnChanged should be implemented on a common base class used
+ // for both WebRtc Audio and Video tracks.
+ virtual void OnChanged() OVERRIDE;
+
+ private:
+ void DoRenderFrameOnMainThread(scoped_refptr<media::VideoFrame> video_frame);
+
+ scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
+ MediaStreamVideoSink* sink_;
+ // The video track the renderer is connected to.
+ scoped_refptr<webrtc::VideoTrackInterface> video_track_;
+ webrtc::MediaStreamTrackInterface::TrackState state_;
+ bool track_enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(WebRtcVideoSinkAdapter);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_SINK_ADAPTER_H_