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

Side by Side Diff: content/renderer/media/webrtc/peer_connection_remote_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: REBASE + Workaround to ensure MediaStreamAudioProcessor is destroyed on the main thread. Created 4 years, 7 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/media/webrtc/peer_connection_remote_audio_source.h"
6
7 #include "base/logging.h"
8 #include "base/time/time.h"
9 #include "media/base/audio_bus.h"
10
11 namespace content {
12
13 namespace {
14 // Used as an identifier for the down-casters.
15 void* const kClassIdentifier = const_cast<void**>(&kClassIdentifier);
16 } // namespace
17
18 PeerConnectionRemoteAudioTrack::PeerConnectionRemoteAudioTrack(
19 scoped_refptr<webrtc::AudioTrackInterface> track_interface)
20 : MediaStreamAudioTrack(false /* is_local_track */),
21 track_interface_(std::move(track_interface)) {
22 DVLOG(1)
23 << "PeerConnectionRemoteAudioTrack::PeerConnectionRemoteAudioTrack()";
24 }
25
26 PeerConnectionRemoteAudioTrack::~PeerConnectionRemoteAudioTrack() {
27 DVLOG(1)
28 << "PeerConnectionRemoteAudioTrack::~PeerConnectionRemoteAudioTrack()";
29 // Ensure the track is stopped.
30 MediaStreamAudioTrack::Stop();
31 }
32
33 // static
34 PeerConnectionRemoteAudioTrack* PeerConnectionRemoteAudioTrack::From(
35 MediaStreamAudioTrack* track) {
36 if (track && track->GetClassIdentifier() == kClassIdentifier)
37 return static_cast<PeerConnectionRemoteAudioTrack*>(track);
38 return nullptr;
39 }
40
41 void PeerConnectionRemoteAudioTrack::SetEnabled(bool enabled) {
42 DCHECK(thread_checker_.CalledOnValidThread());
43
44 // This affects the shared state of the source for whether or not it's a part
45 // of the mixed audio that's rendered for remote tracks from WebRTC.
46 // All tracks from the same source will share this state and thus can step
47 // on each other's toes.
48 // This is also why we can't check the enabled state for equality with
49 // |enabled| before setting the mixing enabled state. This track's enabled
50 // state and the shared state might not be the same.
51 track_interface_->set_enabled(enabled);
52
53 MediaStreamAudioTrack::SetEnabled(enabled);
54 }
55
56 void* PeerConnectionRemoteAudioTrack::GetClassIdentifier() const {
57 return kClassIdentifier;
58 }
59
60 PeerConnectionRemoteAudioSource::PeerConnectionRemoteAudioSource(
61 scoped_refptr<webrtc::AudioTrackInterface> track_interface)
62 : MediaStreamAudioSource(false /* is_local_source */),
63 track_interface_(std::move(track_interface)),
64 is_sink_of_peer_connection_(false) {
65 DCHECK(track_interface_);
66 DVLOG(1)
67 << "PeerConnectionRemoteAudioSource::PeerConnectionRemoteAudioSource()";
68 }
69
70 PeerConnectionRemoteAudioSource::~PeerConnectionRemoteAudioSource() {
71 DVLOG(1)
72 << "PeerConnectionRemoteAudioSource::~PeerConnectionRemoteAudioSource()";
73 EnsureSourceIsStopped();
74 }
75
76 std::unique_ptr<MediaStreamAudioTrack>
77 PeerConnectionRemoteAudioSource::CreateMediaStreamAudioTrack(
78 const std::string& id) {
79 DCHECK(thread_checker_.CalledOnValidThread());
80 return std::unique_ptr<MediaStreamAudioTrack>(
81 new PeerConnectionRemoteAudioTrack(track_interface_));
82 }
83
84 bool PeerConnectionRemoteAudioSource::EnsureSourceIsStarted() {
85 DCHECK(thread_checker_.CalledOnValidThread());
86 if (is_sink_of_peer_connection_)
87 return true;
88 VLOG(1) << "Starting PeerConnection remote audio source with id="
89 << track_interface_->id();
90 track_interface_->AddSink(this);
91 is_sink_of_peer_connection_ = true;
92 return true;
93 }
94
95 void PeerConnectionRemoteAudioSource::EnsureSourceIsStopped() {
96 DCHECK(thread_checker_.CalledOnValidThread());
97 if (is_sink_of_peer_connection_) {
98 track_interface_->RemoveSink(this);
99 is_sink_of_peer_connection_ = false;
100 VLOG(1) << "Stopped PeerConnection remote audio source with id="
101 << track_interface_->id();
102 }
103 }
104
105 void PeerConnectionRemoteAudioSource::OnData(const void* audio_data,
106 int bits_per_sample,
107 int sample_rate,
108 size_t number_of_channels,
109 size_t number_of_frames) {
110 // Debug builds: Note that this lock isn't meant to synchronize anything.
111 // Instead, it is being used as a run-time check to ensure there isn't already
112 // another thread executing this method. The reason we don't use
113 // base::ThreadChecker here is because we shouldn't be making assumptions
114 // about the private threading model of libjingle. For example, it would be
115 // legitimate for libjingle to use a different thread to invoke this method
116 // whenever the audio format changes.
117 #ifndef NDEBUG
118 const bool is_only_thread_here = single_audio_thread_guard_.Try();
119 DCHECK(is_only_thread_here);
120 #endif
121
122 // TODO(tommi): We should get the timestamp from WebRTC.
123 base::TimeTicks playout_time(base::TimeTicks::Now());
124
125 if (!audio_bus_ ||
126 static_cast<size_t>(audio_bus_->channels()) != number_of_channels ||
127 static_cast<size_t>(audio_bus_->frames()) != number_of_frames) {
128 audio_bus_ = media::AudioBus::Create(number_of_channels, number_of_frames);
129 }
130
131 audio_bus_->FromInterleaved(audio_data, number_of_frames,
132 bits_per_sample / 8);
133
134 media::AudioParameters params = MediaStreamAudioSource::GetAudioParameters();
135 if (!params.IsValid() ||
136 params.format() != media::AudioParameters::AUDIO_PCM_LOW_LATENCY ||
137 static_cast<size_t>(params.channels()) != number_of_channels ||
138 params.sample_rate() != sample_rate ||
139 static_cast<size_t>(params.frames_per_buffer()) != number_of_frames) {
140 MediaStreamAudioSource::SetFormat(
141 media::AudioParameters(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
142 media::GuessChannelLayout(number_of_channels),
143 sample_rate, bits_per_sample, number_of_frames));
144 }
145
146 MediaStreamAudioSource::DeliverDataToTracks(*audio_bus_, playout_time);
147
148 #ifndef NDEBUG
149 single_audio_thread_guard_.Release();
150 #endif
151 }
152
153 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698