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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/media/webrtc_audio_renderer.cc
diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc
index 32c27bf8be65487b9e021bf5e6a3e95d8345ab66..f6801862af369539c8d9e7ccca595a1b27dfe1b2 100644
--- a/content/renderer/media/webrtc_audio_renderer.cc
+++ b/content/renderer/media/webrtc_audio_renderer.cc
@@ -54,17 +54,24 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
public:
// Callback definition for a callback that is called when when Play(), Pause()
// or SetVolume are called (whenever the internal |playing_state_| changes).
- typedef base::Callback<void(const blink::WebMediaStream&,
- WebRtcAudioRenderer::PlayingState*)>
- OnPlayStateChanged;
+ using OnPlayStateChanged =
+ base::Callback<void(const blink::WebMediaStream&,
+ WebRtcAudioRenderer::PlayingState*)>;
+
+ // Signals that the PlayingState* is about to become invalid, see comment in
+ // OnPlayStateRemoved.
+ using OnPlayStateRemoved =
+ base::OnceCallback<void(WebRtcAudioRenderer::PlayingState*)>;
SharedAudioRenderer(const scoped_refptr<MediaStreamAudioRenderer>& delegate,
const blink::WebMediaStream& media_stream,
- const OnPlayStateChanged& on_play_state_changed)
+ const OnPlayStateChanged& on_play_state_changed,
+ OnPlayStateRemoved on_play_state_removed)
: delegate_(delegate),
media_stream_(media_stream),
started_(false),
- on_play_state_changed_(on_play_state_changed) {
+ on_play_state_changed_(on_play_state_changed),
+ on_play_state_removed_(std::move(on_play_state_removed)) {
DCHECK(!on_play_state_changed_.is_null());
DCHECK(!media_stream_.isNull());
}
@@ -74,6 +81,7 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << __func__;
Stop();
+ std::move(on_play_state_removed_).Run(&playing_state_);
}
void Start() override {
@@ -148,6 +156,7 @@ class SharedAudioRenderer : public MediaStreamAudioRenderer {
bool started_;
WebRtcAudioRenderer::PlayingState playing_state_;
OnPlayStateChanged on_play_state_changed_;
+ OnPlayStateRemoved on_play_state_removed_;
};
} // namespace
@@ -220,9 +229,12 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
scoped_refptr<MediaStreamAudioRenderer>
WebRtcAudioRenderer::CreateSharedAudioRendererProxy(
const blink::WebMediaStream& media_stream) {
- content::SharedAudioRenderer::OnPlayStateChanged on_play_state_changed =
+ SharedAudioRenderer::OnPlayStateChanged on_play_state_changed =
base::Bind(&WebRtcAudioRenderer::OnPlayStateChanged, this);
- return new SharedAudioRenderer(this, media_stream, on_play_state_changed);
+ SharedAudioRenderer::OnPlayStateRemoved on_play_state_removed =
+ base::BindOnce(&WebRtcAudioRenderer::OnPlayStateRemoved, this);
+ return new SharedAudioRenderer(this, media_stream, on_play_state_changed,
+ std::move(on_play_state_removed));
}
bool WebRtcAudioRenderer::IsStarted() const {
@@ -593,6 +605,27 @@ void WebRtcAudioRenderer::OnPlayStateChanged(
}
}
+void WebRtcAudioRenderer::OnPlayStateRemoved(PlayingState* state) {
+ // It is possible we associated |state| to a source for a track that is no
+ // longer easily reachable. We iterate over |source_playing_states_| to
+ // ensure there are no dangling pointers to |state| there. See
+ // crbug.com/697256.
+ // TODO(maxmorin): Clean up cleanup code in this and related classes so that
+ // this hack isn't necessary.
+ DCHECK(thread_checker_.CalledOnValidThread());
+ for (auto it = source_playing_states_.begin();
+ it != source_playing_states_.end();) {
+ PlayingStates& states = it->second;
+ // We cannot use RemovePlayingState as it might invalidate |it|.
+ states.erase(std::remove(states.begin(), states.end(), state),
+ states.end());
+ if (states.empty())
+ it = source_playing_states_.erase(it);
+ else
+ ++it;
+ }
+}
+
void WebRtcAudioRenderer::PrepareSink() {
DCHECK(thread_checker_.CalledOnValidThread());
media::AudioParameters new_sink_params;
« 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