Commit 342574ee authored by Dmitry Skiba's avatar Dmitry Skiba Committed by Commit Bot

Lower demuxer stream limits on low-end Android devices.

Currently demuxer stream limits are 12MiB for audio and 150MiB for video,
regardless of the platform. This means that when playing long videos Chrome
will slowly allocate up to 162MiB. Most low-end Android devices can't afford
allocating that much, which translates to bad user experience: first device
becomes sluggish, as OS tries hard to kill other processes / move memory to
zram. Eventually (since renderer keeps allocating) Android gives up and kills
Chrome.

Turns out that Chromecast had similar issues and ended up lowering demuxer
limits to 2MiB for audio / 30MiB for video.

This CL turns demuxer limit constants into functions and selects lower
values on low-end Android devices.

Bug: 810906
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I33fcd7d4916379abcb1f56cf9289928dfe3788a7
Reviewed-on: https://chromium-review.googlesource.com/922884Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Commit-Queue: Dmitry Skiba <dskiba@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537853}
parent 70a4ce30
......@@ -348,10 +348,12 @@ source_set("base") {
deps += [ "//media/base/win" ]
}
if (use_low_memory_buffer) {
sources += [ "demuxer_memory_limit_lowmem.cc" ]
if (is_chromecast) {
sources += [ "demuxer_memory_limit_low.cc" ]
} else if (is_android) {
sources += [ "demuxer_memory_limit_select.cc" ]
} else {
sources += [ "demuxer_memory_limit.cc" ]
sources += [ "demuxer_memory_limit_default.cc" ]
}
}
......
......@@ -13,11 +13,28 @@ namespace media {
// The maximum amount of data (in bytes) a demuxer can keep in memory, for a
// particular type of stream.
extern const size_t kDemuxerStreamAudioMemoryLimit;
extern const size_t kDemuxerStreamVideoMemoryLimit;
MEDIA_EXPORT size_t GetDemuxerStreamAudioMemoryLimit();
MEDIA_EXPORT size_t GetDemuxerStreamVideoMemoryLimit();
// The maximum amount of data (in bytes) a demuxer can keep in memory overall.
extern const size_t kDemuxerMemoryLimit;
MEDIA_EXPORT size_t GetDemuxerMemoryLimit();
namespace internal {
// These values should not be used directly, they are selected by functions
// above based on platform capabilities.
// Default audio memory limit: 12MB (5 minutes of 320Kbps content).
// Low audio memory limit: 2MB (1 minute of 256Kbps content).
constexpr size_t kDemuxerStreamAudioMemoryLimitDefault = 12 * 1024 * 1024;
constexpr size_t kDemuxerStreamAudioMemoryLimitLow = 2 * 1024 * 1024;
// Default video memory limit: 150MB (5 minutes of 4Mbps content).
// Low video memory limit: 30MB (1 minute of 4Mbps content).
constexpr size_t kDemuxerStreamVideoMemoryLimitDefault = 150 * 1024 * 1024;
constexpr size_t kDemuxerStreamVideoMemoryLimitLow = 30 * 1024 * 1024;
} // namespace internal
} // namespace media
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Copyright 2018 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.
......@@ -6,13 +6,17 @@
namespace media {
// 2MB: approximately 1 minute of 256Kbps content.
const size_t kDemuxerStreamAudioMemoryLimit = 2 * 1024 * 1024;
size_t GetDemuxerStreamAudioMemoryLimit() {
return internal::kDemuxerStreamAudioMemoryLimitDefault;
}
// 30MB: approximately 1 minute of 4Mbps content.
const size_t kDemuxerStreamVideoMemoryLimit = 30 * 1024 * 1024;
size_t GetDemuxerStreamVideoMemoryLimit() {
return internal::kDemuxerStreamVideoMemoryLimitDefault;
}
const size_t kDemuxerMemoryLimit =
kDemuxerStreamAudioMemoryLimit + kDemuxerStreamVideoMemoryLimit;
size_t GetDemuxerMemoryLimit() {
return GetDemuxerStreamAudioMemoryLimit() +
GetDemuxerStreamVideoMemoryLimit();
}
} // namespace media
// Copyright 2014 The Chromium Authors. All rights reserved.
// Copyright 2018 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 "media/base/demuxer_memory_limit.h"
#include "build/build_config.h"
namespace media {
// 12MB: approximately 5 minutes of 320Kbps content.
const size_t kDemuxerStreamAudioMemoryLimit = 12 * 1024 * 1024;
size_t GetDemuxerStreamAudioMemoryLimit() {
return internal::kDemuxerStreamAudioMemoryLimitLow;
}
// 150MB: approximately 5 minutes of 4Mbps content.
const size_t kDemuxerStreamVideoMemoryLimit = 150 * 1024 * 1024;
size_t GetDemuxerStreamVideoMemoryLimit() {
return internal::kDemuxerStreamVideoMemoryLimitLow;
}
const size_t kDemuxerMemoryLimit =
kDemuxerStreamAudioMemoryLimit + kDemuxerStreamVideoMemoryLimit;
size_t GetDemuxerMemoryLimit() {
return GetDemuxerStreamAudioMemoryLimit() +
GetDemuxerStreamVideoMemoryLimit();
}
} // namespace media
// Copyright 2018 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 "media/base/demuxer_memory_limit.h"
#include "base/sys_info.h"
namespace media {
size_t GetDemuxerStreamAudioMemoryLimit() {
static size_t limit = base::SysInfo::IsLowEndDevice()
? internal::kDemuxerStreamAudioMemoryLimitLow
: internal::kDemuxerStreamAudioMemoryLimitDefault;
return limit;
}
size_t GetDemuxerStreamVideoMemoryLimit() {
static size_t limit = base::SysInfo::IsLowEndDevice()
? internal::kDemuxerStreamVideoMemoryLimitLow
: internal::kDemuxerStreamVideoMemoryLimitDefault;
return limit;
}
size_t GetDemuxerMemoryLimit() {
return GetDemuxerStreamAudioMemoryLimit() +
GetDemuxerStreamVideoMemoryLimit();
}
} // namespace media
......@@ -1882,7 +1882,7 @@ bool FFmpegDemuxer::StreamsHaveAvailableCapacity() {
bool FFmpegDemuxer::IsMaxMemoryUsageReached() const {
DCHECK(task_runner_->BelongsToCurrentThread());
size_t memory_left = kDemuxerMemoryLimit;
size_t memory_left = GetDemuxerMemoryLimit();
for (const auto& stream : streams_) {
if (!stream)
continue;
......
......@@ -197,7 +197,7 @@ SourceBufferStream<RangeClass>::SourceBufferStream(
highest_output_buffer_timestamp_(kNoDecodeTimestamp()),
max_interbuffer_distance_(
base::TimeDelta::FromMilliseconds(kMinimumInterbufferDistanceInMs)),
memory_limit_(kDemuxerStreamAudioMemoryLimit) {
memory_limit_(GetDemuxerStreamAudioMemoryLimit()) {
DCHECK(audio_config.IsValidConfig());
audio_configs_.push_back(audio_config);
}
......@@ -213,7 +213,7 @@ SourceBufferStream<RangeClass>::SourceBufferStream(
highest_output_buffer_timestamp_(kNoDecodeTimestamp()),
max_interbuffer_distance_(
base::TimeDelta::FromMilliseconds(kMinimumInterbufferDistanceInMs)),
memory_limit_(kDemuxerStreamVideoMemoryLimit) {
memory_limit_(GetDemuxerStreamVideoMemoryLimit()) {
DCHECK(video_config.IsValidConfig());
video_configs_.push_back(video_config);
}
......@@ -230,7 +230,7 @@ SourceBufferStream<RangeClass>::SourceBufferStream(
highest_output_buffer_timestamp_(kNoDecodeTimestamp()),
max_interbuffer_distance_(
base::TimeDelta::FromMilliseconds(kMinimumInterbufferDistanceInMs)),
memory_limit_(kDemuxerStreamAudioMemoryLimit) {}
memory_limit_(GetDemuxerStreamAudioMemoryLimit()) {}
template <typename RangeClass>
SourceBufferStream<RangeClass>::~SourceBufferStream() = default;
......
......@@ -396,7 +396,7 @@ bool TrackRunIterator::Init(const MovieFragment& moof) {
// Avoid allocating insane sample counts for invalid media.
const size_t max_sample_count =
kDemuxerMemoryLimit / sizeof(decltype(tri.samples)::value_type);
GetDemuxerMemoryLimit() / sizeof(decltype(tri.samples)::value_type);
RCHECK_MEDIA_LOGGED(
base::strict_cast<size_t>(trun.sample_count) <= max_sample_count,
media_log_, "Metadata overhead exceeds storage limit.");
......
......@@ -54,9 +54,6 @@ declare_args() {
# Override to dynamically link the cras (ChromeOS audio) library.
use_cras = false
# Use low-memory buffers on cast builds.
use_low_memory_buffer = is_chromecast
# Enables AC3/EAC3 audio demuxing. This is enabled only on Chromecast, since
# it only provides demuxing, and is only useful for AC3/EAC3 audio
# pass-through to HDMI sink on Chromecast.
......
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