Improve recommended sample counts for PPAPI.

Testing shows we can allow for much lower buffer sizes on WASAPI,
OSX, and PulseAudio clients.  In most cases, this change brings those
clients down to the nearest multiple of 512.  WaveOut and ALSA clients
will use the nearest multiple of 2048.

Based on testing done in https://codereview.chromium.org/14570002/

BUG=162207
TEST=Using these buffer sizes for HTML5 audio works without glitching
when an AudioConverter is in the graph.

Review URL: https://chromiumcodereview.appspot.com/14573006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202775 0039d316-1c4b-4281-b951-d872f2087c98
parent 2a5a40ed
......@@ -8,6 +8,14 @@
namespace ppapi {
// Rounds up requested_size to the nearest multiple of minimum_size.
static uint32_t CalculateMultipleOfSampleFrameCount(uint32_t minimum_size,
uint32_t requested_size) {
const uint32_t multiple = (requested_size + minimum_size - 1) / minimum_size;
return std::min(minimum_size * multiple,
static_cast<uint32_t>(PP_AUDIOMAXSAMPLEFRAMECOUNT));
}
PPB_AudioConfig_Shared::PPB_AudioConfig_Shared(ResourceObjectType type,
PP_Instance instance)
: Resource(type, instance),
......@@ -62,31 +70,57 @@ uint32_t PPB_AudioConfig_Shared::RecommendSampleFrameCount_1_1(
if (sample_frame_count < PP_AUDIOMINSAMPLEFRAMECOUNT)
sample_frame_count = PP_AUDIOMINSAMPLEFRAMECOUNT;
// If hardware information isn't available we're connected to a fake audio
// output stream on the browser side, so we can use whatever sample count the
// client wants.
if (!hardware_sample_frame_count || !hardware_sample_rate)
return sample_frame_count;
// Note: All the values below were determined through experimentation to
// minimize jitter and back-to-back callbacks from the browser. Please take
// care when modifying these values as they impact a large number of users.
// TODO(dalecurtis): Land jitter test and add documentation for updating this.
// If client is using same sample rate as audio hardware, then recommend a
// multiple of the audio hardware's sample frame count.
if (hardware_sample_rate == sample_rate && hardware_sample_frame_count > 0) {
// Round up input sample_frame_count to nearest multiple.
uint32_t multiple = (sample_frame_count + hardware_sample_frame_count - 1) /
hardware_sample_frame_count;
uint32_t recommendation = hardware_sample_frame_count * multiple;
if (recommendation > PP_AUDIOMAXSAMPLEFRAMECOUNT)
recommendation = PP_AUDIOMAXSAMPLEFRAMECOUNT;
return recommendation;
if (hardware_sample_rate == sample_rate) {
return CalculateMultipleOfSampleFrameCount(
hardware_sample_frame_count, sample_frame_count);
}
// Otherwise, recommend a conservative 50ms buffer based on sample rate.
const uint32_t kDefault50msAt44100kHz = 2205;
const uint32_t kDefault50msAt48000kHz = 2400;
switch (sample_rate) {
case PP_AUDIOSAMPLERATE_44100:
return kDefault50msAt44100kHz;
case PP_AUDIOSAMPLERATE_48000:
return kDefault50msAt48000kHz;
case PP_AUDIOSAMPLERATE_NONE:
return 0;
// Should track the value reported by XP and ALSA backends.
const uint32_t kHighLatencySampleFrameCount = 2048;
// If the hardware requires a high latency buffer or we're at a low sample
// rate w/ a buffer that's larger than 10ms, choose the nearest multiple of
// the high latency sample frame count. An example of too low and too large
// is 16kHz and a sample frame count greater than 160 frames.
if (hardware_sample_frame_count >= kHighLatencySampleFrameCount ||
(hardware_sample_rate < 44100 &&
hardware_sample_frame_count > hardware_sample_rate / 100u)) {
return CalculateMultipleOfSampleFrameCount(
sample_frame_count,
std::max(kHighLatencySampleFrameCount, hardware_sample_frame_count));
}
// Unable to make a recommendation.
return 0;
// All low latency clients should be able to handle a 512 frame buffer with
// resampling from 44.1kHz and 48kHz to higher sample rates.
// TODO(dalecurtis): We may need to investigate making the callback thread
// high priority to handle buffers at the absolute minimum w/o glitching.
const uint32_t kLowLatencySampleFrameCount = 512;
// Special case for 48kHz -> 44.1kHz and buffer sizes greater than 10ms. In
// testing most buffer sizes > 10ms led to glitching, so we choose a size we
// know won't cause jitter.
int min_sample_frame_count = kLowLatencySampleFrameCount;
if (hardware_sample_rate == 44100 && sample_rate == 48000 &&
hardware_sample_frame_count > hardware_sample_rate / 100u) {
min_sample_frame_count = std::max(
2 * kLowLatencySampleFrameCount, hardware_sample_frame_count);
}
return CalculateMultipleOfSampleFrameCount(
min_sample_frame_count, sample_frame_count);
}
// static
......@@ -116,6 +150,8 @@ bool PPB_AudioConfig_Shared::Init(PP_AudioSampleRate sample_rate,
uint32_t sample_frame_count) {
// TODO(brettw): Currently we don't actually check what the hardware
// supports, so just allow sample rates of the "guaranteed working" ones.
// TODO(dalecurtis): If sample rates are added RecommendSampleFrameCount_1_1()
// must be updated to account for the new rates.
if (sample_rate != PP_AUDIOSAMPLERATE_44100 &&
sample_rate != PP_AUDIOSAMPLERATE_48000)
return false;
......
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