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

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

Issue 2758453004: Remove dangling PlayingState pointers in WebRtcAudioRenderer. (Closed)
Patch Set: Update comment and add thread check. Created 3 years, 9 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
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/webrtc_audio_renderer.h" 5 #include "content/renderer/media/webrtc_audio_renderer.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 47
48 // This is a simple wrapper class that's handed out to users of a shared 48 // This is a simple wrapper class that's handed out to users of a shared
49 // WebRtcAudioRenderer instance. This class maintains the per-user 'playing' 49 // WebRtcAudioRenderer instance. This class maintains the per-user 'playing'
50 // and 'started' states to avoid problems related to incorrect usage which 50 // and 'started' states to avoid problems related to incorrect usage which
51 // might violate the implementation assumptions inside WebRtcAudioRenderer 51 // might violate the implementation assumptions inside WebRtcAudioRenderer
52 // (see the play reference count). 52 // (see the play reference count).
53 class SharedAudioRenderer : public MediaStreamAudioRenderer { 53 class SharedAudioRenderer : public MediaStreamAudioRenderer {
54 public: 54 public:
55 // Callback definition for a callback that is called when when Play(), Pause() 55 // Callback definition for a callback that is called when when Play(), Pause()
56 // or SetVolume are called (whenever the internal |playing_state_| changes). 56 // or SetVolume are called (whenever the internal |playing_state_| changes).
57 typedef base::Callback<void(const blink::WebMediaStream&, 57 using OnPlayStateChanged =
58 WebRtcAudioRenderer::PlayingState*)> 58 base::Callback<void(const blink::WebMediaStream&,
59 OnPlayStateChanged; 59 WebRtcAudioRenderer::PlayingState*)>;
60
61 // Signals that the PlayingState* is about to become invalid, see comment in
62 // OnPlayStateRemoved.
63 using OnPlayStateRemoved =
64 base::OnceCallback<void(WebRtcAudioRenderer::PlayingState*)>;
60 65
61 SharedAudioRenderer(const scoped_refptr<MediaStreamAudioRenderer>& delegate, 66 SharedAudioRenderer(const scoped_refptr<MediaStreamAudioRenderer>& delegate,
62 const blink::WebMediaStream& media_stream, 67 const blink::WebMediaStream& media_stream,
63 const OnPlayStateChanged& on_play_state_changed) 68 const OnPlayStateChanged& on_play_state_changed,
69 OnPlayStateRemoved on_play_state_removed)
64 : delegate_(delegate), 70 : delegate_(delegate),
65 media_stream_(media_stream), 71 media_stream_(media_stream),
66 started_(false), 72 started_(false),
67 on_play_state_changed_(on_play_state_changed) { 73 on_play_state_changed_(on_play_state_changed),
74 on_play_state_removed_(std::move(on_play_state_removed)) {
68 DCHECK(!on_play_state_changed_.is_null()); 75 DCHECK(!on_play_state_changed_.is_null());
69 DCHECK(!media_stream_.isNull()); 76 DCHECK(!media_stream_.isNull());
70 } 77 }
71 78
72 protected: 79 protected:
73 ~SharedAudioRenderer() override { 80 ~SharedAudioRenderer() override {
74 DCHECK(thread_checker_.CalledOnValidThread()); 81 DCHECK(thread_checker_.CalledOnValidThread());
75 DVLOG(1) << __func__; 82 DVLOG(1) << __func__;
76 Stop(); 83 Stop();
84 std::move(on_play_state_removed_).Run(&playing_state_);
77 } 85 }
78 86
79 void Start() override { 87 void Start() override {
80 DCHECK(thread_checker_.CalledOnValidThread()); 88 DCHECK(thread_checker_.CalledOnValidThread());
81 if (started_) 89 if (started_)
82 return; 90 return;
83 started_ = true; 91 started_ = true;
84 delegate_->Start(); 92 delegate_->Start();
85 } 93 }
86 94
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 return delegate_->IsLocalRenderer(); 149 return delegate_->IsLocalRenderer();
142 } 150 }
143 151
144 private: 152 private:
145 base::ThreadChecker thread_checker_; 153 base::ThreadChecker thread_checker_;
146 const scoped_refptr<MediaStreamAudioRenderer> delegate_; 154 const scoped_refptr<MediaStreamAudioRenderer> delegate_;
147 const blink::WebMediaStream media_stream_; 155 const blink::WebMediaStream media_stream_;
148 bool started_; 156 bool started_;
149 WebRtcAudioRenderer::PlayingState playing_state_; 157 WebRtcAudioRenderer::PlayingState playing_state_;
150 OnPlayStateChanged on_play_state_changed_; 158 OnPlayStateChanged on_play_state_changed_;
159 OnPlayStateRemoved on_play_state_removed_;
151 }; 160 };
152 161
153 } // namespace 162 } // namespace
154 163
155 WebRtcAudioRenderer::WebRtcAudioRenderer( 164 WebRtcAudioRenderer::WebRtcAudioRenderer(
156 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread, 165 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread,
157 const blink::WebMediaStream& media_stream, 166 const blink::WebMediaStream& media_stream,
158 int source_render_frame_id, 167 int source_render_frame_id,
159 int session_id, 168 int session_id,
160 const std::string& device_id, 169 const std::string& device_id,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 222 }
214 sink_->Start(); 223 sink_->Start();
215 sink_->Play(); // Not all the sinks play on start. 224 sink_->Play(); // Not all the sinks play on start.
216 225
217 return true; 226 return true;
218 } 227 }
219 228
220 scoped_refptr<MediaStreamAudioRenderer> 229 scoped_refptr<MediaStreamAudioRenderer>
221 WebRtcAudioRenderer::CreateSharedAudioRendererProxy( 230 WebRtcAudioRenderer::CreateSharedAudioRendererProxy(
222 const blink::WebMediaStream& media_stream) { 231 const blink::WebMediaStream& media_stream) {
223 content::SharedAudioRenderer::OnPlayStateChanged on_play_state_changed = 232 SharedAudioRenderer::OnPlayStateChanged on_play_state_changed =
224 base::Bind(&WebRtcAudioRenderer::OnPlayStateChanged, this); 233 base::Bind(&WebRtcAudioRenderer::OnPlayStateChanged, this);
225 return new SharedAudioRenderer(this, media_stream, on_play_state_changed); 234 SharedAudioRenderer::OnPlayStateRemoved on_play_state_removed =
235 base::BindOnce(&WebRtcAudioRenderer::OnPlayStateRemoved, this);
236 return new SharedAudioRenderer(this, media_stream, on_play_state_changed,
237 std::move(on_play_state_removed));
226 } 238 }
227 239
228 bool WebRtcAudioRenderer::IsStarted() const { 240 bool WebRtcAudioRenderer::IsStarted() const {
229 DCHECK(thread_checker_.CalledOnValidThread()); 241 DCHECK(thread_checker_.CalledOnValidThread());
230 return start_ref_count_ != 0; 242 return start_ref_count_ != 0;
231 } 243 }
232 244
233 bool WebRtcAudioRenderer::CurrentThreadIsRenderingThread() { 245 bool WebRtcAudioRenderer::CurrentThreadIsRenderingThread() {
234 return sink_->CurrentThreadIsRenderingThread(); 246 return sink_->CurrentThreadIsRenderingThread();
235 } 247 }
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 if (!state->playing()) { 598 if (!state->playing()) {
587 if (RemovePlayingState(source, state)) 599 if (RemovePlayingState(source, state))
588 EnterPauseState(); 600 EnterPauseState();
589 } else if (AddPlayingState(source, state)) { 601 } else if (AddPlayingState(source, state)) {
590 EnterPlayState(); 602 EnterPlayState();
591 } 603 }
592 UpdateSourceVolume(source); 604 UpdateSourceVolume(source);
593 } 605 }
594 } 606 }
595 607
608 void WebRtcAudioRenderer::OnPlayStateRemoved(PlayingState* state) {
609 // It is possible we associated |state| to a source for a track that is no
610 // longer easily reachable. We iterate over |source_playing_states_| to
611 // ensure there are no dangling pointers to |state| there. See
612 // crbug.com/697256.
613 // TODO(maxmorin): Clean up cleanup code in this and related classes so that
614 // this hack isn't necessary.
615 DCHECK(thread_checker_.CalledOnValidThread());
616 for (auto it = source_playing_states_.begin();
617 it != source_playing_states_.end();) {
618 PlayingStates& states = it->second;
619 // We cannot use RemovePlayingState as it might invalidate |it|.
620 states.erase(std::remove(states.begin(), states.end(), state),
621 states.end());
622 if (states.empty())
623 it = source_playing_states_.erase(it);
624 else
625 ++it;
626 }
627 }
628
596 void WebRtcAudioRenderer::PrepareSink() { 629 void WebRtcAudioRenderer::PrepareSink() {
597 DCHECK(thread_checker_.CalledOnValidThread()); 630 DCHECK(thread_checker_.CalledOnValidThread());
598 media::AudioParameters new_sink_params; 631 media::AudioParameters new_sink_params;
599 { 632 {
600 base::AutoLock lock(lock_); 633 base::AutoLock lock(lock_);
601 new_sink_params = sink_params_; 634 new_sink_params = sink_params_;
602 } 635 }
603 636
604 const media::OutputDeviceInfo& device_info = sink_->GetOutputDeviceInfo(); 637 const media::OutputDeviceInfo& device_info = sink_->GetOutputDeviceInfo();
605 DCHECK_EQ(device_info.device_status(), media::OUTPUT_DEVICE_STATUS_OK); 638 DCHECK_EQ(device_info.device_status(), media::OUTPUT_DEVICE_STATUS_OK);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 sink_params_ = new_sink_params; 691 sink_params_ = new_sink_params;
659 } 692 }
660 693
661 // Specify the latency info to be passed to the browser side. 694 // Specify the latency info to be passed to the browser side.
662 new_sink_params.set_latency_tag(AudioDeviceFactory::GetSourceLatencyType( 695 new_sink_params.set_latency_tag(AudioDeviceFactory::GetSourceLatencyType(
663 AudioDeviceFactory::AudioDeviceFactory::kSourceWebRtc)); 696 AudioDeviceFactory::AudioDeviceFactory::kSourceWebRtc));
664 sink_->Initialize(new_sink_params, this); 697 sink_->Initialize(new_sink_params, this);
665 } 698 }
666 699
667 } // namespace content 700 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698