Merge change I49f02be9 into eclair
* changes:
Issue 2265163: Audio still reported routed through earpiece on sholes
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 008468c..622c596 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -268,7 +268,7 @@
* Returned value:
* handle on audio hardware input
*/
- audio_io_handle_t getInput() { return mInput; }
+ audio_io_handle_t getInput();
/* obtains a buffer of "frameCount" frames. The buffer must be
* filled entirely. If the track is stopped, obtainBuffer() returns
@@ -318,7 +318,8 @@
int format,
int channelCount,
int frameCount,
- uint32_t flags);
+ uint32_t flags,
+ audio_io_handle_t input);
sp<IAudioRecord> mAudioRecord;
sp<IMemory> mCblkMemory;
@@ -345,8 +346,8 @@
bool mMarkerReached;
uint32_t mNewPosition;
uint32_t mUpdatePeriod;
- audio_io_handle_t mInput;
uint32_t mFlags;
+ uint32_t mChannels;
};
}; // namespace android
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index d918998..daec6e8 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -674,32 +674,13 @@
}
// audioConfigChanged_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::audioConfigChanged_l(int event, const sp<ThreadBase>& thread, void *param2) {
- int ioHandle = 0;
-
- for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
- if (mPlaybackThreads.valueAt(i) == thread) {
- ioHandle = mPlaybackThreads.keyAt(i);
- break;
- }
- }
- if (ioHandle == 0) {
- for (size_t i = 0; i < mRecordThreads.size(); i++) {
- if (mRecordThreads.valueAt(i) == thread) {
- ioHandle = mRecordThreads.keyAt(i);
- break;
- }
- }
- }
-
- if (ioHandle != 0) {
- size_t size = mNotificationClients.size();
- for (size_t i = 0; i < size; i++) {
- sp<IBinder> binder = mNotificationClients.itemAt(i);
- LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get());
- sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
- client->ioConfigChanged(event, ioHandle, param2);
- }
+void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) {
+ size_t size = mNotificationClients.size();
+ for (size_t i = 0; i < size; i++) {
+ sp<IBinder> binder = mNotificationClients.itemAt(i);
+ LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get());
+ sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
+ client->ioConfigChanged(event, ioHandle, param2);
}
}
@@ -712,10 +693,10 @@
// ----------------------------------------------------------------------------
-AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger)
+AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
: Thread(false),
mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
- mFormat(0), mFrameSize(1), mStandby(false)
+ mFormat(0), mFrameSize(1), mStandby(false), mId(id), mExiting(false)
{
}
@@ -734,6 +715,7 @@
LOGV("ThreadBase::exit");
{
AutoMutex lock(&mLock);
+ mExiting = true;
requestExit();
mWaitWorkCV.signal();
}
@@ -870,8 +852,8 @@
// ----------------------------------------------------------------------------
-AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output)
- : ThreadBase(audioFlinger),
+AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
+ : ThreadBase(audioFlinger, id),
mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
{
@@ -1106,15 +1088,6 @@
{
status_t status = ALREADY_EXISTS;
- // here the track could be either new, or restarted
- // in both cases "unstop" the track
- if (track->isPaused()) {
- track->mState = TrackBase::RESUMING;
- LOGV("PAUSED => RESUMING (%d) on thread %p", track->name(), this);
- } else {
- track->mState = TrackBase::ACTIVE;
- LOGV("? => ACTIVE (%d) on thread %p", track->name(), this);
- }
// set retry count for buffer fill
track->mRetryCount = kMaxTrackStartupRetries;
if (mActiveTracks.indexOf(track) < 0) {
@@ -1173,7 +1146,7 @@
break;
}
Mutex::Autolock _l(mAudioFlinger->mLock);
- mAudioFlinger->audioConfigChanged_l(event, this, param2);
+ mAudioFlinger->audioConfigChanged_l(event, mId, param2);
}
void AudioFlinger::PlaybackThread::readOutputParameters()
@@ -1194,8 +1167,8 @@
// ----------------------------------------------------------------------------
-AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output)
- : PlaybackThread(audioFlinger, output),
+AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
+ : PlaybackThread(audioFlinger, output, id),
mAudioMixer(0)
{
mType = PlaybackThread::MIXER;
@@ -1303,7 +1276,6 @@
}
} else if (mBytesWritten != 0 ||
(mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
- LOGV("NO DATA READY, %p", this);
memset (curBuf, 0, mixBufferSize);
sleepTime = 0;
LOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
@@ -1639,8 +1611,8 @@
}
// ----------------------------------------------------------------------------
-AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output)
- : PlaybackThread(audioFlinger, output),
+AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
+ : PlaybackThread(audioFlinger, output, id),
mLeftVolume (1.0), mRightVolume(1.0)
{
mType = PlaybackThread::DIRECT;
@@ -1941,8 +1913,8 @@
// ----------------------------------------------------------------------------
-AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread)
- : MixerThread(audioFlinger, mainThread->getOutput())
+AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id)
+ : MixerThread(audioFlinger, mainThread->getOutput(), id)
{
mType = PlaybackThread::DUPLICATING;
addOutputTrack(mainThread);
@@ -2305,8 +2277,10 @@
LOGV("PlaybackThread::Track destructor");
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
- Mutex::Autolock _l(thread->mLock);
+ thread->mLock.lock();
mState = TERMINATED;
+ thread->mLock.unlock();
+ AudioSystem::releaseOutput(thread->id());
}
}
@@ -2324,6 +2298,9 @@
{ // scope for mLock
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
+ if (!isOutputTrack() && (mState == ACTIVE || mState == RESUMING)) {
+ AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ }
Mutex::Autolock _l(thread->mLock);
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
playbackThread->destroyTrack_l(this);
@@ -2405,14 +2382,37 @@
status_t AudioFlinger::PlaybackThread::Track::start()
{
+ status_t status = NO_ERROR;
LOGV("start(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
- PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
- playbackThread->addTrack_l(this);
+ int state = mState;
+ // here the track could be either new, or restarted
+ // in both cases "unstop" the track
+ if (mState == PAUSED) {
+ mState = TrackBase::RESUMING;
+ LOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
+ } else {
+ mState = TrackBase::ACTIVE;
+ LOGV("? => ACTIVE (%d) on thread %p", mName, this);
+ }
+
+ if (!isOutputTrack() && state != ACTIVE && state != RESUMING) {
+ thread->mLock.unlock();
+ status = AudioSystem::startOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ thread->mLock.lock();
+ }
+ if (status == NO_ERROR) {
+ PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ playbackThread->addTrack_l(this);
+ } else {
+ mState = state;
+ }
+ } else {
+ status = BAD_VALUE;
}
- return NO_ERROR;
+ return status;
}
void AudioFlinger::PlaybackThread::Track::stop()
@@ -2421,6 +2421,7 @@
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
Mutex::Autolock _l(thread->mLock);
+ int state = mState;
if (mState > STOPPED) {
mState = STOPPED;
// If the track is not active (PAUSED and buffers full), flush buffers
@@ -2430,6 +2431,11 @@
}
LOGV("(> STOPPED) => STOPPED (%d) on thread %p", mName, playbackThread);
}
+ if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) {
+ thread->mLock.unlock();
+ AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ thread->mLock.lock();
+ }
}
}
@@ -2442,6 +2448,11 @@
if (mState == ACTIVE || mState == RESUMING) {
mState = PAUSING;
LOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
+ if (!isOutputTrack()) {
+ thread->mLock.unlock();
+ AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
+ thread->mLock.lock();
+ }
}
}
}
@@ -2525,6 +2536,10 @@
AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
{
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ AudioSystem::releaseInput(thread->id());
+ }
}
status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
@@ -2572,8 +2587,9 @@
if (thread != 0) {
RecordThread *recordThread = (RecordThread *)thread.get();
return recordThread->start(this);
+ } else {
+ return BAD_VALUE;
}
- return NO_INIT;
}
void AudioFlinger::RecordThread::RecordTrack::stop()
@@ -3010,8 +3026,8 @@
// ----------------------------------------------------------------------------
-AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels) :
- ThreadBase(audioFlinger),
+AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, int id) :
+ ThreadBase(audioFlinger, id),
mInput(input), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
{
mReqChannelCount = AudioSystem::popCount(channels);
@@ -3039,6 +3055,7 @@
run(buffer, PRIORITY_URGENT_AUDIO);
}
+
bool AudioFlinger::RecordThread::threadLoop()
{
AudioBufferProvider::Buffer buffer;
@@ -3084,6 +3101,10 @@
}
if (mActiveTrack != 0) {
+ if (mActiveTrack->mState != TrackBase::ACTIVE) {
+ usleep(5000);
+ continue;
+ }
buffer.frameCount = mFrameCount;
if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
size_t framesOut = buffer.frameCount;
@@ -3181,6 +3202,8 @@
}
mActiveTrack.clear();
+ mStartStopCond.broadcast();
+
LOGV("RecordThread %p exiting", this);
return false;
}
@@ -3188,37 +3211,71 @@
status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack)
{
LOGV("RecordThread::start");
- AutoMutex lock(&mLock);
+ sp <ThreadBase> strongMe = this;
+ status_t status = NO_ERROR;
+ {
+ AutoMutex lock(&mLock);
+ if (mActiveTrack != 0) {
+ if (recordTrack != mActiveTrack.get()) {
+ status = -EBUSY;
+ } else if (mActiveTrack->mState == TrackBase::PAUSING) {
+ mActiveTrack->mState = TrackBase::RESUMING;
+ }
+ return status;
+ }
- if (mActiveTrack != 0) {
- if (recordTrack != mActiveTrack.get()) return -EBUSY;
-
- if (mActiveTrack->mState == TrackBase::PAUSING) mActiveTrack->mState = TrackBase::RESUMING;
-
- return NO_ERROR;
- }
-
- mActiveTrack = recordTrack;
- mActiveTrack->mState = TrackBase::RESUMING;
- // signal thread to start
- LOGV("Signal record thread");
- mWaitWorkCV.signal();
- mStartStopCond.wait(mLock);
- if (mActiveTrack != 0) {
+ recordTrack->mState = TrackBase::IDLE;
+ mActiveTrack = recordTrack;
+ mLock.unlock();
+ status_t status = AudioSystem::startInput(mId);
+ mLock.lock();
+ if (status != NO_ERROR) {
+ mActiveTrack.clear();
+ return status;
+ }
+ mActiveTrack->mState = TrackBase::RESUMING;
+ // signal thread to start
+ LOGV("Signal record thread");
+ mWaitWorkCV.signal();
+ // do not wait for mStartStopCond if exiting
+ if (mExiting) {
+ mActiveTrack.clear();
+ status = INVALID_OPERATION;
+ goto startError;
+ }
+ mStartStopCond.wait(mLock);
+ if (mActiveTrack == 0) {
+ LOGV("Record failed to start");
+ status = BAD_VALUE;
+ goto startError;
+ }
LOGV("Record started OK");
- return NO_ERROR;
- } else {
- LOGV("Record failed to start");
- return BAD_VALUE;
+ return status;
}
+startError:
+ AudioSystem::stopInput(mId);
+ return status;
}
void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
LOGV("RecordThread::stop");
- AutoMutex lock(&mLock);
- if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) {
- mActiveTrack->mState = TrackBase::PAUSING;
- mStartStopCond.wait(mLock);
+ sp <ThreadBase> strongMe = this;
+ {
+ AutoMutex lock(&mLock);
+ if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) {
+ mActiveTrack->mState = TrackBase::PAUSING;
+ // do not wait for mStartStopCond if exiting
+ if (mExiting) {
+ return;
+ }
+ mStartStopCond.wait(mLock);
+ // if we have been restarted, recordTrack == mActiveTrack.get() here
+ if (mActiveTrack == 0 || recordTrack != mActiveTrack.get()) {
+ mLock.unlock();
+ AudioSystem::stopInput(mId);
+ mLock.lock();
+ }
+ }
}
}
@@ -3388,7 +3445,7 @@
break;
}
Mutex::Autolock _l(mAudioFlinger->mLock);
- mAudioFlinger->audioConfigChanged_l(event, this, param2);
+ mAudioFlinger->audioConfigChanged_l(event, mId, param2);
}
void AudioFlinger::RecordThread::readInputParameters()
@@ -3476,13 +3533,13 @@
if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
(format != AudioSystem::PCM_16_BIT) ||
(channels != AudioSystem::CHANNEL_OUT_STEREO)) {
- thread = new DirectOutputThread(this, output);
- LOGV("openOutput() created direct output: ID %d thread %p", (mNextThreadId + 1), thread);
+ thread = new DirectOutputThread(this, output, ++mNextThreadId);
+ LOGV("openOutput() created direct output: ID %d thread %p", mNextThreadId, thread);
} else {
- thread = new MixerThread(this, output);
- LOGV("openOutput() created mixer output: ID %d thread %p", (mNextThreadId + 1), thread);
+ thread = new MixerThread(this, output, ++mNextThreadId);
+ LOGV("openOutput() created mixer output: ID %d thread %p", mNextThreadId, thread);
}
- mPlaybackThreads.add(++mNextThreadId, thread);
+ mPlaybackThreads.add(mNextThreadId, thread);
if (pSamplingRate) *pSamplingRate = samplingRate;
if (pFormat) *pFormat = format;
@@ -3505,9 +3562,9 @@
}
- DuplicatingThread *thread = new DuplicatingThread(this, thread1);
+ DuplicatingThread *thread = new DuplicatingThread(this, thread1, ++mNextThreadId);
thread->addOutputTrack(thread2);
- mPlaybackThreads.add(++mNextThreadId, thread);
+ mPlaybackThreads.add(mNextThreadId, thread);
return mNextThreadId;
}
@@ -3534,7 +3591,7 @@
}
}
void *param2 = 0;
- audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, thread, param2);
+ audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2);
mPlaybackThreads.removeItem(output);
}
thread->exit();
@@ -3628,8 +3685,8 @@
if (input != 0) {
// Start record thread
- thread = new RecordThread(this, input, reqSamplingRate, reqChannels);
- mRecordThreads.add(++mNextThreadId, thread);
+ thread = new RecordThread(this, input, reqSamplingRate, reqChannels, ++mNextThreadId);
+ mRecordThreads.add(mNextThreadId, thread);
LOGV("openInput() created record thread: ID %d thread %p", mNextThreadId, thread);
if (pSamplingRate) *pSamplingRate = reqSamplingRate;
if (pFormat) *pFormat = format;
@@ -3655,7 +3712,7 @@
LOGV("closeInput() %d", input);
void *param2 = 0;
- audioConfigChanged_l(AudioSystem::INPUT_CLOSED, thread, param2);
+ audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2);
mRecordThreads.removeItem(input);
}
thread->exit();
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 594d878..5a17294 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -213,7 +213,7 @@
class ThreadBase : public Thread {
public:
- ThreadBase (const sp<AudioFlinger>& audioFlinger);
+ ThreadBase (const sp<AudioFlinger>& audioFlinger, int id);
virtual ~ThreadBase();
status_t dumpBase(int fd, const Vector<String16>& args);
@@ -323,6 +323,7 @@
void sendConfigEvent(int event, int param = 0);
void sendConfigEvent_l(int event, int param = 0);
void processConfigEvents();
+ int id() const { return mId;}
mutable Mutex mLock;
@@ -349,6 +350,8 @@
status_t mParamStatus;
Vector<ConfigEvent *> mConfigEvents;
bool mStandby;
+ int mId;
+ bool mExiting;
};
// --- PlaybackThread ---
@@ -421,6 +424,10 @@
void setPaused() { mState = PAUSED; }
void reset();
+ bool isOutputTrack() const {
+ return (mStreamType == AudioSystem::NUM_STREAM_TYPES);
+ }
+
// we don't really need a lock for these
float mVolume[2];
volatile bool mMute;
@@ -473,7 +480,7 @@
}; // end of OutputTrack
- PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output);
+ PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
virtual ~PlaybackThread();
virtual status_t dump(int fd, const Vector<String16>& args);
@@ -573,7 +580,7 @@
class MixerThread : public PlaybackThread {
public:
- MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output);
+ MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
virtual ~MixerThread();
// Thread virtuals
@@ -600,7 +607,7 @@
class DirectOutputThread : public PlaybackThread {
public:
- DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output);
+ DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
~DirectOutputThread();
// Thread virtuals
@@ -621,7 +628,7 @@
class DuplicatingThread : public MixerThread {
public:
- DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread);
+ DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, int id);
~DuplicatingThread();
// Thread virtuals
@@ -637,7 +644,7 @@
MixerThread *checkMixerThread_l(int output) const;
RecordThread *checkRecordThread_l(int input) const;
float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; }
- void audioConfigChanged_l(int event, const sp<ThreadBase>& thread, void *param2);
+ void audioConfigChanged_l(int event, int ioHandle, void *param2);
friend class AudioBuffer;
@@ -705,7 +712,8 @@
RecordThread(const sp<AudioFlinger>& audioFlinger,
AudioStreamIn *input,
uint32_t sampleRate,
- uint32_t channels);
+ uint32_t channels,
+ int id);
~RecordThread();
virtual bool threadLoop();
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index e63c0d2..c3828f0 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -46,7 +46,7 @@
// ---------------------------------------------------------------------------
AudioRecord::AudioRecord()
- : mStatus(NO_INIT), mInput(0)
+ : mStatus(NO_INIT)
{
}
@@ -60,7 +60,7 @@
callback_t cbf,
void* user,
int notificationFrames)
- : mStatus(NO_INIT), mInput(0)
+ : mStatus(NO_INIT)
{
mStatus = set(inputSource, sampleRate, format, channels,
frameCount, flags, cbf, user, notificationFrames);
@@ -79,7 +79,6 @@
}
mAudioRecord.clear();
IPCThreadState::self()->flushCommands();
- AudioSystem::releaseInput(mInput);
}
}
@@ -123,9 +122,9 @@
}
int channelCount = AudioSystem::popCount(channels);
- mInput = AudioSystem::getInput(inputSource,
+ audio_io_handle_t input = AudioSystem::getInput(inputSource,
sampleRate, format, channels, (AudioSystem::audio_in_acoustics)flags);
- if (mInput == 0) {
+ if (input == 0) {
LOGE("Could not get audio output for stream type %d", inputSource);
return BAD_VALUE;
}
@@ -168,7 +167,7 @@
// create the IAudioRecord
status_t status = openRecord(sampleRate, format, channelCount,
- frameCount, flags);
+ frameCount, flags, input);
if (status != NO_ERROR) {
return status;
@@ -187,6 +186,7 @@
// Update buffer size in case it has been limited by AudioFlinger during track creation
mFrameCount = mCblk->frameCount;
mChannelCount = (uint8_t)channelCount;
+ mChannels = channels;
mActive = 0;
mCbf = cbf;
mNotificationFrames = notificationFrames;
@@ -265,29 +265,28 @@
}
if (android_atomic_or(1, &mActive) == 0) {
- ret = AudioSystem::startInput(mInput);
- if (ret == NO_ERROR) {
- ret = mAudioRecord->start();
- if (ret == DEAD_OBJECT) {
- LOGV("start() dead IAudioRecord: creating a new one");
- ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
- mFrameCount, mFlags);
- }
+ ret = mAudioRecord->start();
+ if (ret == DEAD_OBJECT) {
+ LOGV("start() dead IAudioRecord: creating a new one");
+ ret = openRecord(mCblk->sampleRate, mFormat, mChannelCount,
+ mFrameCount, mFlags, getInput());
if (ret == NO_ERROR) {
- mNewPosition = mCblk->user + mUpdatePeriod;
- mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
- mCblk->waitTimeMs = 0;
- if (t != 0) {
- t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
- } else {
- setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
- }
- } else {
- LOGV("start() failed");
- AudioSystem::stopInput(mInput);
- android_atomic_and(~1, &mActive);
+ ret = mAudioRecord->start();
}
}
+ if (ret == NO_ERROR) {
+ mNewPosition = mCblk->user + mUpdatePeriod;
+ mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ mCblk->waitTimeMs = 0;
+ if (t != 0) {
+ t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT);
+ } else {
+ setpriority(PRIO_PROCESS, 0, THREAD_PRIORITY_AUDIO_CLIENT);
+ }
+ } else {
+ LOGV("start() failed");
+ android_atomic_and(~1, &mActive);
+ }
}
if (t != 0) {
@@ -318,7 +317,6 @@
} else {
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
}
- AudioSystem::stopInput(mInput);
}
if (t != 0) {
@@ -395,7 +393,8 @@
int format,
int channelCount,
int frameCount,
- uint32_t flags)
+ uint32_t flags,
+ audio_io_handle_t input)
{
status_t status;
const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
@@ -403,7 +402,7 @@
return NO_INIT;
}
- sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), mInput,
+ sp<IAudioRecord> record = audioFlinger->openRecord(getpid(), input,
sampleRate, format,
channelCount,
frameCount,
@@ -425,7 +424,8 @@
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
mCblk->out = 0;
-
+ mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ mCblk->waitTimeMs = 0;
return NO_ERROR;
}
@@ -466,10 +466,10 @@
if (result == DEAD_OBJECT) {
LOGW("obtainBuffer() dead IAudioRecord: creating a new one");
result = openRecord(cblk->sampleRate, mFormat, mChannelCount,
- mFrameCount, mFlags);
+ mFrameCount, mFlags, getInput());
if (result == NO_ERROR) {
cblk = mCblk;
- cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ mAudioRecord->start();
}
}
cblk->lock.lock();
@@ -516,6 +516,14 @@
cblk->stepUser(audioBuffer->frameCount);
}
+audio_io_handle_t AudioRecord::getInput()
+{
+ return AudioSystem::getInput(mInputSource,
+ mCblk->sampleRate,
+ mFormat, mChannels,
+ (AudioSystem::audio_in_acoustics)mFlags);
+}
+
// -------------------------------------------------------------------------
ssize_t AudioRecord::read(void* buffer, size_t userSize)
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index cedd79d..ad0f42e 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -97,7 +97,6 @@
}
mAudioTrack.clear();
IPCThreadState::self()->flushCommands();
- AudioSystem::releaseOutput(getOutput());
}
}
@@ -318,8 +317,6 @@
}
if (android_atomic_or(1, &mActive) == 0) {
- audio_io_handle_t output = getOutput();
- AudioSystem::startOutput(output, (AudioSystem::stream_type)mStreamType);
mNewPosition = mCblk->server + mUpdatePeriod;
mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
mCblk->waitTimeMs = 0;
@@ -333,10 +330,13 @@
if (status == DEAD_OBJECT) {
LOGV("start() dead IAudioTrack: creating a new one");
status = createTrack(mStreamType, mCblk->sampleRate, mFormat, mChannelCount,
- mFrameCount, mFlags, mSharedBuffer, output);
- mNewPosition = mCblk->server + mUpdatePeriod;
- mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
- mCblk->waitTimeMs = 0;
+ mFrameCount, mFlags, mSharedBuffer, getOutput());
+ if (status == NO_ERROR) {
+ status = mAudioTrack->start();
+ if (status == NO_ERROR) {
+ mNewPosition = mCblk->server + mUpdatePeriod;
+ }
+ }
}
if (status != NO_ERROR) {
LOGV("start() failed");
@@ -346,7 +346,6 @@
} else {
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
}
- AudioSystem::stopOutput(output, (AudioSystem::stream_type)mStreamType);
}
}
@@ -383,7 +382,6 @@
} else {
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL);
}
- AudioSystem::stopOutput(getOutput(), (AudioSystem::stream_type)mStreamType);
}
if (t != 0) {
@@ -418,9 +416,7 @@
{
LOGV("pause");
if (android_atomic_and(~1, &mActive) == 1) {
- mActive = 0;
mAudioTrack->pause();
- AudioSystem::stopOutput(getOutput(), (AudioSystem::stream_type)mStreamType);
}
}
@@ -658,7 +654,8 @@
}
mCblk->volumeLR = (int32_t(int16_t(mVolume[LEFT] * 0x1000)) << 16) | int16_t(mVolume[RIGHT] * 0x1000);
-
+ mCblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
+ mCblk->waitTimeMs = 0;
return NO_ERROR;
}
@@ -709,6 +706,7 @@
if (result == NO_ERROR) {
cblk = mCblk;
cblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
+ mAudioTrack->start();
}
}
cblk->lock.lock();