Bug 833724 - Use actual playback position to calculate free buffer space and change start-after-write logic in sydneyaudio Gonk backend. r=mchen

--HG--
extra : rebase_source : c9cb0ea2264713facc0d7c27e16342eb13d9751a
This commit is contained in:
Matthew Gregan 2013-02-20 15:55:26 +13:00
parent d9371cd901
commit 1751c7c811

View File

@ -33,8 +33,6 @@ struct sa_stream {
unsigned int channels;
unsigned int isPaused;
int64_t lastStartTime;
int64_t timePlaying;
int64_t amountWritten;
unsigned int bufferSize;
@ -88,8 +86,6 @@ sa_stream_create_pcm(
s->channels = channels;
s->isPaused = 0;
s->lastStartTime = 0;
s->timePlaying = 0;
s->amountWritten = 0;
s->bufferSize = 0;
@ -165,19 +161,15 @@ sa_stream_open(sa_stream_t *s) {
s->rate) != NO_ERROR) {
return SA_ERROR_INVALID;
}
int minsz = frameCount * s->channels * sizeof(int16_t);
s->bufferSize = s->rate * s->channels * sizeof(int16_t);
if (s->bufferSize < minsz) {
s->bufferSize = minsz;
}
s->bufferSize = frameCount * s->channels * sizeof(int16_t);
AudioTrack *track =
new AudioTrack(s->streamType,
s->rate,
AudioSystem::PCM_16_BIT,
chanConfig,
frameCount,
s->bufferSize / s->channels / sizeof(int16_t),
0,
NULL, NULL,
0,
@ -190,8 +182,7 @@ sa_stream_open(sa_stream_t *s) {
s->output_unit = track;
ALOG("%p - New stream %u %u bsz=%u min=%u", s, s->rate, s->channels,
s->bufferSize, minsz);
ALOG("%p - New stream rate=%u chan=%u bsz=%u", s, s->rate, s->channels, s->bufferSize);
return SA_SUCCESS;
}
@ -249,20 +240,12 @@ sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) {
break;
}
/* AudioTrack::write is blocking when the AudioTrack is playing. When
it's not playing, it's a non-blocking call that will return a short
write when the buffer is full. Use a short write to indicate a good
time to start the AudioTrack playing. */
if (r != towrite) {
ALOG("%p - Buffer full, starting playback", s);
sa_stream_resume(s);
}
p += r;
wrote += r;
} while (wrote < nbytes);
s->amountWritten += r;
s->amountWritten += nbytes;
sa_stream_resume(s);
} while (wrote < nbytes);
return r < 0 ? SA_ERROR_INVALID : SA_SUCCESS;
}
@ -281,17 +264,21 @@ sa_stream_get_write_size(sa_stream_t *s, size_t *size) {
return SA_ERROR_NO_INIT;
}
/* No android API for this, so estimate based on how much we have played and
* how much we have written. */
*size = s->bufferSize - ((s->timePlaying * s->channels * s->rate * sizeof(int16_t) /
MILLISECONDS_PER_SECOND) - s->amountWritten);
/* No way to query the available buffer space directly, so calculate it from
the amount we've written and the current playback position. */
uint32_t framePosition = 0;
s->output_unit->getPosition(&framePosition);
int64_t bytePos = framePosition * s->channels * sizeof(int16_t);
*size = s->bufferSize - (s->amountWritten - bytePos);
/* Available buffer space can't exceed bufferSize. */
if (*size > s->bufferSize) {
*size = s->bufferSize;
}
ALOG("%p - Write Size tp=%lld aw=%u sz=%zu", s, s->timePlaying, s->amountWritten, *size);
ALOG("%p - Write Size aw=%lld bufsz=%u pos=%lld sz=%u",
s, s->amountWritten, s->bufferSize, bytePos, *size);
return SA_SUCCESS;
}
@ -324,15 +311,7 @@ sa_stream_pause(sa_stream_t *s) {
s->isPaused = 1;
/* Update stats */
if (s->lastStartTime != 0) {
/* if lastStartTime is not zero, so playback has started */
struct timespec current_time;
clock_gettime(CLOCK_REALTIME, &current_time);
int64_t ticker = current_time.tv_sec * 1000 + current_time.tv_nsec / 1000000;
s->timePlaying += ticker - s->lastStartTime;
}
ALOG("%p - Pause total time playing: %lld total written: %lld", s, s->timePlaying, s->amountWritten);
ALOG("%p - pause", s);
s->output_unit->pause();
return SA_SUCCESS;
@ -350,12 +329,6 @@ sa_stream_resume(sa_stream_t *s) {
s->isPaused = 0;
/* Update stats */
struct timespec current_time;
clock_gettime(CLOCK_REALTIME, &current_time);
int64_t ticker = current_time.tv_sec * 1000 + current_time.tv_nsec / 1000000;
s->lastStartTime = ticker;
s->output_unit->start();
return SA_SUCCESS;
}