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

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

Issue 1633423002: MediaStream audio rendering: Bypass audio processing for non-WebRTC cases. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add comment to TrackAudioRenderer header to explain it does not handle remote WebRTC tracks. Created 4 years, 10 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_local_audio_renderer.h ('k') | media/base/audio_shifter.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/renderer/media/webrtc_local_audio_renderer.cc
diff --git a/content/renderer/media/webrtc_local_audio_renderer.cc b/content/renderer/media/webrtc_local_audio_renderer.cc
deleted file mode 100644
index f39a017b94db441164f527fba3b8790aca8d46b0..0000000000000000000000000000000000000000
--- a/content/renderer/media/webrtc_local_audio_renderer.cc
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/webrtc_local_audio_renderer.h"
-
-#include <utility>
-
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/synchronization/lock.h"
-#include "base/thread_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
-#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/media_stream_dispatcher.h"
-#include "content/renderer/media/webrtc_audio_capturer.h"
-#include "content/renderer/media/webrtc_audio_renderer.h"
-#include "content/renderer/render_frame_impl.h"
-#include "media/audio/audio_output_device.h"
-#include "media/base/audio_bus.h"
-#include "media/base/audio_shifter.h"
-
-namespace content {
-
-namespace {
-
-enum LocalRendererSinkStates {
- kSinkStarted = 0,
- kSinkNeverStarted,
- kSinkStatesMax // Must always be last!
-};
-
-} // namespace
-
-// media::AudioRendererSink::RenderCallback implementation
-int WebRtcLocalAudioRenderer::Render(media::AudioBus* audio_bus,
- uint32_t audio_delay_milliseconds,
- uint32_t frames_skipped) {
- TRACE_EVENT0("audio", "WebRtcLocalAudioRenderer::Render");
- base::AutoLock auto_lock(thread_lock_);
-
- if (!playing_ || !volume_ || !audio_shifter_) {
- audio_bus->Zero();
- return 0;
- }
-
- audio_shifter_->Pull(
- audio_bus,
- base::TimeTicks::Now() -
- base::TimeDelta::FromMilliseconds(audio_delay_milliseconds));
-
- return audio_bus->frames();
-}
-
-void WebRtcLocalAudioRenderer::OnRenderError() {
- NOTIMPLEMENTED();
-}
-
-// content::MediaStreamAudioSink implementation
-void WebRtcLocalAudioRenderer::OnData(const media::AudioBus& audio_bus,
- base::TimeTicks estimated_capture_time) {
- DCHECK(capture_thread_checker_.CalledOnValidThread());
- DCHECK(!estimated_capture_time.is_null());
-
- TRACE_EVENT0("audio", "WebRtcLocalAudioRenderer::CaptureData");
-
- base::AutoLock auto_lock(thread_lock_);
- if (!playing_ || !volume_ || !audio_shifter_)
- return;
-
- scoped_ptr<media::AudioBus> audio_data(
- media::AudioBus::Create(audio_bus.channels(), audio_bus.frames()));
- audio_bus.CopyTo(audio_data.get());
- audio_shifter_->Push(std::move(audio_data), estimated_capture_time);
- const base::TimeTicks now = base::TimeTicks::Now();
- total_render_time_ += now - last_render_time_;
- last_render_time_ = now;
-}
-
-void WebRtcLocalAudioRenderer::OnSetFormat(
- const media::AudioParameters& params) {
- DVLOG(1) << "WebRtcLocalAudioRenderer::OnSetFormat()";
- // If the source is restarted, we might have changed to another capture
- // thread.
- capture_thread_checker_.DetachFromThread();
- DCHECK(capture_thread_checker_.CalledOnValidThread());
-
- // Post a task on the main render thread to reconfigure the |sink_| with the
- // new format.
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&WebRtcLocalAudioRenderer::ReconfigureSink, this, params));
-}
-
-// WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer implementation.
-WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer(
- const blink::WebMediaStreamTrack& audio_track,
- int source_render_frame_id,
- int session_id,
- const std::string& device_id,
- const url::Origin& security_origin)
- : audio_track_(audio_track),
- source_render_frame_id_(source_render_frame_id),
- session_id_(session_id),
- task_runner_(base::ThreadTaskRunnerHandle::Get()),
- playing_(false),
- output_device_id_(device_id),
- security_origin_(security_origin),
- volume_(0.0),
- sink_started_(false) {
- DVLOG(1) << "WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer()";
-}
-
-WebRtcLocalAudioRenderer::~WebRtcLocalAudioRenderer() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK(!sink_.get());
- DVLOG(1) << "WebRtcLocalAudioRenderer::~WebRtcLocalAudioRenderer()";
-}
-
-void WebRtcLocalAudioRenderer::Start() {
- DVLOG(1) << "WebRtcLocalAudioRenderer::Start()";
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- // We get audio data from |audio_track_|...
- MediaStreamAudioSink::AddToAudioTrack(this, audio_track_);
- // ...and |sink_| will get audio data from us.
- DCHECK(!sink_.get());
- sink_ =
- AudioDeviceFactory::NewOutputDevice(source_render_frame_id_, session_id_,
- output_device_id_, security_origin_);
-
- base::AutoLock auto_lock(thread_lock_);
- last_render_time_ = base::TimeTicks::Now();
- playing_ = false;
-}
-
-void WebRtcLocalAudioRenderer::Stop() {
- DVLOG(1) << "WebRtcLocalAudioRenderer::Stop()";
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- {
- base::AutoLock auto_lock(thread_lock_);
- playing_ = false;
- audio_shifter_.reset();
- }
-
- // Stop the output audio stream, i.e, stop asking for data to render.
- // It is safer to call Stop() on the |sink_| to clean up the resources even
- // when the |sink_| is never started.
- if (sink_.get()) {
- sink_->Stop();
- sink_ = NULL;
- }
-
- if (!sink_started_) {
- UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates",
- kSinkNeverStarted, kSinkStatesMax);
- }
- sink_started_ = false;
-
- // Ensure that the capturer stops feeding us with captured audio.
- MediaStreamAudioSink::RemoveFromAudioTrack(this, audio_track_);
-}
-
-void WebRtcLocalAudioRenderer::Play() {
- DVLOG(1) << "WebRtcLocalAudioRenderer::Play()";
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- if (!sink_.get())
- return;
-
- {
- base::AutoLock auto_lock(thread_lock_);
- // Resumes rendering by ensuring that WebRtcLocalAudioRenderer::Render()
- // now reads data from the local FIFO.
- playing_ = true;
- last_render_time_ = base::TimeTicks::Now();
- }
-
- // Note: If volume_ is currently muted, the |sink_| will not be started yet.
- MaybeStartSink();
-}
-
-void WebRtcLocalAudioRenderer::Pause() {
- DVLOG(1) << "WebRtcLocalAudioRenderer::Pause()";
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- if (!sink_.get())
- return;
-
- base::AutoLock auto_lock(thread_lock_);
- // Temporarily suspends rendering audio.
- // WebRtcLocalAudioRenderer::Render() will return early during this state
- // and only zeros will be provided to the active sink.
- playing_ = false;
-}
-
-void WebRtcLocalAudioRenderer::SetVolume(float volume) {
- DVLOG(1) << "WebRtcLocalAudioRenderer::SetVolume(" << volume << ")";
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- {
- base::AutoLock auto_lock(thread_lock_);
- // Cache the volume.
- volume_ = volume;
- }
-
- // Lazily start the |sink_| when the local renderer is unmuted during
- // playing.
- MaybeStartSink();
-
- if (sink_.get())
- sink_->SetVolume(volume);
-}
-
-media::OutputDevice* WebRtcLocalAudioRenderer::GetOutputDevice() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- return this;
-}
-
-base::TimeDelta WebRtcLocalAudioRenderer::GetCurrentRenderTime() const {
- DCHECK(task_runner_->BelongsToCurrentThread());
- base::AutoLock auto_lock(thread_lock_);
- if (!sink_.get())
- return base::TimeDelta();
- return total_render_time();
-}
-
-bool WebRtcLocalAudioRenderer::IsLocalRenderer() const {
- return true;
-}
-
-void WebRtcLocalAudioRenderer::SwitchOutputDevice(
- const std::string& device_id,
- const url::Origin& security_origin,
- const media::SwitchOutputDeviceCB& callback) {
- DVLOG(1) << "WebRtcLocalAudioRenderer::SwitchOutputDevice()";
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- scoped_refptr<media::AudioOutputDevice> new_sink =
- AudioDeviceFactory::NewOutputDevice(source_render_frame_id_, session_id_,
- device_id, security_origin);
- if (new_sink->GetDeviceStatus() != media::OUTPUT_DEVICE_STATUS_OK) {
- callback.Run(new_sink->GetDeviceStatus());
- return;
- }
-
- output_device_id_ = device_id;
- security_origin_ = security_origin;
- bool was_sink_started = sink_started_;
-
- if (sink_.get())
- sink_->Stop();
-
- sink_started_ = false;
- sink_ = new_sink;
- int frames_per_buffer = sink_->GetOutputParameters().frames_per_buffer();
- sink_params_ = source_params_;
- sink_params_.set_frames_per_buffer(WebRtcAudioRenderer::GetOptimalBufferSize(
- source_params_.sample_rate(), frames_per_buffer));
-
- if (was_sink_started)
- MaybeStartSink();
-
- callback.Run(media::OUTPUT_DEVICE_STATUS_OK);
-}
-
-media::AudioParameters WebRtcLocalAudioRenderer::GetOutputParameters() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- if (!sink_.get())
- return media::AudioParameters();
-
- return sink_->GetOutputParameters();
-}
-
-media::OutputDeviceStatus WebRtcLocalAudioRenderer::GetDeviceStatus() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- if (!sink_.get())
- return media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL;
-
- return sink_->GetDeviceStatus();
-}
-
-void WebRtcLocalAudioRenderer::MaybeStartSink() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink()";
-
- if (!sink_.get() || !source_params_.IsValid())
- return;
-
- {
- // Clear up the old data in the FIFO.
- base::AutoLock auto_lock(thread_lock_);
- audio_shifter_->Flush();
- }
-
- if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_ ||
- sink_->GetDeviceStatus() != media::OUTPUT_DEVICE_STATUS_OK)
- return;
-
- DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink() -- Starting sink_.";
- sink_->Initialize(sink_params_, this);
- sink_->Start();
- sink_started_ = true;
- UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates",
- kSinkStarted, kSinkStatesMax);
-}
-
-void WebRtcLocalAudioRenderer::ReconfigureSink(
- const media::AudioParameters& params) {
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()";
-
- if (source_params_.Equals(params))
- return;
-
- // Reset the |source_params_|, |sink_params_| and |loopback_fifo_| to match
- // the new format.
-
- source_params_ = params;
- {
- // Note: The max buffer is fairly large, but will rarely be used.
- // Cast needs the buffer to hold at least one second of audio.
- // The clock accuracy is set to 20ms because clock accuracy is
- // ~15ms on windows.
- media::AudioShifter* const new_shifter = new media::AudioShifter(
- base::TimeDelta::FromSeconds(2),
- base::TimeDelta::FromMilliseconds(20),
- base::TimeDelta::FromSeconds(20),
- source_params_.sample_rate(),
- params.channels());
-
- base::AutoLock auto_lock(thread_lock_);
- audio_shifter_.reset(new_shifter);
- }
-
- if (!sink_.get())
- return; // WebRtcLocalAudioRenderer has not yet been started.
-
- // Stop |sink_| and re-create a new one to be initialized with different audio
- // parameters. Then, invoke MaybeStartSink() to restart everything again.
- sink_->Stop();
- sink_started_ = false;
- sink_ =
- AudioDeviceFactory::NewOutputDevice(source_render_frame_id_, session_id_,
- output_device_id_, security_origin_);
- int frames_per_buffer = sink_->GetOutputParameters().frames_per_buffer();
- sink_params_ = source_params_;
- sink_params_.set_frames_per_buffer(WebRtcAudioRenderer::GetOptimalBufferSize(
- source_params_.sample_rate(), frames_per_buffer));
- MaybeStartSink();
-}
-
-} // namespace content
« no previous file with comments | « content/renderer/media/webrtc_local_audio_renderer.h ('k') | media/base/audio_shifter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698