- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / media / remote_media_stream_impl.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
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/remote_media_stream_impl.h"
6
7 #include <string>
8
9 #include "base/logging.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/renderer/media/media_stream_dependency_factory.h"
12 #include "content/renderer/media/media_stream_extra_data.h"
13 #include "third_party/WebKit/public/platform/WebString.h"
14
15 namespace content {
16
17 // RemoteMediaStreamTrackObserver is responsible for listening on change
18 // notification on a remote webrtc MediaStreamTrack and notify WebKit.
19 class RemoteMediaStreamTrackObserver
20     : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
21       NON_EXPORTED_BASE(public base::NonThreadSafe) {
22  public:
23   RemoteMediaStreamTrackObserver(
24       webrtc::MediaStreamTrackInterface* webrtc_track,
25       const WebKit::WebMediaStreamTrack& webkit_track);
26   virtual ~RemoteMediaStreamTrackObserver();
27
28   webrtc::MediaStreamTrackInterface* observered_track() {
29     return webrtc_track_.get();
30   }
31   const WebKit::WebMediaStreamTrack& webkit_track() { return webkit_track_; }
32
33  private:
34   // webrtc::ObserverInterface implementation.
35   virtual void OnChanged() OVERRIDE;
36
37   webrtc::MediaStreamTrackInterface::TrackState state_;
38   scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
39   WebKit::WebMediaStreamTrack webkit_track_;
40
41   DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackObserver);
42 };
43
44 }  // namespace content
45
46 namespace {
47
48 void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track,
49                            WebKit::WebMediaStreamTrack* webkit_track,
50                            WebKit::WebMediaStreamSource::Type type) {
51   WebKit::WebMediaStreamSource webkit_source;
52   WebKit::WebString webkit_track_id(UTF8ToUTF16(track->id()));
53
54   webkit_source.initialize(webkit_track_id, type, webkit_track_id);
55   webkit_track->initialize(webkit_track_id, webkit_source);
56   content::MediaStreamDependencyFactory::AddNativeTrackToBlinkTrack(track,
57       *webkit_track);
58 }
59
60 content::RemoteMediaStreamTrackObserver* FindTrackObserver(
61     webrtc::MediaStreamTrackInterface* track,
62     const ScopedVector<content::RemoteMediaStreamTrackObserver>& observers) {
63   ScopedVector<content::RemoteMediaStreamTrackObserver>::const_iterator it =
64       observers.begin();
65   for (; it != observers.end(); ++it) {
66     if ((*it)->observered_track() == track)
67       return *it;
68   }
69   return NULL;
70 }
71
72 } // namespace anonymous
73
74 namespace content {
75
76 RemoteMediaStreamTrackObserver::RemoteMediaStreamTrackObserver(
77     webrtc::MediaStreamTrackInterface* webrtc_track,
78     const WebKit::WebMediaStreamTrack& webkit_track)
79     : state_(webrtc_track->state()),
80       webrtc_track_(webrtc_track),
81       webkit_track_(webkit_track) {
82   webrtc_track->RegisterObserver(this);
83 }
84
85 RemoteMediaStreamTrackObserver::~RemoteMediaStreamTrackObserver() {
86   webrtc_track_->UnregisterObserver(this);
87 }
88
89 void RemoteMediaStreamTrackObserver::OnChanged() {
90   DCHECK(CalledOnValidThread());
91
92   webrtc::MediaStreamTrackInterface::TrackState state = webrtc_track_->state();
93   if (state == state_)
94     return;
95
96   state_ = state;
97   switch (state) {
98     case webrtc::MediaStreamTrackInterface::kInitializing:
99       // Ignore the kInitializing state since there is no match in
100       // WebMediaStreamSource::ReadyState.
101       break;
102     case webrtc::MediaStreamTrackInterface::kLive:
103       webkit_track_.source().setReadyState(
104           WebKit::WebMediaStreamSource::ReadyStateLive);
105       break;
106     case webrtc::MediaStreamTrackInterface::kEnded:
107       webkit_track_.source().setReadyState(
108           WebKit::WebMediaStreamSource::ReadyStateEnded);
109       break;
110     default:
111       NOTREACHED();
112       break;
113   }
114 }
115
116 RemoteMediaStreamImpl::RemoteMediaStreamImpl(
117     webrtc::MediaStreamInterface* webrtc_stream)
118     : webrtc_stream_(webrtc_stream) {
119   webrtc_stream_->RegisterObserver(this);
120
121   webrtc::AudioTrackVector webrtc_audio_tracks =
122       webrtc_stream_->GetAudioTracks();
123   WebKit::WebVector<WebKit::WebMediaStreamTrack> webkit_audio_tracks(
124       webrtc_audio_tracks.size());
125
126   // Initialize WebKit audio tracks.
127   size_t i = 0;
128   for (; i < webrtc_audio_tracks.size(); ++i) {
129     webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i];
130     DCHECK(audio_track);
131     InitializeWebkitTrack(audio_track,  &webkit_audio_tracks[i],
132                           WebKit::WebMediaStreamSource::TypeAudio);
133     audio_track_observers_.push_back(
134         new RemoteMediaStreamTrackObserver(audio_track,
135                                            webkit_audio_tracks[i]));
136   }
137
138   // Initialize WebKit video tracks.
139   webrtc::VideoTrackVector webrtc_video_tracks =
140         webrtc_stream_->GetVideoTracks();
141   WebKit::WebVector<WebKit::WebMediaStreamTrack> webkit_video_tracks(
142        webrtc_video_tracks.size());
143   for (i = 0; i < webrtc_video_tracks.size(); ++i) {
144     webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i];
145     DCHECK(video_track);
146     InitializeWebkitTrack(video_track,  &webkit_video_tracks[i],
147                           WebKit::WebMediaStreamSource::TypeVideo);
148     video_track_observers_.push_back(
149         new RemoteMediaStreamTrackObserver(video_track,
150                                            webkit_video_tracks[i]));
151   }
152
153   webkit_stream_.initialize(UTF8ToUTF16(webrtc_stream->label()),
154                             webkit_audio_tracks, webkit_video_tracks);
155   webkit_stream_.setExtraData(new MediaStreamExtraData(webrtc_stream, false));
156 }
157
158 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
159   webrtc_stream_->UnregisterObserver(this);
160 }
161
162 void RemoteMediaStreamImpl::OnChanged() {
163   // Find removed audio tracks.
164   ScopedVector<RemoteMediaStreamTrackObserver>::iterator audio_it =
165       audio_track_observers_.begin();
166   while (audio_it != audio_track_observers_.end()) {
167     std::string track_id = (*audio_it)->observered_track()->id();
168     if (webrtc_stream_->FindAudioTrack(track_id) == NULL) {
169        webkit_stream_.removeTrack((*audio_it)->webkit_track());
170        audio_it = audio_track_observers_.erase(audio_it);
171     } else {
172       ++audio_it;
173     }
174   }
175
176   // Find removed video tracks.
177   ScopedVector<RemoteMediaStreamTrackObserver>::iterator video_it =
178       video_track_observers_.begin();
179   while (video_it != video_track_observers_.end()) {
180     std::string track_id = (*video_it)->observered_track()->id();
181     if (webrtc_stream_->FindVideoTrack(track_id) == NULL) {
182       webkit_stream_.removeTrack((*video_it)->webkit_track());
183       video_it = video_track_observers_.erase(video_it);
184     } else {
185       ++video_it;
186     }
187   }
188
189   // Find added audio tracks.
190   webrtc::AudioTrackVector webrtc_audio_tracks =
191       webrtc_stream_->GetAudioTracks();
192   for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin();
193        it != webrtc_audio_tracks.end(); ++it) {
194     if (!FindTrackObserver(*it, audio_track_observers_)) {
195       WebKit::WebMediaStreamTrack new_track;
196       InitializeWebkitTrack(*it, &new_track,
197                             WebKit::WebMediaStreamSource::TypeAudio);
198       audio_track_observers_.push_back(
199           new RemoteMediaStreamTrackObserver(*it, new_track));
200       webkit_stream_.addTrack(new_track);
201     }
202   }
203
204   // Find added video tracks.
205   webrtc::VideoTrackVector webrtc_video_tracks =
206       webrtc_stream_->GetVideoTracks();
207   for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin();
208        it != webrtc_video_tracks.end(); ++it) {
209     if (!FindTrackObserver(*it, video_track_observers_)) {
210       WebKit::WebMediaStreamTrack new_track;
211       InitializeWebkitTrack(*it, &new_track,
212                             WebKit::WebMediaStreamSource::TypeVideo);
213       video_track_observers_.push_back(
214           new RemoteMediaStreamTrackObserver(*it, new_track));
215       webkit_stream_.addTrack(new_track);
216     }
217   }
218 }
219
220 }  // namespace content