OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_audio_track.h" | 5 #include "content/renderer/media/media_stream_audio_track.h" |
6 | 6 |
| 7 #include <algorithm> |
| 8 |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "content/public/renderer/media_stream_audio_sink.h" |
8 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" | 11 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" |
9 #include "third_party/webrtc/api/mediastreaminterface.h" | |
10 | 12 |
11 namespace content { | 13 namespace content { |
12 | 14 |
13 MediaStreamAudioTrack::MediaStreamAudioTrack(bool is_local_track) | 15 MediaStreamAudioTrack::MediaStreamAudioTrack(bool is_local_track) |
14 : MediaStreamTrack(is_local_track) { | 16 : MediaStreamTrack(is_local_track), |
| 17 is_enabled_(true) { |
| 18 DVLOG(1) << "MediaStreamAudioTrack::MediaStreamAudioTrack(is a " |
| 19 << (is_local_track ? "local" : "remote") << " track)"; |
15 } | 20 } |
16 | 21 |
17 MediaStreamAudioTrack::~MediaStreamAudioTrack() { | 22 MediaStreamAudioTrack::~MediaStreamAudioTrack() { |
| 23 DVLOG(1) << "MediaStreamAudioTrack::~MediaStreamAudioTrack()"; |
| 24 Stop(); |
18 } | 25 } |
19 | 26 |
20 // static | 27 // static |
21 MediaStreamAudioTrack* MediaStreamAudioTrack::GetTrack( | 28 MediaStreamAudioTrack* MediaStreamAudioTrack::Get( |
22 const blink::WebMediaStreamTrack& track) { | 29 const blink::WebMediaStreamTrack& track) { |
23 if (track.isNull() || | 30 if (track.isNull() || |
24 track.source().type() != blink::WebMediaStreamSource::TypeAudio) { | 31 track.source().type() != blink::WebMediaStreamSource::TypeAudio) { |
25 return nullptr; | 32 return nullptr; |
26 } | 33 } |
27 return static_cast<MediaStreamAudioTrack*>(track.extraData()); | 34 return static_cast<MediaStreamAudioTrack*>(track.extraData()); |
28 } | 35 } |
29 | 36 |
30 webrtc::AudioTrackInterface* MediaStreamAudioTrack::GetAudioAdapter() { | 37 void MediaStreamAudioTrack::AddStopObserver( |
31 NOTREACHED(); | 38 const base::Closure& stop_callback) { |
| 39 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 40 DCHECK(!stop_callback.is_null()); |
| 41 DVLOG(1) << "MediaStreamAudioTrack::AddStopObserver()"; |
| 42 stop_callbacks_.push_back(stop_callback); |
| 43 } |
| 44 |
| 45 void MediaStreamAudioTrack::AddSink(MediaStreamAudioSink* sink) { |
| 46 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 47 DCHECK(sink); |
| 48 DVLOG(1) << "MediaStreamAudioTrack::AddSink(" << sink << ')'; |
| 49 { |
| 50 base::AutoLock auto_lock(lock_); |
| 51 DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end()); |
| 52 DCHECK(std::find(pending_sinks_.begin(), pending_sinks_.end(), sink) == |
| 53 pending_sinks_.end()); |
| 54 pending_sinks_.push_back(sink); |
| 55 } |
| 56 sink->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateLive); |
| 57 } |
| 58 |
| 59 void MediaStreamAudioTrack::RemoveSink(MediaStreamAudioSink* sink) { |
| 60 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 61 { |
| 62 base::AutoLock auto_lock(lock_); |
| 63 auto it = std::find(pending_sinks_.begin(), pending_sinks_.end(), sink); |
| 64 if (it != pending_sinks_.end()) { |
| 65 DVLOG(1) << "MediaStreamAudioTrack::RemoveSink(" << sink |
| 66 << ") from pending sinks list."; |
| 67 pending_sinks_.erase(it); |
| 68 } else { |
| 69 it = std::find(sinks_.begin(), sinks_.end(), sink); |
| 70 if (it != sinks_.end()) { |
| 71 DVLOG(1) << "MediaStreamAudioTrack::RemoveSink(" << sink |
| 72 << ") from active sinks list."; |
| 73 sinks_.erase(it); |
| 74 } |
| 75 } |
| 76 } |
| 77 sink->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); |
| 78 } |
| 79 |
| 80 void MediaStreamAudioTrack::SetFormat(const media::AudioParameters& params) { |
| 81 // Note: May be called on any thread. |
| 82 |
| 83 base::AutoLock auto_lock(lock_); |
| 84 if (params_.Equals(params)) |
| 85 return; |
| 86 params_ = params; |
| 87 pending_sinks_.insert(pending_sinks_.end(), sinks_.begin(), sinks_.end()); |
| 88 sinks_.clear(); |
| 89 } |
| 90 |
| 91 void MediaStreamAudioTrack::DeliverDataToSinks(const media::AudioBus& audio_bus, |
| 92 base::TimeTicks reference_time) { |
| 93 // Note: May be called on any thread. |
| 94 |
| 95 // Lock sink lists while this audio thread is manipulating the lists and |
| 96 // invoking the OnData() callback for each sink. |
| 97 base::AutoLock auto_lock(lock_); |
| 98 |
| 99 // If audio delivery is currently disabled, take no actions. |
| 100 if (!is_enabled_) |
| 101 return; |
| 102 |
| 103 // Call OnSetFormat() for all pending sinks and move them to the |
| 104 // active-delivery list. |
| 105 DCHECK(params_.IsValid()); |
| 106 if (!pending_sinks_.empty()) { |
| 107 for (MediaStreamAudioSink* sink : pending_sinks_) |
| 108 sink->OnSetFormat(params_); |
| 109 sinks_.insert(sinks_.end(), pending_sinks_.begin(), pending_sinks_.end()); |
| 110 pending_sinks_.clear(); |
| 111 } |
| 112 |
| 113 // Deliver the audio data to each sink. |
| 114 for (MediaStreamAudioSink* sink : sinks_) |
| 115 sink->OnData(audio_bus, reference_time); |
| 116 } |
| 117 |
| 118 void MediaStreamAudioTrack::SetEnabled(bool enabled) { |
| 119 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 120 base::AutoLock auto_lock(lock_); |
| 121 DVLOG(1) << "MediaStreamAudioTrack::SetEnabled(" << (enabled ? 'Y' : 'N') |
| 122 << "), was previously set to " << (is_enabled_ ? 'Y' : 'N') << '.'; |
| 123 is_enabled_ = enabled; |
| 124 } |
| 125 |
| 126 void MediaStreamAudioTrack::Stop() { |
| 127 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 128 DVLOG(1) << "MediaStreamAudioTrack::Stop()"; |
| 129 |
| 130 std::vector<MediaStreamAudioSink*> zombies; |
| 131 { |
| 132 base::AutoLock auto_lock(lock_); |
| 133 is_enabled_ = false; |
| 134 zombies.swap(sinks_); |
| 135 zombies.insert(zombies.end(), pending_sinks_.begin(), pending_sinks_.end()); |
| 136 pending_sinks_.clear(); |
| 137 } |
| 138 for (MediaStreamAudioSink* zombie : zombies) |
| 139 zombie->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); |
| 140 |
| 141 std::vector<base::Closure> callbacks_to_run; |
| 142 callbacks_to_run.swap(stop_callbacks_); |
| 143 for (base::Closure& callback : callbacks_to_run) |
| 144 callback.Run(); |
| 145 } |
| 146 |
| 147 media::AudioParameters MediaStreamAudioTrack::GetOutputFormat() const { |
| 148 base::AutoLock auto_lock(lock_); |
| 149 return params_; |
| 150 } |
| 151 |
| 152 void* MediaStreamAudioTrack::GetClassIdentifier() const { |
32 return nullptr; | 153 return nullptr; |
33 } | 154 } |
34 | 155 |
35 } // namespace content | 156 } // namespace content |
OLD | NEW |