Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: content/renderer/media/media_stream_audio_source.cc

Issue 1834323002: MediaStream audio: Refactor 3 separate "glue" implementations into one. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_source.h" 5 #include "content/renderer/media/media_stream_audio_source.h"
6 6
7 #include "content/renderer/media/webrtc_local_audio_track.h" 7 #include <algorithm>
8 #include "content/renderer/render_frame_impl.h" 8
9 #include "base/bind.h"
10 #include "content/renderer/media/media_stream_audio_track.h"
9 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 11 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
12 #include "third_party/WebKit/public/platform/WebString.h"
10 13
11 namespace content { 14 namespace content {
12 15
13 MediaStreamAudioSource::MediaStreamAudioSource( 16 MediaStreamAudioSource::MediaStreamAudioSource(bool is_local_source)
14 int render_frame_id, 17 : is_stopped_(false),
15 const StreamDeviceInfo& device_info, 18 is_local_source_(is_local_source),
16 const SourceStoppedCallback& stop_callback,
17 PeerConnectionDependencyFactory* factory)
18 : render_frame_id_(render_frame_id), factory_(factory),
19 weak_factory_(this) { 19 weak_factory_(this) {
20 SetDeviceInfo(device_info); 20 DVLOG(1) << "MediaStreamAudioSource::MediaStreamAudioSource(is a "
21 SetStopCallback(stop_callback); 21 << (is_local_source_ ? "local" : "remote") << " source)";
22 } 22 }
23 23
24 MediaStreamAudioSource::MediaStreamAudioSource() 24 MediaStreamAudioSource::~MediaStreamAudioSource() {
25 : render_frame_id_(-1), factory_(NULL), weak_factory_(this) { 25 DCHECK(thread_checker_.CalledOnValidThread());
26 DVLOG(1) << "MediaStreamAudioSource::~MediaStreamAudioSource()";
27 DCHECK(is_stopped_) << "BUG: Subclass must ensure StopSource() is called.";
o1ka 2016/03/30 15:00:57 Since this flag is supposed to be set by a child c
miu 2016/03/31 04:57:59 Fixed. As described in a comment below, I reworke
26 } 28 }
27 29
28 MediaStreamAudioSource::~MediaStreamAudioSource() {}
29
30 // static 30 // static
31 MediaStreamAudioSource* MediaStreamAudioSource::From( 31 MediaStreamAudioSource* MediaStreamAudioSource::From(
32 const blink::WebMediaStreamSource& source) { 32 const blink::WebMediaStreamSource& source) {
33 if (source.isNull() || 33 if (source.isNull() ||
34 source.getType() != blink::WebMediaStreamSource::TypeAudio) { 34 source.getType() != blink::WebMediaStreamSource::TypeAudio) {
35 return nullptr; 35 return nullptr;
36 } 36 }
37 return static_cast<MediaStreamAudioSource*>(source.getExtraData()); 37 return static_cast<MediaStreamAudioSource*>(source.getExtraData());
38 } 38 }
39 39
40 void MediaStreamAudioSource::DoStopSource() { 40 bool MediaStreamAudioSource::ConnectToTrack(
41 if (audio_capturer_) 41 const blink::WebMediaStreamTrack& track) {
42 audio_capturer_->Stop(); 42 DCHECK(thread_checker_.CalledOnValidThread());
43 if (webaudio_capturer_) 43 DCHECK(!track.isNull());
44 webaudio_capturer_->Stop(); 44
45 // Sanity-check that there is not already a MediaStreamAudioTrack instance
46 // associated with |track|.
47 if (MediaStreamAudioTrack::From(track)) {
48 LOG(DFATAL)
49 << "Attempting to connect another source to a WebMediaStreamTrack.";
50 return false;
51 }
52
53 if (!EnsureSourceIsStarted())
54 return false;
55 ConnectStartedSourceToTrack(track);
56 return true;
45 } 57 }
46 58
47 void MediaStreamAudioSource::AddTrack( 59 media::AudioParameters MediaStreamAudioSource::GetAudioParameters() const {
48 const blink::WebMediaStreamTrack& track, 60 base::AutoLock auto_lock(lock_);
49 const blink::WebMediaConstraints& constraints, 61 return params_;
50 const ConstraintsCallback& callback) { 62 }
51 // TODO(xians): Properly implement for audio sources. 63
52 if (!local_audio_source_.get()) { 64 void* MediaStreamAudioSource::GetClassIdentifier() const {
53 if (!factory_->InitializeMediaStreamAudioSource(render_frame_id_, 65 return nullptr;
54 constraints, this)) { 66 }
55 // The source failed to start. 67
56 // UserMediaClientImpl rely on the |stop_callback| to be triggered when 68 scoped_ptr<MediaStreamAudioTrack>
57 // the last track is removed from the source. But in this case, the 69 MediaStreamAudioSource::CreateMediaStreamAudioTrack(const std::string& id) {
58 // source is is not even started. So we need to fail both adding the 70 DCHECK(thread_checker_.CalledOnValidThread());
59 // track and trigger |stop_callback|. 71 return make_scoped_ptr(new MediaStreamAudioTrack(is_local_source()));
60 callback.Run(this, MEDIA_DEVICE_TRACK_START_FAILURE, ""); 72 }
61 StopSource(); 73
62 return; 74 void MediaStreamAudioSource::DoStopSource() {
63 } 75 DCHECK(thread_checker_.CalledOnValidThread());
76 DVLOG(1) << "MediaStreamAudioSource::DoStopSource()";
77 if (is_stopped_)
78 return;
79 is_stopped_ = true;
80 }
81
82 bool MediaStreamAudioSource::EnsureSourceIsStarted() {
83 DCHECK(thread_checker_.CalledOnValidThread());
84 DVLOG(1) << "MediaStreamAudioSource::EnsureSourceIsStarted()";
85 if (is_stopped_)
86 return false;
87 return true;
88 }
89
90 void MediaStreamAudioSource::SetFormat(const media::AudioParameters& params) {
91 // Note: May be called on any thread.
92 DCHECK(params.IsValid());
93 base::AutoLock auto_lock(lock_);
94 DVLOG(1) << "MediaStreamAudioSource::SetFormat("
95 << params.AsHumanReadableString() << "), was previously set to {"
96 << params_.AsHumanReadableString() << "}.";
97 if (params_.Equals(params))
98 return;
99 params_ = params;
100 for (MediaStreamAudioTrack* track : tracks_)
101 track->SetFormat(params);
102 }
103
104 void MediaStreamAudioSource::DeliverDataToTracks(
105 const media::AudioBus& audio_bus,
106 base::TimeTicks reference_time) {
107 // Note: May be called on any thread.
108 base::AutoLock auto_lock(lock_);
109 DCHECK(params_.IsValid());
110 for (MediaStreamAudioTrack* track : tracks_)
111 track->DeliverDataToSinks(audio_bus, reference_time);
112 }
113
114 void MediaStreamAudioSource::ConnectStartedSourceToTrack(
115 const blink::WebMediaStreamTrack& blink_track) {
116 DCHECK(thread_checker_.CalledOnValidThread());
117 DCHECK(!is_stopped_);
118
119 // Create a MediaStreamAudioTrack to deliver audio data directly from the
120 // calls to Capture() to all its managed sinks. Pass ownership of it to the
121 // WebMediaStreamTrack.
122 scoped_ptr<MediaStreamAudioTrack> track =
123 CreateMediaStreamAudioTrack(blink_track.id().utf8());
124 track->Start(base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo,
125 weak_factory_.GetWeakPtr(), track.get()));
126 track->SetEnabled(blink_track.isEnabled());
127 {
128 base::AutoLock auto_lock(lock_);
129 if (params_.IsValid())
130 track->SetFormat(params_);
131 tracks_.push_back(track.get());
64 } 132 }
65 133 blink::WebMediaStreamTrack mutable_blink_track = blink_track;
66 factory_->CreateLocalAudioTrack(track); 134 mutable_blink_track.setExtraData(track.release());
67 callback.Run(this, MEDIA_DEVICE_OK, "");
68 } 135 }
69 136
70 void MediaStreamAudioSource::StopAudioDeliveryTo(MediaStreamAudioTrack* track) { 137 void MediaStreamAudioSource::StopAudioDeliveryTo(MediaStreamAudioTrack* track) {
71 DCHECK(track); 138 DCHECK(thread_checker_.CalledOnValidThread());
72 if (audio_capturer_) { 139
73 // The cast here is safe because only WebRtcLocalAudioTracks are ever used 140 // Remove |track| from the list of tracks, which will immediatly halt all
74 // with WebRtcAudioCapturer sources. 141 // further audio data delivery.
75 // 142 bool did_remove_last_track = false;
76 // TODO(miu): That said, this ugly cast won't be necessary after my 143 {
77 // soon-upcoming refactoring change. 144 base::AutoLock auto_lock(lock_);
78 audio_capturer_->RemoveTrack(static_cast<WebRtcLocalAudioTrack*>(track)); 145 const bool had_tracks = !tracks_.empty();
146 const auto it = std::find(tracks_.begin(), tracks_.end(), track);
147 if (it != tracks_.end())
148 tracks_.erase(it);
149 did_remove_last_track = had_tracks && tracks_.empty();
79 } 150 }
80 if (webaudio_capturer_) { 151 // TODO(miu): Is this the behavior we want? Perhaps sources should be
81 // A separate source is created for each track, so just stop the source. 152 // explicitly closed, rather than auto-stop on the removal of the last track
82 webaudio_capturer_->Stop(); 153 // (behavior preserved from the defunct WebRtcAudioCapturer::RemoveTrack())?
83 } 154 if (!is_stopped_ && did_remove_last_track)
155 StopSource();
84 } 156 }
85 157
86 } // namespace content 158 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698