Home | History | Annotate | Download | only in media
      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 blink::WebMediaStreamTrack& webkit_track);
     26   virtual ~RemoteMediaStreamTrackObserver();
     27 
     28   webrtc::MediaStreamTrackInterface* observered_track() {
     29     return webrtc_track_.get();
     30   }
     31   const blink::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   blink::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                            blink::WebMediaStreamTrack* webkit_track,
     50                            blink::WebMediaStreamSource::Type type) {
     51   blink::WebMediaStreamSource webkit_source;
     52   blink::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(
     57       track, *webkit_track, false);
     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 blink::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           blink::WebMediaStreamSource::ReadyStateLive);
    105       break;
    106     case webrtc::MediaStreamTrackInterface::kEnded:
    107       webkit_track_.source().setReadyState(
    108           blink::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   blink::WebVector<blink::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                           blink::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   blink::WebVector<blink::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                           blink::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       blink::WebMediaStreamTrack new_track;
    196       InitializeWebkitTrack(*it, &new_track,
    197                             blink::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       blink::WebMediaStreamTrack new_track;
    211       InitializeWebkitTrack(*it, &new_track,
    212                             blink::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
    221