Commit 98b08b03 authored by Alex Leung's avatar Alex Leung Committed by Commit Bot

Allow constants in AudioRendererAlgorithm to be configurable.

This is needed by Cast to change the values of the constants when Multizone is
enabled.

Bug: 124402185
Change-Id: I4563ec0c9de875cf998ffc8ebedc7b2b701b80e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1610842Reviewed-by: default avatarKenneth MacKay <kmackay@chromium.org>
Reviewed-by: default avatarAlex Moshchuk <alexmos@chromium.org>
Reviewed-by: default avatarAvi Drissman <avi@chromium.org>
Reviewed-by: default avatarYuchen Liu <yucliu@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Commit-Queue: Alex Leung <alexleung@google.com>
Cr-Commit-Position: refs/heads/master@{#659706}
parent b5110595
......@@ -24,6 +24,7 @@
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
#include "media/base/audio_parameters.h"
#include "media/base/media.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "services/service_manager/public/cpp/connector.h"
......@@ -306,5 +307,11 @@ CastContentRendererClient::CreateURLLoaderThrottleProvider(
return std::make_unique<CastURLLoaderThrottleProvider>(type);
}
base::Optional<::media::AudioRendererAlgorithmParameters>
CastContentRendererClient::GetAudioRendererAlgorithmParameters(
::media::AudioParameters audio_parameters) {
return base::nullopt;
}
} // namespace shell
} // namespace chromecast
......@@ -14,6 +14,7 @@
#include "chromecast/common/mojom/application_media_capabilities.mojom.h"
#include "content/public/renderer/content_renderer_client.h"
#include "media/base/audio_codecs.h"
#include "media/base/audio_parameters.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace extensions {
......@@ -71,6 +72,9 @@ class CastContentRendererClient
std::unique_ptr<content::URLLoaderThrottleProvider>
CreateURLLoaderThrottleProvider(
content::URLLoaderThrottleProviderType type) override;
base::Optional<::media::AudioRendererAlgorithmParameters>
GetAudioRendererAlgorithmParameters(
::media::AudioParameters audio_parameters) override;
protected:
CastContentRendererClient();
......
......@@ -271,4 +271,10 @@ bool ContentRendererClient::RequiresHtmlImports(const GURL& url) {
return false;
}
base::Optional<::media::AudioRendererAlgorithmParameters>
ContentRendererClient::GetAudioRendererAlgorithmParameters(
media::AudioParameters audio_parameters) {
return base::nullopt;
}
} // namespace content
......@@ -22,6 +22,7 @@
#include "content/public/common/content_client.h"
#include "content/public/renderer/url_loader_throttle_provider.h"
#include "content/public/renderer/websocket_handshake_throttle_provider.h"
#include "media/base/audio_parameters.h"
#include "media/base/supported_types.h"
#include "services/service_manager/public/mojom/service.mojom.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
......@@ -431,6 +432,11 @@ class CONTENT_EXPORT ContentRendererClient {
// TODO(https://crbug.com/937747): Remove this function, when all WebUIs have
// been migrated to use the HTML Imports Polyfill.
virtual bool RequiresHtmlImports(const GURL& url);
// Optionally returns audio renderer algorithm parameters.
virtual base::Optional<::media::AudioRendererAlgorithmParameters>
GetAudioRendererAlgorithmParameters(
::media::AudioParameters audio_parameters);
};
} // namespace content
......
......@@ -9,6 +9,7 @@
#include "base/time/default_tick_clock.h"
#include "content/public/common/content_client.h"
#include "content/public/renderer/content_renderer_client.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_switches.h"
#include "media/base/video_color_space.h"
#include "ui/display/display_switches.h"
......@@ -47,4 +48,11 @@ bool RenderMediaClient::IsSupportedBitstreamAudioCodec(
return GetContentClient()->renderer()->IsSupportedBitstreamAudioCodec(codec);
}
base::Optional<::media::AudioRendererAlgorithmParameters>
RenderMediaClient::GetAudioRendererAlgorithmParameters(
media::AudioParameters audio_parameters) {
return GetContentClient()->renderer()->GetAudioRendererAlgorithmParameters(
audio_parameters);
}
} // namespace content
......@@ -6,6 +6,7 @@
#define CONTENT_RENDERER_MEDIA_RENDER_MEDIA_CLIENT_H_
#include "content/common/content_export.h"
#include "media/base/audio_parameters.h"
#include "media/base/media_client.h"
namespace content {
......@@ -26,6 +27,9 @@ class CONTENT_EXPORT RenderMediaClient : public media::MediaClient {
bool IsSupportedAudioType(const media::AudioType& type) final;
bool IsSupportedVideoType(const media::VideoType& type) final;
bool IsSupportedBitstreamAudioCodec(media::AudioCodec codec) final;
base::Optional<::media::AudioRendererAlgorithmParameters>
GetAudioRendererAlgorithmParameters(
media::AudioParameters audio_parameters) final;
private:
RenderMediaClient();
......
......@@ -78,6 +78,22 @@ struct MEDIA_SHMEM_EXPORT AudioOutputBuffer {
int8_t audio[1];
};
struct MEDIA_SHMEM_EXPORT AudioRendererAlgorithmParameters {
// The maximum size for the audio buffer.
base::TimeDelta max_capacity;
// The minimum size for the audio buffer.
base::TimeDelta starting_capacity;
// The minimum size for the audio buffer for encrypted streams.
// Set this to be larger than |max_capacity| because the
// performance of encrypted playback is always worse than clear playback, due
// to decryption and potentially IPC overhead. For the context, see
// https://crbug.com/403462, https://crbug.com/718161 and
// https://crbug.com/879970.
base::TimeDelta starting_capacity_for_encrypted;
};
// These convenience function safely computes the size required for
// |shared_memory_count| AudioInputBuffers, with enough memory for AudioBus
// data, using |paremeters| (or alternatively |channels| and |frames|). The
......
......@@ -13,6 +13,7 @@
#include <vector>
#include "base/logging.h"
#include "media/base/audio_parameters.h"
#include "media/base/decrypt_config.h"
#include "media/base/eme_constants.h"
#include "media/base/key_systems.h"
......@@ -271,6 +272,9 @@ class TestMediaClient : public MediaClient {
// test the key system update case.
void DisableExternalKeySystemSupport();
base::Optional<::media::AudioRendererAlgorithmParameters>
GetAudioRendererAlgorithmParameters(AudioParameters audio_parameters) final;
private:
bool is_update_needed_;
bool supports_external_key_system_;
......@@ -317,6 +321,12 @@ void TestMediaClient::DisableExternalKeySystemSupport() {
supports_external_key_system_ = false;
}
base::Optional<::media::AudioRendererAlgorithmParameters>
TestMediaClient::GetAudioRendererAlgorithmParameters(
AudioParameters audio_parameters) {
return base::nullopt;
}
} // namespace
class KeySystemsTest : public testing::Test {
......
......@@ -9,7 +9,9 @@
#include <string>
#include <vector>
#include "base/optional.h"
#include "media/base/audio_codecs.h"
#include "media/base/audio_parameters.h"
#include "media/base/key_system_properties.h"
#include "media/base/media_export.h"
#include "media/base/media_types.h"
......@@ -57,6 +59,10 @@ class MEDIA_EXPORT MediaClient {
// Returns true if the compressed audio |codec| format is supported by the
// audio sink.
virtual bool IsSupportedBitstreamAudioCodec(AudioCodec codec) = 0;
// Optionally returns audio renderer algorithm parameters.
virtual base::Optional<::media::AudioRendererAlgorithmParameters>
GetAudioRendererAlgorithmParameters(AudioParameters audio_parameters) = 0;
};
} // namespace media
......
......@@ -15,6 +15,7 @@
#include "base/macros.h"
#include "media/base/audio_decoder.h"
#include "media/base/audio_decoder_config.h"
#include "media/base/audio_parameters.h"
#include "media/base/audio_renderer.h"
#include "media/base/cdm_config.h"
#include "media/base/cdm_context.h"
......@@ -622,6 +623,9 @@ class MockMediaClient : public media::MediaClient {
MOCK_METHOD1(IsSupportedAudioType, bool(const media::AudioType& type));
MOCK_METHOD1(IsSupportedVideoType, bool(const media::VideoType& type));
MOCK_METHOD1(IsSupportedBitstreamAudioCodec, bool(media::AudioCodec codec));
MOCK_METHOD1(GetAudioRendererAlgorithmParameters,
base::Optional<::media::AudioRendererAlgorithmParameters>(
media::AudioParameters audio_parameters));
private:
DISALLOW_COPY_AND_ASSIGN(MockMediaClient);
......
......@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "cc/base/math_util.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_timestamp_helper.h"
#include "media/base/limits.h"
#include "media/filters/wsola_internals.h"
......@@ -46,28 +47,38 @@ namespace media {
// |search_block_center_offset_|.
// Overlap-and-add window size in milliseconds.
static const int kOlaWindowSizeMs = 20;
constexpr base::TimeDelta kOlaWindowSize =
base::TimeDelta::FromMilliseconds(20);
// Size of search interval in milliseconds. The search interval is
// [-delta delta] around |output_index_| * |playback_rate|. So the search
// interval is 2 * delta.
static const int kWsolaSearchIntervalMs = 30;
constexpr base::TimeDelta kWsolaSearchInterval =
base::TimeDelta::FromMilliseconds(30);
// The maximum size in seconds for the |audio_buffer_|. Arbitrarily determined.
static const int kMaxCapacityInSeconds = 3;
// The maximum size for the |audio_buffer_|. Arbitrarily determined.
constexpr base::TimeDelta kMaxCapacity = base::TimeDelta::FromSeconds(3);
// The minimum size in ms for the |audio_buffer_|. Arbitrarily determined.
static const int kStartingCapacityInMs = 200;
// The minimum size for the |audio_buffer_|. Arbitrarily determined.
constexpr base::TimeDelta kStartingCapacity =
base::TimeDelta::FromMilliseconds(200);
// The minimum size in ms for the |audio_buffer_| for encrypted streams.
// Set this to be larger than |kStartingCapacityInMs| because the performance of
// The minimum size for the |audio_buffer_| for encrypted streams.
// Set this to be larger than |kStartingCapacity| because the performance of
// encrypted playback is always worse than clear playback, due to decryption and
// potentially IPC overhead. For the context, see https://crbug.com/403462,
// https://crbug.com/718161 and https://crbug.com/879970.
static const int kStartingCapacityForEncryptedInMs = 500;
constexpr base::TimeDelta kStartingCapacityForEncrypted =
base::TimeDelta::FromMilliseconds(500);
AudioRendererAlgorithm::AudioRendererAlgorithm()
: channels_(0),
: AudioRendererAlgorithm(
{kMaxCapacity, kStartingCapacity, kStartingCapacityForEncrypted}) {}
AudioRendererAlgorithm::AudioRendererAlgorithm(
AudioRendererAlgorithmParameters params)
: audio_renderer_algorithm_params_(std::move(params)),
channels_(0),
samples_per_second_(0),
is_bitstream_format_(false),
capacity_(0),
......@@ -92,14 +103,20 @@ void AudioRendererAlgorithm::Initialize(const AudioParameters& params,
samples_per_second_ = params.sample_rate();
is_bitstream_format_ = params.IsBitstreamFormat();
initial_capacity_ = capacity_ = std::max(
params.frames_per_buffer() * 2,
ConvertMillisecondsToFrames(is_encrypted
? kStartingCapacityForEncryptedInMs
: kStartingCapacityInMs));
max_capacity_ =
std::max(initial_capacity_, kMaxCapacityInSeconds * samples_per_second_);
num_candidate_blocks_ = ConvertMillisecondsToFrames(kWsolaSearchIntervalMs);
ola_window_size_ = ConvertMillisecondsToFrames(kOlaWindowSizeMs);
static_cast<int64_t>(params.frames_per_buffer()) * 2,
AudioTimestampHelper::TimeToFrames(
is_encrypted
? audio_renderer_algorithm_params_.starting_capacity_for_encrypted
: audio_renderer_algorithm_params_.starting_capacity,
samples_per_second_));
max_capacity_ = std::max(
initial_capacity_,
AudioTimestampHelper::TimeToFrames(
audio_renderer_algorithm_params_.max_capacity, samples_per_second_));
num_candidate_blocks_ = AudioTimestampHelper::TimeToFrames(
kWsolaSearchInterval, samples_per_second_);
ola_window_size_ =
AudioTimestampHelper::TimeToFrames(kOlaWindowSize, samples_per_second_);
// Make sure window size in an even number.
ola_window_size_ += ola_window_size_ & 1;
......@@ -249,11 +266,6 @@ bool AudioRendererAlgorithm::CanPerformWsola() const {
search_block_index_ + search_block_size <= frames;
}
int AudioRendererAlgorithm::ConvertMillisecondsToFrames(int ms) const {
return ms * (samples_per_second_ /
static_cast<double>(base::Time::kMillisecondsPerSecond));
}
bool AudioRendererAlgorithm::RunOneWsolaIteration(double playback_rate) {
if (!CanPerformWsola())
return false;
......
......@@ -39,6 +39,7 @@ class AudioBus;
class MEDIA_EXPORT AudioRendererAlgorithm {
public:
AudioRendererAlgorithm();
AudioRendererAlgorithm(AudioRendererAlgorithmParameters params);
~AudioRendererAlgorithm();
// Initializes this object with information about the audio stream.
......@@ -139,14 +140,14 @@ class MEDIA_EXPORT AudioRendererAlgorithm {
// Do we have enough data to perform one round of WSOLA?
bool CanPerformWsola() const;
// Converts a time in milliseconds to frames using |samples_per_second_|.
int ConvertMillisecondsToFrames(int ms) const;
// Creates or recreates |target_block_wrapper_| and |search_block_wrapper_|
// after a |channel_mask_| change. May be called at anytime after a channel
// mask has been specified.
void CreateSearchWrappers();
// Parameters.
AudioRendererAlgorithmParameters audio_renderer_algorithm_params_;
// Number of channels in audio stream.
int channels_;
......@@ -160,7 +161,7 @@ class MEDIA_EXPORT AudioRendererAlgorithm {
AudioBufferQueue audio_buffer_;
// How many frames to have in the queue before we report the queue is full.
int capacity_;
int64_t capacity_;
// Book keeping of the current time of generated audio, in frames. This
// should be appropriately updated when out samples are generated, regardless
......@@ -234,8 +235,8 @@ class MEDIA_EXPORT AudioRendererAlgorithm {
std::unique_ptr<AudioBus> target_block_wrapper_;
// The initial and maximum capacity calculated by Initialize().
int initial_capacity_;
int max_capacity_;
int64_t initial_capacity_;
int64_t max_capacity_;
DISALLOW_COPY_AND_ASSIGN(AudioRendererAlgorithm);
};
......
......@@ -613,7 +613,16 @@ void AudioRendererImpl::OnAudioDecoderStreamInitialized(bool success) {
// We're all good! Continue initializing the rest of the audio renderer
// based on the decoder format.
algorithm_.reset(new AudioRendererAlgorithm());
auto* media_client = GetMediaClient();
auto params =
(media_client ? media_client->GetAudioRendererAlgorithmParameters(
audio_parameters_)
: base::nullopt);
if (params) {
algorithm_ = std::make_unique<AudioRendererAlgorithm>(params.value());
} else {
algorithm_ = std::make_unique<AudioRendererAlgorithm>();
}
algorithm_->Initialize(audio_parameters_, is_encrypted_);
ConfigureChannelMask();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment