/* ** ** 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 ANDROID_AUDIO_STREAM_OUT_H #define ANDROID_AUDIO_STREAM_OUT_H #include #include #include #include #include #include "AudioOutput.h" namespace android { class AudioHardwareOutput; class AudioStreamOut { public: AudioStreamOut(AudioHardwareOutput& owner, bool mcOut, bool isIec958NonAudio); ~AudioStreamOut(); uint32_t latency() const; status_t getRenderPosition(uint32_t *dspFrames); status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp); status_t getNextWriteTimestamp(int64_t *timestamp); status_t standby(); status_t pause(); status_t resume(); status_t flush(); status_t dump(int fd); uint32_t sampleRate() const { return mInputSampleRate; } uint32_t outputSampleRate() const; size_t bufferSize() const { return mInputBufSize; } uint32_t chanMask() const { return mInputChanMask; } audio_format_t format() const { return mInputFormat; } uint32_t framesPerChunk() const { return mInputChunkFrames; } uint32_t nomChunksInFlight() const { return mInputNominalChunksInFlight; } status_t set(audio_format_t *pFormat, uint32_t *pChannels, uint32_t *pRate); void setTgtDevices(uint32_t tgtDevices); status_t setParameters(struct audio_stream *stream, const char *kvpairs); char* getParameters(const char* keys); const char* getName() const { return mIsMCOutput ? "Multi-channel" : "Main"; } ssize_t write(const void* buffer, size_t bytes); bool isIec958NonAudio() const { return mIsIec958NonAudio; } protected: // Lock in this order to avoid deadlock. // mRoutingLock // mPresentationLock // Track frame position for timestamps, etc. uint64_t mRenderPosition; // in frames, increased by write uint64_t mFramesPresented; // increased by write // Cache of the last PresentationPosition. // This cache is used in case of retrograde timestamps or if the mRoutingLock is held. Mutex mPresentationLock; // protects these mLastPresentation* variables uint64_t mLastPresentationPosition; // frames struct timespec mLastPresentationTime; bool mLastPresentationValid; // Our HAL, used as the middle-man to collect and trade AudioOutputs. AudioHardwareOutput& mOwnerHAL; // Details about the format of the audio we have been configured to receive // from audio flinger. uint32_t mInputSampleRate; uint32_t mInputChanMask; audio_format_t mInputFormat; uint32_t mInputNominalChunksInFlight; // Handy values pre-computed from the audio configuration. uint32_t mInputBufSize; uint32_t mInputChanCount; uint32_t mInputFrameSize; uint32_t mInputChunkFrames; uint32_t mInputNominalLatencyUSec; LinearTransform mLocalTimeToFrames; // Bookkeeping used to throttle audio flinger when this audio stream has no // actual physical outputs. LocalClock mLocalClock; bool mThrottleValid; int64_t mWriteStartLT; int64_t mFramesWritten; // application rate frames, not device rate frames LinearTransform mUSecToLocalTime; // State to track which actual outputs are assigned to this output stream. Mutex mRoutingLock; // This protects mPhysOutputs and mTgtDevices AudioOutputList mPhysOutputs; uint32_t mTgtDevices; bool mTgtDevicesDirty; uint32_t mAudioFlingerTgtDevices; // Flag to track if this StreamOut was created to sink a direct output // multichannel stream. bool mIsMCOutput; // Is the stream on standby? bool mInStandby; // Is the stream compressed audio in SPDIF data bursts? const bool mIsIec958NonAudio; // reduce log spew bool mReportedAvailFail; status_t standbyHardware(); void releaseAllOutputs(); // locks mRoutingLock void updateTargetOutputs(); // locks mRoutingLock void updateInputNums(); void finishedWriteOp(size_t framesWritten, bool needThrottle); void resetThrottle() { mThrottleValid = false; } status_t getNextWriteTimestamp_internal(int64_t *timestamp); void adjustOutputs(int64_t maxTime); ssize_t writeInternal(const void* buffer, size_t bytes); // mRoutingLock should be held before calling this. status_t getPresentationPosition_l(uint64_t *frames, struct timespec *timestamp); }; } // android #endif // ANDROID_AUDIO_STREAM_OUT_H