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

Unified Diff: content/renderer/media/webrtc_local_audio_track.cc

Issue 23691038: Switch LiveAudio to source provider solution. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed Tommi's comments and added unittest Created 7 years, 3 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
Index: content/renderer/media/webrtc_local_audio_track.cc
diff --git a/content/renderer/media/webrtc_local_audio_track.cc b/content/renderer/media/webrtc_local_audio_track.cc
index 3687b248e23a7d5cbbba467b99510688e53e0090..13f3d68c35dd672528af5a4a161cc7a201c4f6f4 100644
--- a/content/renderer/media/webrtc_local_audio_track.cc
+++ b/content/renderer/media/webrtc_local_audio_track.cc
@@ -4,12 +4,16 @@
#include "content/renderer/media/webrtc_local_audio_track.h"
+#include "content/renderer/media/webaudio_capturer_source.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
#include "content/renderer/media/webrtc_audio_capturer_sink_owner.h"
+#include "content/renderer/media/webrtc_local_audio_source_provider.h"
+#include "media/base/audio_fifo.h"
#include "third_party/libjingle/source/talk/media/base/audiorenderer.h"
namespace content {
+static const size_t kMaxNumberOfBuffersInFifo = 2;
static const char kAudioTrackKind[] = "audio";
namespace {
@@ -47,28 +51,86 @@ bool NeedsAudioProcessing(
} // namespace.
+// This is a temporary audio buffer with parameters used to send data to
+// callbacks.
+class WebRtcLocalAudioTrack::ConfiguredBuffer :
+ public base::RefCounted<WebRtcLocalAudioTrack::ConfiguredBuffer> {
+ public:
+ ConfiguredBuffer() : sink_buffer_size_(0) {}
+
+ void Initialize(const media::AudioParameters& params) {
+ DCHECK(params.IsValid());
+ params_ = params;
+
+ // Use 10ms as the sink buffer size since that is the native packet size
+ // WebRtc is running on.
+ sink_buffer_size_ = params.sample_rate() / 100;
+ audio_wrapper_ =
+ media::AudioBus::Create(params.channels(),sink_buffer_size_);
tommi (sloooow) - chröme 2013/09/10 16:00:38 space after ,
no longer working on chromium 2013/09/11 10:22:07 Done.
+ buffer_.reset(new int16[params.frames_per_buffer() * params.channels()]);
+
+ // The size of the FIFO should be at least twice of the source buffer size
+ // or twice of the sink buffer size.
+ int buffer_size = std::max(
+ kMaxNumberOfBuffersInFifo * params.frames_per_buffer(),
+ kMaxNumberOfBuffersInFifo * sink_buffer_size_);
+ fifo_.reset(new media::AudioFifo(params.channels(), buffer_size));
+ }
+
+ void Push(media::AudioBus* audio_source) {
+ DCHECK(fifo_->frames() + audio_source->frames() <= fifo_->max_frames());
+ fifo_->Push(audio_source);
+ }
+
+ bool Consume() {
+ if (fifo_->frames() < audio_wrapper_->frames())
+ return false;
+
+ fifo_->Consume(audio_wrapper_.get(), 0, audio_wrapper_->frames());
+ audio_wrapper_->ToInterleaved(audio_wrapper_->frames(),
+ params_.bits_per_sample() / 8,
+ buffer());
+ return true;
+ }
+
+ int16* buffer() const { return buffer_.get(); }
+ const media::AudioParameters& params() const { return params_; }
+ int sink_buffer_size() const { return sink_buffer_size_; }
+
+ private:
+ ~ConfiguredBuffer() {}
+ friend class base::RefCounted<WebRtcLocalAudioTrack::ConfiguredBuffer>;
+
+ media::AudioParameters params_;
+ scoped_ptr<media::AudioBus> audio_wrapper_;
+ scoped_ptr<media::AudioFifo> fifo_;
+ scoped_ptr<int16[]> buffer_;
+ int sink_buffer_size_;
+};
+
scoped_refptr<WebRtcLocalAudioTrack> WebRtcLocalAudioTrack::Create(
const std::string& id,
const scoped_refptr<WebRtcAudioCapturer>& capturer,
+ WebAudioCapturerSource* webaudio_source,
webrtc::AudioSourceInterface* track_source,
const webrtc::MediaConstraintsInterface* constraints) {
talk_base::RefCountedObject<WebRtcLocalAudioTrack>* track =
new talk_base::RefCountedObject<WebRtcLocalAudioTrack>(
- id, capturer, track_source, constraints);
+ id, capturer, webaudio_source, track_source, constraints);
return track;
}
WebRtcLocalAudioTrack::WebRtcLocalAudioTrack(
const std::string& label,
const scoped_refptr<WebRtcAudioCapturer>& capturer,
+ WebAudioCapturerSource* webaudio_source,
webrtc::AudioSourceInterface* track_source,
const webrtc::MediaConstraintsInterface* constraints)
: webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label),
capturer_(capturer),
+ webaudio_source_(webaudio_source),
track_source_(track_source),
need_audio_processing_(NeedsAudioProcessing(constraints)) {
- // The capturer with a valid device id is using microphone as source,
- // and APM (AudioProcessingModule) is turned on only for microphone data.
DCHECK(capturer.get());
DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()";
}
@@ -80,19 +142,20 @@ WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() {
Stop();
}
-void WebRtcLocalAudioTrack::CaptureData(const int16* audio_data,
- int number_of_channels,
- int number_of_frames,
- int audio_delay_milliseconds,
- int volume,
- bool key_pressed) {
+void WebRtcLocalAudioTrack::Capture(media::AudioBus* audio_source,
+ int audio_delay_milliseconds,
+ int volume,
+ bool key_pressed) {
scoped_refptr<WebRtcAudioCapturer> capturer;
std::vector<int> voe_channels;
int sample_rate = 0;
+ int number_of_channels = 0;
+ int number_of_frames = 0;
SinkList sinks;
+ scoped_refptr<ConfiguredBuffer> current_buffer;
{
base::AutoLock auto_lock(lock_);
- // When the track is diabled, we simply return here.
+ // When the track is disabled, we simply return here.
// TODO(xians): Figure out if we should feed zero to sinks instead, in
// order to inject VAD data in such case.
if (!enabled())
@@ -100,34 +163,60 @@ void WebRtcLocalAudioTrack::CaptureData(const int16* audio_data,
capturer = capturer_;
voe_channels = voe_channels_;
- sample_rate = params_.sample_rate(),
+ current_buffer = buffer_;
+ sample_rate = current_buffer->params().sample_rate();
+ number_of_channels = current_buffer->params().channels();
+ number_of_frames = current_buffer->sink_buffer_size();
sinks = sinks_;
}
- // Feed the data to the sinks.
- for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) {
- int new_volume = (*it)->CaptureData(voe_channels,
- audio_data,
- sample_rate,
- number_of_channels,
- number_of_frames,
- audio_delay_milliseconds,
- volume,
- need_audio_processing_,
- key_pressed);
- if (new_volume != 0 && capturer.get())
- capturer->SetVolume(new_volume);
+ // Push the data to the fifo.
+ current_buffer->Push(audio_source);
+ // Only turn off the audio processing when the constrain is set to false as
+ // well as there is no correct delay value.
+ bool need_audio_processing = need_audio_processing_?
tommi (sloooow) - chröme 2013/09/10 16:00:38 space before ?
no longer working on chromium 2013/09/11 10:22:07 Done.
+ need_audio_processing_ : (audio_delay_milliseconds != 0);
+ int current_volume = volume;
+ while (current_buffer->Consume()) {
+ // Feed the data to the sinks.
+ for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) {
+ int new_volume = (*it)->CaptureData(voe_channels,
+ current_buffer->buffer(),
+ sample_rate,
+ number_of_channels,
+ number_of_frames,
+ audio_delay_milliseconds,
+ current_volume,
+ need_audio_processing,
+ key_pressed);
+ if (new_volume != 0 && capturer.get()) {
+ // Feed the new volume to WebRtc while changing the volume on the
+ // browser.
+ capturer->SetVolume(new_volume);
+ current_volume = new_volume;
+ }
+ }
}
}
void WebRtcLocalAudioTrack::SetCaptureFormat(
const media::AudioParameters& params) {
- base::AutoLock auto_lock(lock_);
- params_ = params;
+ if (!params.IsValid())
+ return;
+
+ scoped_refptr<ConfiguredBuffer> new_buffer(new ConfiguredBuffer());
+ new_buffer->Initialize(params);
+
+ SinkList sinks;
+ {
+ base::AutoLock auto_lock(lock_);
+ buffer_ = new_buffer;
+ sinks = sinks_;
+ }
// Update all the existing sinks with the new format.
- for (SinkList::const_iterator it = sinks_.begin();
- it != sinks_.end(); ++it)
+ for (SinkList::const_iterator it = sinks.begin();
+ it != sinks.end(); ++it)
tommi (sloooow) - chröme 2013/09/10 16:00:38 {}
no longer working on chromium 2013/09/11 10:22:07 Done.
(*it)->SetCaptureFormat(params);
}
@@ -172,7 +261,8 @@ void WebRtcLocalAudioTrack::AddSink(WebRtcAudioCapturerSink* sink) {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()";
base::AutoLock auto_lock(lock_);
- sink->SetCaptureFormat(params_);
+ if (buffer_.get())
+ sink->SetCaptureFormat(buffer_->params());
// Verify that |sink| is not already added to the list.
DCHECK(std::find_if(
@@ -207,8 +297,19 @@ void WebRtcLocalAudioTrack::RemoveSink(
void WebRtcLocalAudioTrack::Start() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(1) << "WebRtcLocalAudioTrack::Start()";
- if (capturer_.get())
- capturer_->AddTrack(this);
+ DCHECK(capturer_.get());
+ if (webaudio_source_.get()) {
+ // If the track is hooking up with WebAudio, do NOT add the track to the
+ // capturer as its sink otherwise two streams in different clock will be
+ // pushed through the same track.
+ WebRtcLocalAudioSourceProvider* source_provider =
+ static_cast<WebRtcLocalAudioSourceProvider*>(
+ capturer_->audio_source_provider());
+ webaudio_source_->Start(this, source_provider);
+ return;
+ }
+
+ capturer_->AddTrack(this);
}
void WebRtcLocalAudioTrack::Stop() {
@@ -217,7 +318,15 @@ void WebRtcLocalAudioTrack::Stop() {
if (!capturer_.get())
return;
- capturer_->RemoveTrack(this);
+ if (webaudio_source_.get()) {
+ // Called Stop() on the |webaudio_source_| explicitly so that
+ // |webaudio_source_| won't push more data to the track anymore.
+ // Also note that the track is not registered as a sink to the |capturer_|
+ // in such case and no need to call RemoveTrack().
+ webaudio_source_->Stop();
+ } else {
+ capturer_->RemoveTrack(this);
+ }
// Protect the pointers using the lock when accessing |sinks_| and
// setting the |capturer_| to NULL.
@@ -225,6 +334,7 @@ void WebRtcLocalAudioTrack::Stop() {
{
base::AutoLock auto_lock(lock_);
sinks = sinks_;
+ webaudio_source_ = NULL;
capturer_ = NULL;
}

Powered by Google App Engine
This is Rietveld 408576698