Loading services/audioflinger/Android.mk +3 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,9 @@ LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"' LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE # uncomment to allow tee sink debugging to be enabled by property # LOCAL_CFLAGS += -DTEE_SINK # uncomment to enable the audio watchdog # LOCAL_SRC_FILES += AudioWatchdog.cpp # LOCAL_CFLAGS += -DAUDIO_WATCHDOG Loading services/audioflinger/AudioFlinger.cpp +15 −2 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs; uint32_t AudioFlinger::mScreenState; #ifdef TEE_SINK bool AudioFlinger::mTeeSinkInputEnabled = false; bool AudioFlinger::mTeeSinkOutputEnabled = false; bool AudioFlinger::mTeeSinkTrackEnabled = false; Loading @@ -97,6 +98,7 @@ bool AudioFlinger::mTeeSinkTrackEnabled = false; size_t AudioFlinger::mTeeSinkInputFrames = kTeeSinkInputFramesDefault; size_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault; size_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault; #endif // ---------------------------------------------------------------------------- Loading Loading @@ -146,6 +148,7 @@ AudioFlinger::AudioFlinger() if (doLog) { mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters"); } #ifdef TEE_SINK (void) property_get("ro.debuggable", value, "0"); int debuggable = atoi(value); int teeEnabled = 0; Loading @@ -159,6 +162,7 @@ AudioFlinger::AudioFlinger() mTeeSinkOutputEnabled = true; if (teeEnabled & 4) mTeeSinkTrackEnabled = true; #endif } void AudioFlinger::onFirstRef() Loading Loading @@ -347,10 +351,12 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args) dev->dump(dev, fd); } #ifdef TEE_SINK // dump the serially shared record tee sink if (mRecordTeeSource != 0) { dumpTee(fd, mRecordTeeSource); } #endif if (locked) { mLock.unlock(); Loading Loading @@ -1624,6 +1630,7 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module, if (status == NO_ERROR && inStream != NULL) { #ifdef TEE_SINK // Try to re-use most recently used Pipe to archive a copy of input for dumpsys, // or (re-)create if current Pipe is idle and does not match the new format sp<NBAIO_Sink> teeSink; Loading Loading @@ -1670,6 +1677,7 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module, default: break; } #endif AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream); Loading @@ -1682,8 +1690,11 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module, reqChannels, id, primaryOutputDevice_l(), *pDevices, teeSink); *pDevices #ifdef TEE_SINK , teeSink #endif ); mRecordThreads.add(id, thread); ALOGV("openInput() created record thread: ID %d thread %p", id, thread); if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate; Loading Loading @@ -2235,6 +2246,7 @@ int comparEntry(const void *p1, const void *p2) return strcmp(((const Entry *) p1)->mName, ((const Entry *) p2)->mName); } #ifdef TEE_SINK void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id) { NBAIO_Source *teeSource = source.get(); Loading Loading @@ -2350,6 +2362,7 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand } } } #endif // ---------------------------------------------------------------------------- Loading services/audioflinger/AudioFlinger.h +6 −0 Original line number Diff line number Diff line Loading @@ -588,11 +588,15 @@ private: status_t closeOutput_nonvirtual(audio_io_handle_t output); status_t closeInput_nonvirtual(audio_io_handle_t input); #ifdef TEE_SINK // all record threads serially share a common tee sink, which is re-created on format change sp<NBAIO_Sink> mRecordTeeSink; sp<NBAIO_Source> mRecordTeeSource; #endif public: #ifdef TEE_SINK // tee sink, if enabled by property, allows dumpsys to write most recent audio to .wav file static void dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id = 0); Loading @@ -611,6 +615,8 @@ public: static const size_t kTeeSinkInputFramesDefault = 0x200000; static const size_t kTeeSinkOutputFramesDefault = 0x200000; static const size_t kTeeSinkTrackFramesDefault = 0x1000; #endif }; #undef INCLUDING_FROM_AUDIOFLINGER_H Loading services/audioflinger/Threads.cpp +19 −5 Original line number Diff line number Diff line Loading @@ -2124,6 +2124,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); mPipeSink = monoPipe; #ifdef TEE_SINK if (mTeeSinkOutputEnabled) { // create a Pipe to archive a copy of FastMixer's output for dumpsys Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, format); Loading @@ -2137,6 +2138,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud ALOG_ASSERT(index == 0); mTeeSource = teeSource; } #endif // create fast mixer and configure it initially with just one fast track for our submix mFastMixer = new FastMixer(); Loading @@ -2163,7 +2165,9 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud state->mColdFutexAddr = &mFastMixerFutex; state->mColdGen++; state->mDumpState = &mFastMixerDumpState; #ifdef TEE_SINK state->mTeeSink = mTeeSink.get(); #endif mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer"); state->mNBLogWriter = mFastMixerNBLogWriter.get(); sq->end(); Loading Loading @@ -3076,8 +3080,10 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar mutatorCopy.dump(fd); #endif #ifdef TEE_SINK // Write the tee output to a .wav file dumpTee(fd, mTeeSource, mId); #endif #ifdef AUDIO_WATCHDOG if (mAudioWatchdog != 0) { Loading Loading @@ -3574,16 +3580,21 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, audio_channel_mask_t channelMask, audio_io_handle_t id, audio_devices_t outDevice, audio_devices_t inDevice, const sp<NBAIO_Sink>& teeSink) : audio_devices_t inDevice #ifdef TEE_SINK , const sp<NBAIO_Sink>& teeSink #endif ) : ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD), mInput(input), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL), // mRsmpInIndex and mInputBytes set by readInputParameters() mReqChannelCount(popcount(channelMask)), mReqSampleRate(sampleRate), mReqSampleRate(sampleRate) // mBytesRead is only meaningful while active, and so is cleared in start() // (but might be better to also clear here for dump?) mTeeSink(teeSink) #ifdef TEE_SINK , mTeeSink(teeSink) #endif { snprintf(mName, kNameLength, "AudioIn_%X", id); Loading Loading @@ -3740,10 +3751,13 @@ bool AudioFlinger::RecordThread::threadLoop() mRsmpInIndex = mFrameCount; framesOut = 0; buffer.frameCount = 0; } else if (mTeeSink != 0) { } #ifdef TEE_SINK else if (mTeeSink != 0) { (void) mTeeSink->write(readInto, mBytesRead >> Format_frameBitShift(mTeeSink->format())); } #endif } } } else { Loading services/audioflinger/Threads.h +7 −2 Original line number Diff line number Diff line Loading @@ -542,9 +542,11 @@ private: sp<NBAIO_Sink> mPipeSink; // The current sink for the normal mixer to write it's (sub)mix, mOutputSink or mPipeSink sp<NBAIO_Sink> mNormalSink; #ifdef TEE_SINK // For dumpsys sp<NBAIO_Sink> mTeeSink; sp<NBAIO_Source> mTeeSource; #endif uint32_t mScreenState; // cached copy of gScreenState static const size_t kFastMixerLogSize = 8 * 1024; sp<NBLog::Writer> mFastMixerNBLogWriter; Loading Loading @@ -703,8 +705,11 @@ public: audio_channel_mask_t channelMask, audio_io_handle_t id, audio_devices_t outDevice, audio_devices_t inDevice, const sp<NBAIO_Sink>& teeSink); audio_devices_t inDevice #ifdef TEE_SINK , const sp<NBAIO_Sink>& teeSink #endif ); virtual ~RecordThread(); // no addTrack_l ? Loading Loading
services/audioflinger/Android.mk +3 −0 Original line number Diff line number Diff line Loading @@ -66,6 +66,9 @@ LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"' LOCAL_CFLAGS += -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE # uncomment to allow tee sink debugging to be enabled by property # LOCAL_CFLAGS += -DTEE_SINK # uncomment to enable the audio watchdog # LOCAL_SRC_FILES += AudioWatchdog.cpp # LOCAL_CFLAGS += -DAUDIO_WATCHDOG Loading
services/audioflinger/AudioFlinger.cpp +15 −2 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs; uint32_t AudioFlinger::mScreenState; #ifdef TEE_SINK bool AudioFlinger::mTeeSinkInputEnabled = false; bool AudioFlinger::mTeeSinkOutputEnabled = false; bool AudioFlinger::mTeeSinkTrackEnabled = false; Loading @@ -97,6 +98,7 @@ bool AudioFlinger::mTeeSinkTrackEnabled = false; size_t AudioFlinger::mTeeSinkInputFrames = kTeeSinkInputFramesDefault; size_t AudioFlinger::mTeeSinkOutputFrames = kTeeSinkOutputFramesDefault; size_t AudioFlinger::mTeeSinkTrackFrames = kTeeSinkTrackFramesDefault; #endif // ---------------------------------------------------------------------------- Loading Loading @@ -146,6 +148,7 @@ AudioFlinger::AudioFlinger() if (doLog) { mLogMemoryDealer = new MemoryDealer(kLogMemorySize, "LogWriters"); } #ifdef TEE_SINK (void) property_get("ro.debuggable", value, "0"); int debuggable = atoi(value); int teeEnabled = 0; Loading @@ -159,6 +162,7 @@ AudioFlinger::AudioFlinger() mTeeSinkOutputEnabled = true; if (teeEnabled & 4) mTeeSinkTrackEnabled = true; #endif } void AudioFlinger::onFirstRef() Loading Loading @@ -347,10 +351,12 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args) dev->dump(dev, fd); } #ifdef TEE_SINK // dump the serially shared record tee sink if (mRecordTeeSource != 0) { dumpTee(fd, mRecordTeeSource); } #endif if (locked) { mLock.unlock(); Loading Loading @@ -1624,6 +1630,7 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module, if (status == NO_ERROR && inStream != NULL) { #ifdef TEE_SINK // Try to re-use most recently used Pipe to archive a copy of input for dumpsys, // or (re-)create if current Pipe is idle and does not match the new format sp<NBAIO_Sink> teeSink; Loading Loading @@ -1670,6 +1677,7 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module, default: break; } #endif AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream); Loading @@ -1682,8 +1690,11 @@ audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module, reqChannels, id, primaryOutputDevice_l(), *pDevices, teeSink); *pDevices #ifdef TEE_SINK , teeSink #endif ); mRecordThreads.add(id, thread); ALOGV("openInput() created record thread: ID %d thread %p", id, thread); if (pSamplingRate != NULL) *pSamplingRate = reqSamplingRate; Loading Loading @@ -2235,6 +2246,7 @@ int comparEntry(const void *p1, const void *p2) return strcmp(((const Entry *) p1)->mName, ((const Entry *) p2)->mName); } #ifdef TEE_SINK void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id) { NBAIO_Source *teeSource = source.get(); Loading Loading @@ -2350,6 +2362,7 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand } } } #endif // ---------------------------------------------------------------------------- Loading
services/audioflinger/AudioFlinger.h +6 −0 Original line number Diff line number Diff line Loading @@ -588,11 +588,15 @@ private: status_t closeOutput_nonvirtual(audio_io_handle_t output); status_t closeInput_nonvirtual(audio_io_handle_t input); #ifdef TEE_SINK // all record threads serially share a common tee sink, which is re-created on format change sp<NBAIO_Sink> mRecordTeeSink; sp<NBAIO_Source> mRecordTeeSource; #endif public: #ifdef TEE_SINK // tee sink, if enabled by property, allows dumpsys to write most recent audio to .wav file static void dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_handle_t id = 0); Loading @@ -611,6 +615,8 @@ public: static const size_t kTeeSinkInputFramesDefault = 0x200000; static const size_t kTeeSinkOutputFramesDefault = 0x200000; static const size_t kTeeSinkTrackFramesDefault = 0x1000; #endif }; #undef INCLUDING_FROM_AUDIOFLINGER_H Loading
services/audioflinger/Threads.cpp +19 −5 Original line number Diff line number Diff line Loading @@ -2124,6 +2124,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2); mPipeSink = monoPipe; #ifdef TEE_SINK if (mTeeSinkOutputEnabled) { // create a Pipe to archive a copy of FastMixer's output for dumpsys Pipe *teeSink = new Pipe(mTeeSinkOutputFrames, format); Loading @@ -2137,6 +2138,7 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud ALOG_ASSERT(index == 0); mTeeSource = teeSource; } #endif // create fast mixer and configure it initially with just one fast track for our submix mFastMixer = new FastMixer(); Loading @@ -2163,7 +2165,9 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud state->mColdFutexAddr = &mFastMixerFutex; state->mColdGen++; state->mDumpState = &mFastMixerDumpState; #ifdef TEE_SINK state->mTeeSink = mTeeSink.get(); #endif mFastMixerNBLogWriter = audioFlinger->newWriter_l(kFastMixerLogSize, "FastMixer"); state->mNBLogWriter = mFastMixerNBLogWriter.get(); sq->end(); Loading Loading @@ -3076,8 +3080,10 @@ void AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& ar mutatorCopy.dump(fd); #endif #ifdef TEE_SINK // Write the tee output to a .wav file dumpTee(fd, mTeeSource, mId); #endif #ifdef AUDIO_WATCHDOG if (mAudioWatchdog != 0) { Loading Loading @@ -3574,16 +3580,21 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, audio_channel_mask_t channelMask, audio_io_handle_t id, audio_devices_t outDevice, audio_devices_t inDevice, const sp<NBAIO_Sink>& teeSink) : audio_devices_t inDevice #ifdef TEE_SINK , const sp<NBAIO_Sink>& teeSink #endif ) : ThreadBase(audioFlinger, id, outDevice, inDevice, RECORD), mInput(input), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL), // mRsmpInIndex and mInputBytes set by readInputParameters() mReqChannelCount(popcount(channelMask)), mReqSampleRate(sampleRate), mReqSampleRate(sampleRate) // mBytesRead is only meaningful while active, and so is cleared in start() // (but might be better to also clear here for dump?) mTeeSink(teeSink) #ifdef TEE_SINK , mTeeSink(teeSink) #endif { snprintf(mName, kNameLength, "AudioIn_%X", id); Loading Loading @@ -3740,10 +3751,13 @@ bool AudioFlinger::RecordThread::threadLoop() mRsmpInIndex = mFrameCount; framesOut = 0; buffer.frameCount = 0; } else if (mTeeSink != 0) { } #ifdef TEE_SINK else if (mTeeSink != 0) { (void) mTeeSink->write(readInto, mBytesRead >> Format_frameBitShift(mTeeSink->format())); } #endif } } } else { Loading
services/audioflinger/Threads.h +7 −2 Original line number Diff line number Diff line Loading @@ -542,9 +542,11 @@ private: sp<NBAIO_Sink> mPipeSink; // The current sink for the normal mixer to write it's (sub)mix, mOutputSink or mPipeSink sp<NBAIO_Sink> mNormalSink; #ifdef TEE_SINK // For dumpsys sp<NBAIO_Sink> mTeeSink; sp<NBAIO_Source> mTeeSource; #endif uint32_t mScreenState; // cached copy of gScreenState static const size_t kFastMixerLogSize = 8 * 1024; sp<NBLog::Writer> mFastMixerNBLogWriter; Loading Loading @@ -703,8 +705,11 @@ public: audio_channel_mask_t channelMask, audio_io_handle_t id, audio_devices_t outDevice, audio_devices_t inDevice, const sp<NBAIO_Sink>& teeSink); audio_devices_t inDevice #ifdef TEE_SINK , const sp<NBAIO_Sink>& teeSink #endif ); virtual ~RecordThread(); // no addTrack_l ? Loading