| Index: content/renderer/media/media_stream_audio_track.cc
|
| diff --git a/content/renderer/media/media_stream_audio_track.cc b/content/renderer/media/media_stream_audio_track.cc
|
| index 278ab05bb107369cdd23614565470e40846a3518..009b079db3916c710b2227c45e87229e2133c443 100644
|
| --- a/content/renderer/media/media_stream_audio_track.cc
|
| +++ b/content/renderer/media/media_stream_audio_track.cc
|
| @@ -4,21 +4,28 @@
|
|
|
| #include "content/renderer/media/media_stream_audio_track.h"
|
|
|
| +#include <algorithm>
|
| +
|
| #include "base/logging.h"
|
| +#include "content/public/renderer/media_stream_audio_sink.h"
|
| #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
|
| -#include "third_party/webrtc/api/mediastreaminterface.h"
|
|
|
| namespace content {
|
|
|
| MediaStreamAudioTrack::MediaStreamAudioTrack(bool is_local_track)
|
| - : MediaStreamTrack(is_local_track) {
|
| + : MediaStreamTrack(is_local_track),
|
| + is_enabled_(true) {
|
| + DVLOG(1) << "MediaStreamAudioTrack::MediaStreamAudioTrack(is a "
|
| + << (is_local_track ? "local" : "remote") << " track)";
|
| }
|
|
|
| MediaStreamAudioTrack::~MediaStreamAudioTrack() {
|
| + DVLOG(1) << "MediaStreamAudioTrack::~MediaStreamAudioTrack()";
|
| + Stop();
|
| }
|
|
|
| // static
|
| -MediaStreamAudioTrack* MediaStreamAudioTrack::GetTrack(
|
| +MediaStreamAudioTrack* MediaStreamAudioTrack::Get(
|
| const blink::WebMediaStreamTrack& track) {
|
| if (track.isNull() ||
|
| track.source().type() != blink::WebMediaStreamSource::TypeAudio) {
|
| @@ -27,8 +34,122 @@ MediaStreamAudioTrack* MediaStreamAudioTrack::GetTrack(
|
| return static_cast<MediaStreamAudioTrack*>(track.extraData());
|
| }
|
|
|
| -webrtc::AudioTrackInterface* MediaStreamAudioTrack::GetAudioAdapter() {
|
| - NOTREACHED();
|
| +void MediaStreamAudioTrack::AddStopObserver(
|
| + const base::Closure& stop_callback) {
|
| + DCHECK(main_render_thread_checker_.CalledOnValidThread());
|
| + DCHECK(!stop_callback.is_null());
|
| + DVLOG(1) << "MediaStreamAudioTrack::AddStopObserver()";
|
| + stop_callbacks_.push_back(stop_callback);
|
| +}
|
| +
|
| +void MediaStreamAudioTrack::AddSink(MediaStreamAudioSink* sink) {
|
| + DCHECK(main_render_thread_checker_.CalledOnValidThread());
|
| + DCHECK(sink);
|
| + DVLOG(1) << "MediaStreamAudioTrack::AddSink(" << sink << ')';
|
| + {
|
| + base::AutoLock auto_lock(lock_);
|
| + DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end());
|
| + DCHECK(std::find(pending_sinks_.begin(), pending_sinks_.end(), sink) ==
|
| + pending_sinks_.end());
|
| + pending_sinks_.push_back(sink);
|
| + }
|
| + sink->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateLive);
|
| +}
|
| +
|
| +void MediaStreamAudioTrack::RemoveSink(MediaStreamAudioSink* sink) {
|
| + DCHECK(main_render_thread_checker_.CalledOnValidThread());
|
| + {
|
| + base::AutoLock auto_lock(lock_);
|
| + auto it = std::find(pending_sinks_.begin(), pending_sinks_.end(), sink);
|
| + if (it != pending_sinks_.end()) {
|
| + DVLOG(1) << "MediaStreamAudioTrack::RemoveSink(" << sink
|
| + << ") from pending sinks list.";
|
| + pending_sinks_.erase(it);
|
| + } else {
|
| + it = std::find(sinks_.begin(), sinks_.end(), sink);
|
| + if (it != sinks_.end()) {
|
| + DVLOG(1) << "MediaStreamAudioTrack::RemoveSink(" << sink
|
| + << ") from active sinks list.";
|
| + sinks_.erase(it);
|
| + }
|
| + }
|
| + }
|
| + sink->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
|
| +}
|
| +
|
| +void MediaStreamAudioTrack::SetFormat(const media::AudioParameters& params) {
|
| + // Note: May be called on any thread.
|
| +
|
| + base::AutoLock auto_lock(lock_);
|
| + if (params_.Equals(params))
|
| + return;
|
| + params_ = params;
|
| + pending_sinks_.insert(pending_sinks_.end(), sinks_.begin(), sinks_.end());
|
| + sinks_.clear();
|
| +}
|
| +
|
| +void MediaStreamAudioTrack::DeliverDataToSinks(const media::AudioBus& audio_bus,
|
| + base::TimeTicks reference_time) {
|
| + // Note: May be called on any thread.
|
| +
|
| + // Lock sink lists while this audio thread is manipulating the lists and
|
| + // invoking the OnData() callback for each sink.
|
| + base::AutoLock auto_lock(lock_);
|
| +
|
| + // If audio delivery is currently disabled, take no actions.
|
| + if (!is_enabled_)
|
| + return;
|
| +
|
| + // Call OnSetFormat() for all pending sinks and move them to the
|
| + // active-delivery list.
|
| + DCHECK(params_.IsValid());
|
| + if (!pending_sinks_.empty()) {
|
| + for (MediaStreamAudioSink* sink : pending_sinks_)
|
| + sink->OnSetFormat(params_);
|
| + sinks_.insert(sinks_.end(), pending_sinks_.begin(), pending_sinks_.end());
|
| + pending_sinks_.clear();
|
| + }
|
| +
|
| + // Deliver the audio data to each sink.
|
| + for (MediaStreamAudioSink* sink : sinks_)
|
| + sink->OnData(audio_bus, reference_time);
|
| +}
|
| +
|
| +void MediaStreamAudioTrack::SetEnabled(bool enabled) {
|
| + DCHECK(main_render_thread_checker_.CalledOnValidThread());
|
| + base::AutoLock auto_lock(lock_);
|
| + DVLOG(1) << "MediaStreamAudioTrack::SetEnabled(" << (enabled ? 'Y' : 'N')
|
| + << "), was previously set to " << (is_enabled_ ? 'Y' : 'N') << '.';
|
| + is_enabled_ = enabled;
|
| +}
|
| +
|
| +void MediaStreamAudioTrack::Stop() {
|
| + DCHECK(main_render_thread_checker_.CalledOnValidThread());
|
| + DVLOG(1) << "MediaStreamAudioTrack::Stop()";
|
| +
|
| + std::vector<MediaStreamAudioSink*> zombies;
|
| + {
|
| + base::AutoLock auto_lock(lock_);
|
| + is_enabled_ = false;
|
| + zombies.swap(sinks_);
|
| + zombies.insert(zombies.end(), pending_sinks_.begin(), pending_sinks_.end());
|
| + pending_sinks_.clear();
|
| + }
|
| + for (MediaStreamAudioSink* zombie : zombies)
|
| + zombie->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded);
|
| +
|
| + std::vector<base::Closure> callbacks_to_run;
|
| + callbacks_to_run.swap(stop_callbacks_);
|
| + for (base::Closure& callback : callbacks_to_run)
|
| + callback.Run();
|
| +}
|
| +
|
| +media::AudioParameters MediaStreamAudioTrack::GetOutputFormat() const {
|
| + base::AutoLock auto_lock(lock_);
|
| + return params_;
|
| +}
|
| +
|
| +void* MediaStreamAudioTrack::GetClassIdentifier() const {
|
| return nullptr;
|
| }
|
|
|
|
|