TimedAudioTrack: Fix continuity threshold handling.

DO NOT MERGE
this change must be hand-merged into master due to directory
restructuring.

Fix issues with continuity threshold handling; notably
+ If the steady-state continuity threshold is exceeded, be sure to
  clear the on-time flag.  Failure to do this will result in the
  system picking a new mix point which simply satisfies the
  steady-state continuity threshold instead of the startup threshold.
  Since we are putting a discontinuity in presentation anyway, we
  really want to pick a perfect point, not just an OK point.
+ Tighten the steady-state continuity threshold.  It was currently set
  to 100mSec which is enormous.  4mSec (the new setting) is much more
  appropriate.  On systems with a VCXO (like tungsten) this should
  never be wrong by more than a sample.  If TimedAudioTracks are ever
  to be used on VCXO-less systems, this threshold should probably be a
  a parameter configurable by applications on a track by track basis
  so they can make the tradeoff between allowed error and frequency of
  disruptive corrections.
+ Reset the on-time flag if the mixer provides no PTS during a mix
  operation.  This makes for a convenient way for the HAL to reset
  timed tracks when it makes changes for delay compensation across
  multiple outputs.

Change-Id: I2cb23de5a3d1f75618abc1c8ab903db883837aa8
Signed-off-by: John Grossman <johngro@google.com>
This commit is contained in:
John Grossman
2012-04-19 12:08:17 -07:00
parent aa0c94fc87
commit f609b661a6

View File

@@ -4053,6 +4053,7 @@ status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
if (pts == AudioBufferProvider::kInvalidPTS) { if (pts == AudioBufferProvider::kInvalidPTS) {
buffer->raw = 0; buffer->raw = 0;
buffer->frameCount = 0; buffer->frameCount = 0;
mTimedAudioOutputOnTime = false;
return INVALID_OPERATION; return INVALID_OPERATION;
} }
@@ -4151,21 +4152,28 @@ status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
// the current output position is within this threshold, then we will // the current output position is within this threshold, then we will
// concatenate the next input samples to the previous output // concatenate the next input samples to the previous output
const int64_t kSampleContinuityThreshold = const int64_t kSampleContinuityThreshold =
(static_cast<int64_t>(sampleRate()) << 32) / 10; (static_cast<int64_t>(sampleRate()) << 32) / 250;
// if this is the first buffer of audio that we're emitting from this track // if this is the first buffer of audio that we're emitting from this track
// then it should be almost exactly on time. // then it should be almost exactly on time.
const int64_t kSampleStartupThreshold = 1LL << 32; const int64_t kSampleStartupThreshold = 1LL << 32;
if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) || if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) ||
(!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) { (!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) {
// the next input is close enough to being on time, so concatenate it // the next input is close enough to being on time, so concatenate it
// with the last output // with the last output
timedYieldSamples_l(buffer); timedYieldSamples_l(buffer);
LOGVV("*** on time: head.pos=%d frameCount=%u", head.position(), buffer->frameCount); LOGVV("*** on time: head.pos=%d frameCount=%u",
head.position(), buffer->frameCount);
return NO_ERROR; return NO_ERROR;
} else if (sampleDelta > 0) { }
// Looks like our output is not on time. Reset our on timed status.
// Next time we mix samples from our input queue, then should be within
// the StartupThreshold.
mTimedAudioOutputOnTime = false;
if (sampleDelta > 0) {
// the gap between the current output position and the proper start of // the gap between the current output position and the proper start of
// the next input sample is too big, so fill it with silence // the next input sample is too big, so fill it with silence
uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32; uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32;