Merge "Fix issue 3483718: audio streaming and A2DP."

This commit is contained in:
Eric Laurent
2011-03-21 14:06:33 -07:00
committed by Android (Google) Code Review
2 changed files with 33 additions and 12 deletions

View File

@@ -546,12 +546,13 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou
}
if (loopStart >= loopEnd ||
loopEnd - loopStart > cblk->frameCount) {
loopEnd - loopStart > cblk->frameCount ||
cblk->server > loopStart) {
LOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user);
return BAD_VALUE;
}
if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
LOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d",
loopStart, loopEnd, cblk->frameCount);
return BAD_VALUE;
@@ -825,6 +826,12 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
uint32_t framesAvail = cblk->framesAvailable();
cblk->lock.lock();
if (cblk->flags & CBLK_INVALID_MSK) {
goto create_new_track;
}
cblk->lock.unlock();
if (framesAvail == 0) {
cblk->lock.lock();
goto start_loop_here;
@@ -1148,6 +1155,7 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart)
fromStart ? "start()" : "obtainBuffer()");
cblk->flags |= CBLK_RESTORING_ON;
// signal old cblk condition so that other threads waiting for available buffers stop
// waiting now
cblk->cv.broadcast();
@@ -1167,10 +1175,20 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& cblk, bool fromStart)
false);
if (result == NO_ERROR) {
// restore write index and set other indexes to reflect empty buffer status
mCblk->user = cblk->user;
mCblk->server = cblk->user;
mCblk->userBase = cblk->user;
mCblk->serverBase = cblk->user;
// restore loop: this is not guaranteed to succeed if new frame count is not
// compatible with loop length
setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
if (!fromStart) {
mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
}
result = mAudioTrack->start();
if (mActive) {
result = mAudioTrack->start();
}
if (fromStart && result == NO_ERROR) {
mNewPosition = mCblk->server + mUpdatePeriod;
}

View File

@@ -198,18 +198,21 @@ void NuPlayer::Renderer::signalAudioSinkChanged() {
}
void NuPlayer::Renderer::onDrainAudioQueue() {
uint32_t numFramesPlayed;
CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
ssize_t numFramesAvailableToWrite =
mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
for (;;) {
uint32_t numFramesPlayed;
CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
CHECK_GE(numFramesAvailableToWrite, 0);
ssize_t numFramesAvailableToWrite =
mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
size_t numBytesAvailableToWrite =
numFramesAvailableToWrite * mAudioSink->frameSize();
size_t numBytesAvailableToWrite =
numFramesAvailableToWrite * mAudioSink->frameSize();
if (numBytesAvailableToWrite == 0) {
break;
}
while (numBytesAvailableToWrite > 0) {
if (mAudioQueue.empty()) {
break;
}
@@ -264,10 +267,10 @@ void NuPlayer::Renderer::onDrainAudioQueue() {
if (entry->mOffset == entry->mBuffer->size()) {
entry->mNotifyConsumed->post();
mAudioQueue.erase(mAudioQueue.begin());
entry = NULL;
}
numBytesAvailableToWrite -= copy;
mNumFramesWritten += copy / mAudioSink->frameSize();
}