diff options
author | Eric Laurent <elaurent@google.com> | 2012-11-19 14:55:58 -0800 |
---|---|---|
committer | Eric Laurent <elaurent@google.com> | 2012-11-19 19:35:38 -0800 |
commit | 81784c37c61b09289654b979567a42bf73cd2b12 (patch) | |
tree | a0a3fa9225bea006c2e037a337b43bf4ba7c0743 /services/audioflinger/PlaybackTracks.h | |
parent | 4d9cef6c007afd195a8f36d35d46b359bf909331 (diff) | |
download | frameworks_av-81784c37c61b09289654b979567a42bf73cd2b12.zip frameworks_av-81784c37c61b09289654b979567a42bf73cd2b12.tar.gz frameworks_av-81784c37c61b09289654b979567a42bf73cd2b12.tar.bz2 |
AudioFlinger files reorganization
Audioflinger.cpp and Audioflinger.h files must be split to
improve readability and maintainability.
This CL splits the files as follows:
AudioFlinger.cpp split into:
- AudioFlinger.cpp: implementation of IAudioflinger interface and global methods
- AFThreads.cpp: implementation of ThreadBase, PlaybackThread, MixerThread,
DuplicatingThread, DirectOutputThread and RecordThread.
- AFTracks.cpp: implementation of TrackBase, Track, TimedTrack, OutputTrack,
RecordTrack, TrackHandle and RecordHandle.
- AFEffects.cpp: implementation of EffectModule, EffectChain and EffectHandle.
AudioFlinger.h is modified by inline inclusion of header files containing
the declaration of complex inner classes:
- AFThreads.h: ThreadBase, PlaybackThread, MixerThread, DuplicatingThread,
DirectOutputThread and RecordThread
- AFEffects.h: EffectModule, EffectChain and EffectHandle
AFThreads.h includes the follownig headers inline:
- AFTrackBase.h: TrackBase
- AFPlaybackTracks: Track, TimedTrack, OutputTrack
- AFRecordTracks: RecordTrack
Change-Id: I512ebc3a51813ab7a4afccc9a538b18125165c4c
Diffstat (limited to 'services/audioflinger/PlaybackTracks.h')
-rw-r--r-- | services/audioflinger/PlaybackTracks.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h new file mode 100644 index 0000000..b898924 --- /dev/null +++ b/services/audioflinger/PlaybackTracks.h @@ -0,0 +1,285 @@ +/* +** +** Copyright 2012, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#ifndef INCLUDING_FROM_AUDIOFLINGER_H + #error This header file should only be included from AudioFlinger.h +#endif + +// playback track +class Track : public TrackBase, public VolumeProvider { +public: + Track( PlaybackThread *thread, + const sp<Client>& client, + audio_stream_type_t streamType, + uint32_t sampleRate, + audio_format_t format, + audio_channel_mask_t channelMask, + size_t frameCount, + const sp<IMemory>& sharedBuffer, + int sessionId, + IAudioFlinger::track_flags_t flags); + virtual ~Track(); + + static void appendDumpHeader(String8& result); + void dump(char* buffer, size_t size); + virtual status_t start(AudioSystem::sync_event_t event = + AudioSystem::SYNC_EVENT_NONE, + int triggerSession = 0); + virtual void stop(); + void pause(); + + void flush(); + void destroy(); + void mute(bool); + int name() const { return mName; } + + audio_stream_type_t streamType() const { + return mStreamType; + } + status_t attachAuxEffect(int EffectId); + void setAuxBuffer(int EffectId, int32_t *buffer); + int32_t *auxBuffer() const { return mAuxBuffer; } + void setMainBuffer(int16_t *buffer) { mMainBuffer = buffer; } + int16_t *mainBuffer() const { return mMainBuffer; } + int auxEffectId() const { return mAuxEffectId; } + +// implement FastMixerState::VolumeProvider interface + virtual uint32_t getVolumeLR(); + + virtual status_t setSyncEvent(const sp<SyncEvent>& event); + +protected: + // for numerous + friend class PlaybackThread; + friend class MixerThread; + friend class DirectOutputThread; + + Track(const Track&); + Track& operator = (const Track&); + + // AudioBufferProvider interface + virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, + int64_t pts = kInvalidPTS); + // releaseBuffer() not overridden + + virtual size_t framesReady() const; + + bool isMuted() const { return mMute; } + bool isPausing() const { + return mState == PAUSING; + } + bool isPaused() const { + return mState == PAUSED; + } + bool isResuming() const { + return mState == RESUMING; + } + bool isReady() const; + void setPaused() { mState = PAUSED; } + void reset(); + + bool isOutputTrack() const { + return (mStreamType == AUDIO_STREAM_CNT); + } + + sp<IMemory> sharedBuffer() const { return mSharedBuffer; } + + // framesWritten is cumulative, never reset, and is shared all tracks + // audioHalFrames is derived from output latency + // FIXME parameters not needed, could get them from the thread + bool presentationComplete(size_t framesWritten, size_t audioHalFrames); + +public: + void triggerEvents(AudioSystem::sync_event_t type); + virtual bool isTimedTrack() const { return false; } + bool isFastTrack() const { return (mFlags & IAudioFlinger::TRACK_FAST) != 0; } + virtual bool isOut() const; + +protected: + + // written by Track::mute() called by binder thread(s), without a mutex or barrier. + // read by Track::isMuted() called by playback thread, also without a mutex or barrier. + // The lack of mutex or barrier is safe because the mute status is only used by itself. + bool mMute; + + // FILLED state is used for suppressing volume ramp at begin of playing + enum {FS_INVALID, FS_FILLING, FS_FILLED, FS_ACTIVE}; + mutable uint8_t mFillingUpStatus; + int8_t mRetryCount; + const sp<IMemory> mSharedBuffer; + bool mResetDone; + const audio_stream_type_t mStreamType; + int mName; // track name on the normal mixer, + // allocated statically at track creation time, + // and is even allocated (though unused) for fast tracks + // FIXME don't allocate track name for fast tracks + int16_t *mMainBuffer; + int32_t *mAuxBuffer; + int mAuxEffectId; + bool mHasVolumeController; + size_t mPresentationCompleteFrames; // number of frames written to the + // audio HAL when this track will be fully rendered + // zero means not monitoring +private: + IAudioFlinger::track_flags_t mFlags; + + // The following fields are only for fast tracks, and should be in a subclass + int mFastIndex; // index within FastMixerState::mFastTracks[]; + // either mFastIndex == -1 if not isFastTrack() + // or 0 < mFastIndex < FastMixerState::kMaxFast because + // index 0 is reserved for normal mixer's submix; + // index is allocated statically at track creation time + // but the slot is only used if track is active + FastTrackUnderruns mObservedUnderruns; // Most recently observed value of + // mFastMixerDumpState.mTracks[mFastIndex].mUnderruns + uint32_t mUnderrunCount; // Counter of total number of underruns, never reset + volatile float mCachedVolume; // combined master volume and stream type volume; + // 'volatile' means accessed without lock or + // barrier, but is read/written atomically +}; // end of Track + +class TimedTrack : public Track { + public: + static sp<TimedTrack> create(PlaybackThread *thread, + const sp<Client>& client, + audio_stream_type_t streamType, + uint32_t sampleRate, + audio_format_t format, + audio_channel_mask_t channelMask, + size_t frameCount, + const sp<IMemory>& sharedBuffer, + int sessionId); + virtual ~TimedTrack(); + + class TimedBuffer { + public: + TimedBuffer(); + TimedBuffer(const sp<IMemory>& buffer, int64_t pts); + const sp<IMemory>& buffer() const { return mBuffer; } + int64_t pts() const { return mPTS; } + uint32_t position() const { return mPosition; } + void setPosition(uint32_t pos) { mPosition = pos; } + private: + sp<IMemory> mBuffer; + int64_t mPTS; + uint32_t mPosition; + }; + + // Mixer facing methods. + virtual bool isTimedTrack() const { return true; } + virtual size_t framesReady() const; + + // AudioBufferProvider interface + virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer, + int64_t pts); + virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer); + + // Client/App facing methods. + status_t allocateTimedBuffer(size_t size, + sp<IMemory>* buffer); + status_t queueTimedBuffer(const sp<IMemory>& buffer, + int64_t pts); + status_t setMediaTimeTransform(const LinearTransform& xform, + TimedAudioTrack::TargetTimeline target); + + private: + TimedTrack(PlaybackThread *thread, + const sp<Client>& client, + audio_stream_type_t streamType, + uint32_t sampleRate, + audio_format_t format, + audio_channel_mask_t channelMask, + size_t frameCount, + const sp<IMemory>& sharedBuffer, + int sessionId); + + void timedYieldSamples_l(AudioBufferProvider::Buffer* buffer); + void timedYieldSilence_l(uint32_t numFrames, + AudioBufferProvider::Buffer* buffer); + void trimTimedBufferQueue_l(); + void trimTimedBufferQueueHead_l(const char* logTag); + void updateFramesPendingAfterTrim_l(const TimedBuffer& buf, + const char* logTag); + + uint64_t mLocalTimeFreq; + LinearTransform mLocalTimeToSampleTransform; + LinearTransform mMediaTimeToSampleTransform; + sp<MemoryDealer> mTimedMemoryDealer; + + Vector<TimedBuffer> mTimedBufferQueue; + bool mQueueHeadInFlight; + bool mTrimQueueHeadOnRelease; + uint32_t mFramesPendingInQueue; + + uint8_t* mTimedSilenceBuffer; + uint32_t mTimedSilenceBufferSize; + mutable Mutex mTimedBufferQueueLock; + bool mTimedAudioOutputOnTime; + CCHelper mCCHelper; + + Mutex mMediaTimeTransformLock; + LinearTransform mMediaTimeTransform; + bool mMediaTimeTransformValid; + TimedAudioTrack::TargetTimeline mMediaTimeTransformTarget; +}; + + +// playback track, used by DuplicatingThread +class OutputTrack : public Track { +public: + + class Buffer : public AudioBufferProvider::Buffer { + public: + int16_t *mBuffer; + }; + + OutputTrack(PlaybackThread *thread, + DuplicatingThread *sourceThread, + uint32_t sampleRate, + audio_format_t format, + audio_channel_mask_t channelMask, + size_t frameCount); + virtual ~OutputTrack(); + + virtual status_t start(AudioSystem::sync_event_t event = + AudioSystem::SYNC_EVENT_NONE, + int triggerSession = 0); + virtual void stop(); + bool write(int16_t* data, uint32_t frames); + bool bufferQueueEmpty() const { return mBufferQueue.size() == 0; } + bool isActive() const { return mActive; } + const wp<ThreadBase>& thread() const { return mThread; } + +private: + + enum { + NO_MORE_BUFFERS = 0x80000001, // same in AudioTrack.h, ok to be different value + }; + + status_t obtainBuffer(AudioBufferProvider::Buffer* buffer, + uint32_t waitTimeMs); + void clearBufferQueue(); + + // Maximum number of pending buffers allocated by OutputTrack::write() + static const uint8_t kMaxOverFlowBuffers = 10; + + Vector < Buffer* > mBufferQueue; + AudioBufferProvider::Buffer mOutBuffer; + bool mActive; + DuplicatingThread* const mSourceThread; // for waitTimeMs() in write() + void* mBuffers; // starting address of buffers in plain memory +}; // end of OutputTrack |