diff options
author | Glenn Kasten <gkasten@google.com> | 2012-12-21 15:04:30 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-12-21 15:04:30 -0800 |
commit | 856ff4e4c3c43550f013e80277358fdf514342bf (patch) | |
tree | 8c4d4a5e03726de6b40ab9ed3519e738cae2fefc /media/libmedia | |
parent | 5570227ac334479982a9dd8c1647c00f58f47c18 (diff) | |
parent | 552f274d82fb4988fb972df69134e031d375abfe (diff) | |
download | frameworks_av-856ff4e4c3c43550f013e80277358fdf514342bf.zip frameworks_av-856ff4e4c3c43550f013e80277358fdf514342bf.tar.gz frameworks_av-856ff4e4c3c43550f013e80277358fdf514342bf.tar.bz2 |
Merge "Start isolating control block accesses in a proxy"
Diffstat (limited to 'media/libmedia')
-rw-r--r-- | media/libmedia/AudioRecord.cpp | 47 | ||||
-rw-r--r-- | media/libmedia/AudioTrack.cpp | 109 | ||||
-rw-r--r-- | media/libmedia/AudioTrackShared.cpp | 2 |
3 files changed, 103 insertions, 55 deletions
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index ee4cceb..f6e60fc 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -75,7 +75,8 @@ status_t AudioRecord::getMinFrameCount( AudioRecord::AudioRecord() : mStatus(NO_INIT), mSessionId(0), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) + mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT), + mProxy(NULL) { } @@ -90,7 +91,9 @@ AudioRecord::AudioRecord( int notificationFrames, int sessionId) : mStatus(NO_INIT), mSessionId(0), - mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT) + mPreviousPriority(ANDROID_PRIORITY_NORMAL), + mPreviousSchedulingGroup(SP_DEFAULT), + mProxy(NULL) { mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user, notificationFrames, sessionId); @@ -112,6 +115,7 @@ AudioRecord::~AudioRecord() IPCThreadState::self()->flushCommands(); AudioSystem::releaseAudioSessionId(mSessionId); } + delete mProxy; } status_t AudioRecord::set( @@ -149,6 +153,8 @@ status_t AudioRecord::set( if (sampleRate == 0) { sampleRate = DEFAULT_SAMPLE_RATE; } + mSampleRate = sampleRate; + // these below should probably come from the audioFlinger too... if (format == AUDIO_FORMAT_DEFAULT) { format = AUDIO_FORMAT_PCM_16_BIT; @@ -166,6 +172,12 @@ status_t AudioRecord::set( uint32_t channelCount = popcount(channelMask); mChannelCount = channelCount; + if (audio_is_linear_pcm(mFormat)) { + mFrameSize = channelCount * audio_bytes_per_sample(format); + } else { + mFrameSize = sizeof(uint8_t); + } + if (sessionId == 0 ) { mSessionId = AudioSystem::newAudioSessionId(); } else { @@ -218,12 +230,6 @@ status_t AudioRecord::set( // Update buffer size in case it has been limited by AudioFlinger during track creation mFrameCount = mCblk->frameCount_; - if (audio_is_linear_pcm(mFormat)) { - mFrameSize = channelCount * audio_bytes_per_sample(format); - } else { - mFrameSize = sizeof(uint8_t); - } - mActive = false; mCbf = cbf; mNotificationFrames = notificationFrames; @@ -360,7 +366,7 @@ bool AudioRecord::stopped() const uint32_t AudioRecord::getSampleRate() const { - return mCblk->sampleRate; + return mSampleRate; } status_t AudioRecord::setMarkerPosition(uint32_t marker) @@ -473,11 +479,18 @@ status_t AudioRecord::openRecord_l( mBuffers = (char*)cblk + sizeof(audio_track_cblk_t); cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; cblk->waitTimeMs = 0; + + // update proxy + delete mProxy; + mProxy = new AudioRecordClientProxy(cblk, mBuffers, frameCount, mFrameSize); + return NO_ERROR; } status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) { + ALOG_ASSERT(mStatus == NO_ERROR && mProxy != NULL); + AutoMutex lock(mLock); bool active; status_t result = NO_ERROR; @@ -488,7 +501,7 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) audioBuffer->frameCount = 0; audioBuffer->size = 0; - uint32_t framesReady = cblk->framesReadyIn(); + size_t framesReady = mProxy->framesReady(); if (framesReady == 0) { cblk->lock.lock(); @@ -551,7 +564,7 @@ create_new_record: } // read the server count again start_loop_here: - framesReady = cblk->framesReadyIn(); + framesReady = mProxy->framesReady(); } cblk->lock.unlock(); } @@ -573,15 +586,17 @@ create_new_record: audioBuffer->frameCount = framesReq; audioBuffer->size = framesReq * mFrameSize; - audioBuffer->raw = cblk->buffer(mBuffers, mFrameSize, u); + audioBuffer->raw = mProxy->buffer(u); active = mActive; return active ? status_t(NO_ERROR) : status_t(STOPPED); } void AudioRecord::releaseBuffer(Buffer* audioBuffer) { + ALOG_ASSERT(mStatus == NO_ERROR && mProxy != NULL); + AutoMutex lock(mLock); - mCblk->stepUserIn(audioBuffer->frameCount, mFrameCount); + (void) mProxy->stepUser(audioBuffer->frameCount); } audio_io_handle_t AudioRecord::getInput() const @@ -594,7 +609,7 @@ audio_io_handle_t AudioRecord::getInput() const audio_io_handle_t AudioRecord::getInput_l() { mInput = AudioSystem::getInput(mInputSource, - mCblk->sampleRate, + mSampleRate, mFormat, mChannelMask, mSessionId); @@ -746,7 +761,7 @@ bool AudioRecord::processAudioBuffer(const sp<AudioRecordThread>& thread) // Manage overrun callback - if (active && (cblk->framesAvailableIn(mFrameCount) == 0)) { + if (active && (mProxy->framesAvailable() == 0)) { // The value of active is stale, but we are almost sure to be active here because // otherwise we would have exited when obtainBuffer returned STOPPED earlier. ALOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); @@ -782,7 +797,7 @@ status_t AudioRecord::restoreRecord_l(audio_track_cblk_t*& refCblk) // if the new IAudioRecord is created, openRecord_l() will modify the // following member variables: mAudioRecord, mCblkMemory and mCblk. // It will also delete the strong references on previous IAudioRecord and IMemory - result = openRecord_l(cblk->sampleRate, mFormat, mFrameCount, getInput_l()); + result = openRecord_l(mSampleRate, mFormat, mFrameCount, getInput_l()); if (result == NO_ERROR) { newCblk = mCblk; // callback thread or sync event hasn't changed diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index d0872f0..1bd839f 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -97,7 +97,8 @@ AudioTrack::AudioTrack() : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), - mPreviousSchedulingGroup(SP_DEFAULT) + mPreviousSchedulingGroup(SP_DEFAULT), + mProxy(NULL) { } @@ -115,7 +116,8 @@ AudioTrack::AudioTrack( : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), - mPreviousSchedulingGroup(SP_DEFAULT) + mPreviousSchedulingGroup(SP_DEFAULT), + mProxy(NULL) { mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, @@ -136,7 +138,8 @@ AudioTrack::AudioTrack( : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), - mPreviousSchedulingGroup(SP_DEFAULT) + mPreviousSchedulingGroup(SP_DEFAULT), + mProxy(NULL) { if (sharedBuffer == 0) { ALOGE("sharedBuffer must be non-0"); @@ -166,6 +169,7 @@ AudioTrack::~AudioTrack() IPCThreadState::self()->flushCommands(); AudioSystem::releaseAudioSessionId(mSessionId); } + delete mProxy; } status_t AudioTrack::set( @@ -212,6 +216,7 @@ status_t AudioTrack::set( } sampleRate = afSampleRate; } + mSampleRate = sampleRate; // these below should probably come from the audioFlinger too... if (format == AUDIO_FORMAT_DEFAULT) { @@ -252,6 +257,14 @@ status_t AudioTrack::set( uint32_t channelCount = popcount(channelMask); mChannelCount = channelCount; + if (audio_is_linear_pcm(format)) { + mFrameSize = channelCount * audio_bytes_per_sample(format); + mFrameSizeAF = channelCount * sizeof(int16_t); + } else { + mFrameSize = sizeof(uint8_t); + mFrameSizeAF = sizeof(uint8_t); + } + audio_io_handle_t output = AudioSystem::getOutput( streamType, sampleRate, format, channelMask, @@ -300,14 +313,6 @@ status_t AudioTrack::set( mStreamType = streamType; mFormat = format; - if (audio_is_linear_pcm(format)) { - mFrameSize = channelCount * audio_bytes_per_sample(format); - mFrameSizeAF = channelCount * sizeof(int16_t); - } else { - mFrameSize = sizeof(uint8_t); - mFrameSizeAF = sizeof(uint8_t); - } - mSharedBuffer = sharedBuffer; mActive = false; mUserData = user; @@ -460,6 +465,11 @@ void AudioTrack::pause() status_t AudioTrack::setVolume(float left, float right) { + if (mStatus != NO_ERROR) { + return mStatus; + } + ALOG_ASSERT(mProxy != NULL); + if (left < 0.0f || left > 1.0f || right < 0.0f || right > 1.0f) { return BAD_VALUE; } @@ -468,7 +478,7 @@ status_t AudioTrack::setVolume(float left, float right) mVolume[LEFT] = left; mVolume[RIGHT] = right; - mCblk->setVolumeLR((uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000)); + mProxy->setVolumeLR((uint32_t(uint16_t(right * 0x1000)) << 16) | uint16_t(left * 0x1000)); return NO_ERROR; } @@ -481,14 +491,19 @@ status_t AudioTrack::setVolume(float volume) status_t AudioTrack::setAuxEffectSendLevel(float level) { ALOGV("setAuxEffectSendLevel(%f)", level); + + if (mStatus != NO_ERROR) { + return mStatus; + } + ALOG_ASSERT(mProxy != NULL); + if (level < 0.0f || level > 1.0f) { return BAD_VALUE; } AutoMutex lock(mLock); mSendLevel = level; - - mCblk->setSendLevel(level); + mProxy->setSendLevel(level); return NO_ERROR; } @@ -517,7 +532,9 @@ status_t AudioTrack::setSampleRate(uint32_t rate) } AutoMutex lock(mLock); - mCblk->sampleRate = rate; + mSampleRate = rate; + mProxy->setSampleRate(rate); + return NO_ERROR; } @@ -528,7 +545,7 @@ uint32_t AudioTrack::getSampleRate() const } AutoMutex lock(mLock); - return mCblk->sampleRate; + return mSampleRate; } status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount) @@ -665,6 +682,11 @@ status_t AudioTrack::getPosition(uint32_t *position) status_t AudioTrack::reload() { + if (mStatus != NO_ERROR) { + return mStatus; + } + ALOG_ASSERT(mProxy != NULL); + if (mSharedBuffer == 0 || mIsTimed) { return INVALID_OPERATION; } @@ -677,8 +699,7 @@ status_t AudioTrack::reload() flush_l(); - audio_track_cblk_t* cblk = mCblk; - cblk->stepUserOut(mFrameCount, mFrameCount); + (void) mProxy->stepUser(mFrameCount); return NO_ERROR; } @@ -693,7 +714,7 @@ audio_io_handle_t AudioTrack::getOutput() audio_io_handle_t AudioTrack::getOutput_l() { return AudioSystem::getOutput(mStreamType, - mCblk->sampleRate, mFormat, mChannelMask, mFlags); + mSampleRate, mFormat, mChannelMask, mFlags); } status_t AudioTrack::attachAuxEffect(int effectId) @@ -889,13 +910,8 @@ status_t AudioTrack::createTrack_l( mBuffers = (char*)cblk + sizeof(audio_track_cblk_t); } else { mBuffers = sharedBuffer->pointer(); - // Force buffer full condition as data is already present in shared memory - cblk->stepUserOut(frameCount, frameCount); } - cblk->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | - uint16_t(mVolume[LEFT] * 0x1000)); - cblk->setSendLevel(mSendLevel); mAudioTrack->attachAuxEffect(mAuxEffectId); cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS; cblk->waitTimeMs = 0; @@ -908,11 +924,26 @@ status_t AudioTrack::createTrack_l( if (frameCount > mReqFrameCount) { mReqFrameCount = frameCount; } + + // update proxy + delete mProxy; + mProxy = new AudioTrackClientProxy(cblk, mBuffers, frameCount, mFrameSizeAF); + mProxy->setVolumeLR((uint32_t(uint16_t(mVolume[RIGHT] * 0x1000)) << 16) | + uint16_t(mVolume[LEFT] * 0x1000)); + mProxy->setSendLevel(mSendLevel); + mProxy->setSampleRate(mSampleRate); + if (sharedBuffer != 0) { + // Force buffer full condition as data is already present in shared memory + mProxy->stepUser(frameCount); + } + return NO_ERROR; } status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) { + ALOG_ASSERT(mStatus == NO_ERROR && mProxy != NULL); + AutoMutex lock(mLock); bool active; status_t result = NO_ERROR; @@ -923,7 +954,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) audioBuffer->frameCount = 0; audioBuffer->size = 0; - uint32_t framesAvail = cblk->framesAvailableOut(mFrameCount); + size_t framesAvail = mProxy->framesAvailable(); cblk->lock.lock(); if (cblk->flags & CBLK_INVALID) { @@ -999,7 +1030,7 @@ create_new_track: } // read the server count again start_loop_here: - framesAvail = cblk->framesAvailableOut_l(mFrameCount); + framesAvail = mProxy->framesAvailable_l(); } cblk->lock.unlock(); } @@ -1019,16 +1050,18 @@ create_new_track: audioBuffer->frameCount = framesReq; audioBuffer->size = framesReq * mFrameSizeAF; - audioBuffer->raw = cblk->buffer(mBuffers, mFrameSizeAF, u); + audioBuffer->raw = mProxy->buffer(u); active = mActive; return active ? status_t(NO_ERROR) : status_t(STOPPED); } void AudioTrack::releaseBuffer(Buffer* audioBuffer) { + ALOG_ASSERT(mStatus == NO_ERROR && mProxy != NULL); + AutoMutex lock(mLock); audio_track_cblk_t* cblk = mCblk; - cblk->stepUserOut(audioBuffer->frameCount, mFrameCount); + (void) mProxy->stepUser(audioBuffer->frameCount); if (audioBuffer->frameCount > 0) { // restart track if it was disabled by audioflinger due to previous underrun if (mActive && (cblk->flags & CBLK_DISABLED)) { @@ -1198,7 +1231,7 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread) // so all cblk references might still refer to old shared memory, but that should be benign // Manage underrun callback - if (active && (cblk->framesAvailableOut(mFrameCount) == mFrameCount)) { + if (active && (mProxy->framesAvailable() == mFrameCount)) { ALOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags); if (!(android_atomic_or(CBLK_UNDERRUN, &cblk->flags) & CBLK_UNDERRUN)) { mCbf(EVENT_UNDERRUN, mUserData, 0); @@ -1345,7 +1378,7 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart // following member variables: mAudioTrack, mCblkMemory and mCblk. // It will also delete the strong references on previous IAudioTrack and IMemory result = createTrack_l(mStreamType, - cblk->sampleRate, + mSampleRate, mFormat, mReqFrameCount, // so that frame count never goes down mFlags, @@ -1364,12 +1397,12 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart // 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); + size_t frames = 0; if (!fromStart) { newCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; // Make sure that a client relying on callback events indicating underrun or // the actual amount of audio frames played (e.g SoundPool) receives them. if (mSharedBuffer == 0) { - uint32_t frames = 0; if (user > server) { frames = ((user - server) > mFrameCount) ? mFrameCount : (user - server); @@ -1377,13 +1410,15 @@ status_t AudioTrack::restoreTrack_l(audio_track_cblk_t*& refCblk, bool fromStart } // restart playback even if buffer is not completely filled. android_atomic_or(CBLK_FORCEREADY, &newCblk->flags); - // stepUser() clears CBLK_UNDERRUN flag enabling underrun callbacks to - // the client - newCblk->stepUserOut(frames, mFrameCount); } } if (mSharedBuffer != 0) { - newCblk->stepUserOut(mFrameCount, mFrameCount); + frames = mFrameCount; + } + if (frames > 0) { + // stepUser() clears CBLK_UNDERRUN flag enabling underrun callbacks to + // the client + mProxy->stepUser(frames); } if (mActive) { result = mAudioTrack->start(); @@ -1415,7 +1450,6 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const char buffer[SIZE]; String8 result; - audio_track_cblk_t* cblk = mCblk; result.append(" AudioTrack::dump\n"); snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType, mVolume[0], mVolume[1]); @@ -1423,8 +1457,7 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mFrameCount); result.append(buffer); - snprintf(buffer, 255, " sample rate(%u), status(%d)\n", - (cblk == 0) ? 0 : cblk->sampleRate, mStatus); + snprintf(buffer, 255, " sample rate(%u), status(%d)\n", mSampleRate, mStatus); result.append(buffer); snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency); result.append(buffer); diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp index bee13c8..13d47c9 100644 --- a/media/libmedia/AudioTrackShared.cpp +++ b/media/libmedia/AudioTrackShared.cpp @@ -26,7 +26,7 @@ audio_track_cblk_t::audio_track_cblk_t() : lock(Mutex::SHARED), cv(Condition::SHARED), user(0), server(0), userBase(0), serverBase(0), frameCount_(0), loopStart(UINT_MAX), loopEnd(UINT_MAX), loopCount(0), mVolumeLR(0x10001000), - mSendLevel(0), flags(0) + mSampleRate(0), mSendLevel(0), flags(0) { } |